ahcid, nvmed: support MMIO on 32-bit systems

This commit is contained in:
Jeremy Soller
2023-09-09 12:15:07 -06:00
parent 676b1cda67
commit f228483f1f
3 changed files with 28 additions and 14 deletions
+3 -1
View File
@@ -139,7 +139,9 @@ pub struct FisDmaSetup {
pub rsv1: [Mmio<u8>; 2], // Reserved
// DWORD 1&2
pub dma_buffer_id: Mmio<u64>, /* DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */
/* DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */
pub dma_buffer_id_low: Mmio<u32>,
pub dma_buffer_id_high: Mmio<u32>,
// DWORD 3
pub rsv3: Mmio<u32>, // More reserved
+12 -6
View File
@@ -109,7 +109,8 @@ impl HbaPort {
for i in 0..32 {
let cmdheader = &mut clb[i];
cmdheader.ctba.write(ctbas[i].physical() as u64);
cmdheader.ctba_low.write(ctbas[i].physical() as u32);
cmdheader.ctba_high.write((ctbas[i].physical() as u64 >> 32) as u32);
cmdheader.prdtl.write(0);
}
@@ -149,7 +150,8 @@ impl HbaPort {
cmdheader.prdtl.write(1);
let prdt_entry = &mut prdt_entries[0];
prdt_entry.dba.write(dest.physical() as u64);
prdt_entry.dba_low.write(dest.physical() as u32);
prdt_entry.dba_high.write((dest.physical() as u64 >> 32) as u32);
prdt_entry.dbc.write(512 | 1);
cmdfis.pm.write(1 << 7);
@@ -234,7 +236,8 @@ impl HbaPort {
cmdheader.prdtl.write(1);
let prdt_entry = &mut prdt_entries[0];
prdt_entry.dba.write(buf.physical() as u64);
prdt_entry.dba_low.write(buf.physical() as u32);
prdt_entry.dba_high.write((buf.physical() as u64 >> 32) as u32);
prdt_entry.dbc.write(((sectors * 512) as u32) | 1);
cmdfis.pm.write(1 << 7);
@@ -268,7 +271,8 @@ impl HbaPort {
cmdheader.prdtl.write(1);
let prdt_entry = &mut prdt_entries[0];
prdt_entry.dba.write(buf.physical() as u64);
prdt_entry.dba_low.write(buf.physical() as u32);
prdt_entry.dba_high.write((buf.physical() as u64 >> 32) as u32);
prdt_entry.dbc.write(size - 1);
cmdfis.pm.write(1 << 7);
@@ -392,7 +396,8 @@ impl HbaMem {
#[repr(packed)]
pub struct HbaPrdtEntry {
dba: Mmio<u64>, // Data base address
dba_low: Mmio<u32>, // Data base address (low
dba_high: Mmio<u32>, // Data base address (high)
_rsv0: Mmio<u32>, // Reserved
dbc: Mmio<u32>, // Byte count, 4M max, interrupt = 1
}
@@ -424,7 +429,8 @@ pub struct HbaCmdHeader {
_prdbc: Mmio<u32>, // Physical region descriptor byte count transferred
// DW2, 3
ctba: Mmio<u64>, // Command table descriptor base address
ctba_low: Mmio<u32>, // Command table descriptor base address (low)
ctba_high: Mmio<u32>, // Command table descriptor base address (high)
// DW4 - 7
_rsv1: [Mmio<u32>; 4], // Reserved
+13 -7
View File
@@ -128,7 +128,8 @@ pub struct MsixCfg {
#[repr(packed)]
pub struct NvmeRegs {
/// Controller Capabilities
cap: Mmio<u64>,
cap_low: Mmio<u32>,
cap_high: Mmio<u32>,
/// Version
vs: Mmio<u32>,
/// Interrupt mask set
@@ -146,9 +147,11 @@ pub struct NvmeRegs {
/// Admin queue attributes
aqa: Mmio<u32>,
/// Admin submission queue base address
asq: Mmio<u64>,
asq_low: Mmio<u32>,
asq_high: Mmio<u32>,
/// Admin completion queue base address
acq: Mmio<u64>,
acq_low: Mmio<u32>,
acq_high: Mmio<u32>,
/// Controller memory buffer location
cmbloc: Mmio<u32>,
/// Controller memory buffer size
@@ -242,7 +245,7 @@ impl Nvme {
let mut regs_guard = self.regs.write().unwrap();
let mut regs: &mut NvmeRegs = regs_guard.deref_mut();
let dstrd = ((regs.cap.read() >> 32) & 0b1111) as usize;
let dstrd = (regs.cap_high.read() & 0b1111) as usize;
let addr = (regs as *mut NvmeRegs as usize) + 0x1000 + index * (4 << dstrd);
(&mut *(addr as *mut Mmio<u32>)).write(value);
}
@@ -265,7 +268,8 @@ impl Nvme {
{
let regs = self.regs.read().unwrap();
log::debug!("CAPS: {:X}", regs.cap.read());
log::debug!("CAP_LOW: {:X}", regs.cap_low.read());
log::debug!("CAP_HIGH: {:X}", regs.cap_high.read());
log::debug!("VS: {:X}", regs.vs.read());
log::debug!("CC: {:X}", regs.cc.read());
log::debug!("CSTS: {:X}", regs.csts.read());
@@ -315,8 +319,10 @@ impl Nvme {
let (acq, _) = completion_queues.get_mut(&0).unwrap().get_mut().unwrap();
regs.aqa
.write(((acq.data.len() as u32 - 1) << 16) | (asq.data.len() as u32 - 1));
regs.asq.write(asq.data.physical() as u64);
regs.acq.write(acq.data.physical() as u64);
regs.asq_low.write(asq.data.physical() as u32);
regs.asq_high.write((asq.data.physical() as u64 >> 32) as u32);
regs.acq_low.write(acq.data.physical() as u32);
regs.acq_high.write((acq.data.physical() as u64 >> 32) as u32);
// Set IOCQES, IOSQES, AMS, MPS, and CSS
let mut cc = regs.cc.read();