xhcid: support MMIO on 32-bit systems
This commit is contained in:
@@ -166,11 +166,13 @@ impl StreamContextArray {
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct ScratchpadBufferEntry {
|
||||
pub value: Mmio<u64>,
|
||||
pub value_low: Mmio<u32>,
|
||||
pub value_high: Mmio<u32>,
|
||||
}
|
||||
impl ScratchpadBufferEntry {
|
||||
pub fn set_addr(&mut self, addr: u64) {
|
||||
self.value.write(addr);
|
||||
self.value_low.write(addr as u32);
|
||||
self.value_high.write((addr >> 32) as u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ use super::trb::Trb;
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct EventRingSte {
|
||||
pub address: Mmio<u64>,
|
||||
pub address_low: Mmio<u32>,
|
||||
pub address_high: Mmio<u32>,
|
||||
pub size: Mmio<u16>,
|
||||
_rsvd: Mmio<u16>,
|
||||
_rsvd2: Mmio<u32>,
|
||||
@@ -28,7 +29,8 @@ impl EventRing {
|
||||
ring: Ring::new(ac64, 256, false)?,
|
||||
};
|
||||
|
||||
ring.ste[0].address.write(ring.ring.trbs.physical() as u64);
|
||||
ring.ste[0].address_low.write(ring.ring.trbs.physical() as u32);
|
||||
ring.ste[0].address_high.write((ring.ring.trbs.physical() as u64 >> 32) as u32);
|
||||
ring.ste[0].size.write(ring.ring.trbs.len() as u16);
|
||||
|
||||
Ok(ring)
|
||||
|
||||
@@ -209,7 +209,8 @@ impl IrqReactor {
|
||||
|
||||
trace!("Updated ERDP to {:#0x}", dequeue_pointer);
|
||||
|
||||
self.hci.run.lock().unwrap().ints[0].erdp.write(dequeue_pointer);
|
||||
self.hci.run.lock().unwrap().ints[0].erdp_low.write(dequeue_pointer as u32);
|
||||
self.hci.run.lock().unwrap().ints[0].erdp_high.write((dequeue_pointer >> 32) as u32);
|
||||
}
|
||||
fn handle_requests(&mut self) {
|
||||
self.states.extend(self.receiver.try_iter().inspect(|req| trace!("Received request: {:X?}", req)));
|
||||
|
||||
+10
-6
@@ -367,13 +367,15 @@ impl Xhci {
|
||||
// Set device context address array pointer
|
||||
let dcbaap = self.dev_ctx.dcbaap();
|
||||
debug!("Writing DCBAAP: {:X}", dcbaap);
|
||||
self.op.get_mut().unwrap().dcbaap.write(dcbaap as u64);
|
||||
self.op.get_mut().unwrap().dcbaap_low.write(dcbaap as u32);
|
||||
self.op.get_mut().unwrap().dcbaap_high.write((dcbaap as u64 >> 32) as u32);
|
||||
|
||||
// Set command ring control register
|
||||
let crcr = self.cmd.get_mut().unwrap().register();
|
||||
assert_eq!(crcr & 0xFFFF_FFFF_FFFF_FFC1, crcr, "unaligned CRCR");
|
||||
debug!("Writing CRCR: {:X}", crcr);
|
||||
self.op.get_mut().unwrap().crcr.write(crcr as u64);
|
||||
self.op.get_mut().unwrap().crcr_low.write(crcr as u32);
|
||||
self.op.get_mut().unwrap().crcr_high.write((crcr as u64 >> 32) as u32);
|
||||
|
||||
// Set event ring segment table registers
|
||||
debug!("Interrupter 0: {:p}", self.run.get_mut().unwrap().ints.as_ptr());
|
||||
@@ -386,11 +388,13 @@ impl Xhci {
|
||||
|
||||
let erdp = self.primary_event_ring.get_mut().unwrap().erdp();
|
||||
debug!("Writing ERDP: {:X}", erdp);
|
||||
int.erdp.write(erdp as u64 | (1 << 3));
|
||||
int.erdp_low.write(erdp as u32 | (1 << 3));
|
||||
int.erdp_high.write((erdp as u64 >> 32) as u32);
|
||||
|
||||
let erstba = self.primary_event_ring.get_mut().unwrap().erstba();
|
||||
debug!("Writing ERSTBA: {:X}", erstba);
|
||||
int.erstba.write(erstba as u64);
|
||||
int.erstba_low.write(erstba as u32);
|
||||
int.erstba_high.write((erstba as u64 >> 32) as u32);
|
||||
|
||||
debug!("Writing IMODC and IMODI: {} and {}", 0, 0);
|
||||
int.imod.write(0);
|
||||
@@ -749,10 +753,10 @@ impl Xhci {
|
||||
if self.uses_msi() || self.uses_msix() {
|
||||
// Since using MSI and MSI-X implies having no IRQ sharing whatsoever, the IP bit
|
||||
// doesn't have to be touched.
|
||||
trace!("Successfully received MSI/MSI-X interrupt, IP={}, EHB={}", runtime_regs.ints[0].iman.readf(1), runtime_regs.ints[0].erdp.readf(3));
|
||||
trace!("Successfully received MSI/MSI-X interrupt, IP={}, EHB={}", runtime_regs.ints[0].iman.readf(1), runtime_regs.ints[0].erdp_low.readf(3));
|
||||
true
|
||||
} else if runtime_regs.ints[0].iman.readf(1) {
|
||||
trace!("Successfully received INTx# interrupt, IP={}, EHB={}", runtime_regs.ints[0].iman.readf(1), runtime_regs.ints[0].erdp.readf(3));
|
||||
trace!("Successfully received INTx# interrupt, IP={}, EHB={}", runtime_regs.ints[0].iman.readf(1), runtime_regs.ints[0].erdp_low.readf(3));
|
||||
// If MSI and/or MSI-X are not used, the interrupt might have to be shared, and thus there is
|
||||
// a special register to specify whether the IRQ actually came from the xHC.
|
||||
runtime_regs.ints[0].iman.writef(1, true);
|
||||
|
||||
@@ -11,9 +11,11 @@ pub struct OperationalRegs {
|
||||
pub page_size: Mmio<u32>,
|
||||
_rsvd: [Mmio<u32>; 2],
|
||||
pub dn_ctrl: Mmio<u32>,
|
||||
pub crcr: Mmio<u64>,
|
||||
pub crcr_low: Mmio<u32>,
|
||||
pub crcr_high: Mmio<u32>,
|
||||
_rsvd2: [Mmio<u32>; 4],
|
||||
pub dcbaap: Mmio<u64>,
|
||||
pub dcbaap_low: Mmio<u32>,
|
||||
pub dcbaap_high: Mmio<u32>,
|
||||
pub config: Mmio<u32>,
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ pub struct Interrupter {
|
||||
pub imod: Mmio<u32>,
|
||||
pub erstsz: Mmio<u32>,
|
||||
_rsvd: Mmio<u32>,
|
||||
pub erstba: Mmio<u64>,
|
||||
pub erdp: Mmio<u64>,
|
||||
pub erstba_low: Mmio<u32>,
|
||||
pub erstba_high: Mmio<u32>,
|
||||
pub erdp_low: Mmio<u32>,
|
||||
pub erdp_high: Mmio<u32>,
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
|
||||
@@ -259,8 +259,8 @@ impl Xhci {
|
||||
//TODO: find out why this bit is set earlier!
|
||||
let mut run = self.run.lock().unwrap();
|
||||
let mut int = &mut run.ints[0];
|
||||
if int.erdp.readf(1 << 3) {
|
||||
int.erdp.writef(1 << 3, true);
|
||||
if int.erdp_low.readf(1 << 3) {
|
||||
int.erdp_low.writef(1 << 3, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2110,7 +2110,7 @@ impl Xhci {
|
||||
pub fn event_handler_finished(&self) {
|
||||
trace!("Event handler finished");
|
||||
// write 1 to EHB to clear it
|
||||
self.run.lock().unwrap().ints[0].erdp.writef(1 << 3, true);
|
||||
self.run.lock().unwrap().ints[0].erdp_low.writef(1 << 3, true);
|
||||
}
|
||||
}
|
||||
pub fn handle_event_trb(name: &str, event_trb: &Trb, command_trb: &Trb) -> Result<()> {
|
||||
|
||||
+16
-8
@@ -110,14 +110,16 @@ pub enum TransferKind {
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct Trb {
|
||||
pub data: Mmio<u64>,
|
||||
pub data_low: Mmio<u32>,
|
||||
pub data_high: Mmio<u32>,
|
||||
pub status: Mmio<u32>,
|
||||
pub control: Mmio<u32>,
|
||||
}
|
||||
impl Clone for Trb {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
data: Mmio::from(self.data.read()),
|
||||
data_low: Mmio::from(self.data_low.read()),
|
||||
data_high: Mmio::from(self.data_high.read()),
|
||||
status: Mmio::from(self.status.read()),
|
||||
control: Mmio::from(self.control.read()),
|
||||
}
|
||||
@@ -144,7 +146,8 @@ pub const TRB_CONTROL_ENDPOINT_ID_SHIFT: u8 = 16;
|
||||
|
||||
impl Trb {
|
||||
pub fn set(&mut self, data: u64, status: u32, control: u32) {
|
||||
self.data.write(data);
|
||||
self.data_low.write(data as u32);
|
||||
self.data_high.write((data >> 32) as u32);
|
||||
self.status.write(status);
|
||||
self.control.write(control);
|
||||
}
|
||||
@@ -153,6 +156,11 @@ impl Trb {
|
||||
self.set(0, 0, ((TrbType::Reserved as u32) << 10) | (cycle as u32));
|
||||
}
|
||||
|
||||
pub fn read_data(&self) -> u64 {
|
||||
(self.data_low.read() as u64) |
|
||||
((self.data_high.read() as u64) << 32)
|
||||
}
|
||||
|
||||
pub fn completion_code(&self) -> u8 {
|
||||
(self.status.read() >> TRB_STATUS_COMPLETION_CODE_SHIFT) as u8
|
||||
}
|
||||
@@ -172,7 +180,7 @@ impl Trb {
|
||||
debug_assert_eq!(self.trb_type(), TrbType::CommandCompletion as u8);
|
||||
|
||||
if self.has_completion_trb_pointer() {
|
||||
Some(self.data.read())
|
||||
Some(self.read_data())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -181,7 +189,7 @@ impl Trb {
|
||||
debug_assert_eq!(self.trb_type(), TrbType::Transfer as u8);
|
||||
|
||||
if self.has_completion_trb_pointer() {
|
||||
Some(self.data.read())
|
||||
Some(self.read_data())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -199,7 +207,7 @@ impl Trb {
|
||||
}
|
||||
pub fn event_data(&self) -> Option<u64> {
|
||||
if self.event_data_bit() {
|
||||
Some(self.data.read())
|
||||
Some(self.read_data())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -459,7 +467,7 @@ impl fmt::Debug for Trb {
|
||||
write!(
|
||||
f,
|
||||
"Trb {{ data: {:>016X}, status: {:>08X}, control: {:>08X} }}",
|
||||
self.data.read(),
|
||||
self.read_data(),
|
||||
self.status.read(),
|
||||
self.control.read()
|
||||
)
|
||||
@@ -471,7 +479,7 @@ impl fmt::Display for Trb {
|
||||
write!(
|
||||
f,
|
||||
"({:>016X}, {:>08X}, {:>08X})",
|
||||
self.data.read(),
|
||||
self.read_data(),
|
||||
self.status.read(),
|
||||
self.control.read()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user