diff --git a/xhcid/src/xhci/context.rs b/xhcid/src/xhci/context.rs index d0fa24174a..4656a826fb 100644 --- a/xhcid/src/xhci/context.rs +++ b/xhcid/src/xhci/context.rs @@ -166,11 +166,13 @@ impl StreamContextArray { #[repr(packed)] pub struct ScratchpadBufferEntry { - pub value: Mmio, + pub value_low: Mmio, + pub value_high: Mmio, } 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); } } diff --git a/xhcid/src/xhci/event.rs b/xhcid/src/xhci/event.rs index 329afc0ed3..b42a126ae7 100644 --- a/xhcid/src/xhci/event.rs +++ b/xhcid/src/xhci/event.rs @@ -9,7 +9,8 @@ use super::trb::Trb; #[repr(packed)] pub struct EventRingSte { - pub address: Mmio, + pub address_low: Mmio, + pub address_high: Mmio, pub size: Mmio, _rsvd: Mmio, _rsvd2: Mmio, @@ -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) diff --git a/xhcid/src/xhci/irq_reactor.rs b/xhcid/src/xhci/irq_reactor.rs index 602cce288f..215832ff9f 100644 --- a/xhcid/src/xhci/irq_reactor.rs +++ b/xhcid/src/xhci/irq_reactor.rs @@ -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))); diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index aa371007d7..99efcbd2e5 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -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); diff --git a/xhcid/src/xhci/operational.rs b/xhcid/src/xhci/operational.rs index 0d4af23901..855de69808 100644 --- a/xhcid/src/xhci/operational.rs +++ b/xhcid/src/xhci/operational.rs @@ -11,9 +11,11 @@ pub struct OperationalRegs { pub page_size: Mmio, _rsvd: [Mmio; 2], pub dn_ctrl: Mmio, - pub crcr: Mmio, + pub crcr_low: Mmio, + pub crcr_high: Mmio, _rsvd2: [Mmio; 4], - pub dcbaap: Mmio, + pub dcbaap_low: Mmio, + pub dcbaap_high: Mmio, pub config: Mmio, } diff --git a/xhcid/src/xhci/runtime.rs b/xhcid/src/xhci/runtime.rs index 4dc4663ea4..b18fb482e9 100644 --- a/xhcid/src/xhci/runtime.rs +++ b/xhcid/src/xhci/runtime.rs @@ -6,8 +6,10 @@ pub struct Interrupter { pub imod: Mmio, pub erstsz: Mmio, _rsvd: Mmio, - pub erstba: Mmio, - pub erdp: Mmio, + pub erstba_low: Mmio, + pub erstba_high: Mmio, + pub erdp_low: Mmio, + pub erdp_high: Mmio, } #[repr(packed)] diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index 71e1610cf7..9af57334ef 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -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<()> { diff --git a/xhcid/src/xhci/trb.rs b/xhcid/src/xhci/trb.rs index 66d30437be..8d71f8b81e 100644 --- a/xhcid/src/xhci/trb.rs +++ b/xhcid/src/xhci/trb.rs @@ -110,14 +110,16 @@ pub enum TransferKind { #[repr(packed)] pub struct Trb { - pub data: Mmio, + pub data_low: Mmio, + pub data_high: Mmio, pub status: Mmio, pub control: Mmio, } 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 { 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() )