From cfc4d65d4882be57b745e430299bbdf19c578990 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 22 Mar 2020 15:34:14 +0100 Subject: [PATCH] THE INTERRUPTS ARE GETTING GENERATED! --- pcid/src/pci/msi.rs | 4 ++-- xhcid/src/main.rs | 8 ++------ xhcid/src/xhci/mod.rs | 41 +++++++++++++++++++++++++++++++++------- xhcid/src/xhci/scheme.rs | 16 ++++++++++------ 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/pcid/src/pci/msi.rs b/pcid/src/pci/msi.rs index da993840ec..8b420501aa 100644 --- a/pcid/src/pci/msi.rs +++ b/pcid/src/pci/msi.rs @@ -263,8 +263,8 @@ pub struct MsixTableEntry { pub mod x86_64 { #[repr(u8)] pub enum TriggerMode { - Level = 0, - Edge = 1, + Edge = 0, + Level = 1, } #[repr(u8)] diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index e8c29b2848..a415b5cc24 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -104,14 +104,10 @@ fn main() { dbg!(has_msix, msix_enabled); if has_msi && !msi_enabled { - pcid_handle.enable_feature(PciFeature::Msi).expect("xhcid: failed to enable MSI"); msi_enabled = true; - println!("Enabled MSI"); } - if has_msi && msi_enabled && has_msix && !msix_enabled { - pcid_handle.enable_feature(PciFeature::MsiX).expect("xhcid: failed to enable MSI-X"); + if has_msix && !msix_enabled { msix_enabled = true; - println!("Enabled MSI-X"); } let (mut irq_file, msix_info) = if msi_enabled && !msix_enabled { @@ -200,7 +196,7 @@ fn main() { { let hci = Arc::new(RefCell::new( - Xhci::new(name, address, msi_enabled, msix_enabled, msix_info).expect("xhcid: failed to allocate device"), + Xhci::new(name, address, msi_enabled, msix_enabled, msix_info, pcid_handle).expect("xhcid: failed to allocate device"), )); hci.borrow_mut().probe().expect("xhcid: failed to probe"); diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index 47df7db0a8..813ec2728b 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -12,6 +12,7 @@ use syscall::io::{Dma, Io}; use crate::usb; use pcid_interface::msi::{MsixTableEntry, MsixCapability}; +use pcid_interface::{PcidServerHandle, PciFeature}; mod capability; mod command; @@ -108,7 +109,7 @@ impl<'a> Device<'a> { } } - self.int.erdp.write(self.cmd.erdp()); + self.int.erdp.write(self.cmd.erdp() | (1 << 3)); } fn get_device(&mut self) -> Result { @@ -173,6 +174,8 @@ pub struct Xhci { msi: bool, msix: bool, msix_info: Option, + + pcid_handle: PcidServerHandle, } struct PortState { @@ -201,7 +204,7 @@ impl EndpointState { } impl Xhci { - pub fn new(scheme_name: String, address: usize, msi: bool, msix: bool, msix_info: Option) -> Result { + pub fn new(scheme_name: String, address: usize, msi: bool, msix: bool, msix_info: Option, handle: PcidServerHandle) -> Result { let cap = unsafe { &mut *(address as *mut CapabilityRegs) }; println!(" - CAP {:X}", address); @@ -276,6 +279,7 @@ impl Xhci { msi, msix, msix_info, + pcid_handle: handle, }; xhci.init(max_slots); @@ -302,13 +306,29 @@ impl Xhci { // Set event ring segment table registers println!(" - Interrupter 0: {:X}", self.run.ints.as_ptr() as usize); { + self.run.ints[0].iman.writef(1, true); // clear interrupt pending if set earlier by the BIOS + + println!("IP={}", self.run.ints[0].iman.readf(1)); + + /*if self.msi { + self.pcid_handle.enable_feature(PciFeature::Msi).expect("xhcid: failed to enable MSI"); + println!("Enabled MSI"); + }*/ + if self.msix { + self.pcid_handle.enable_feature(PciFeature::MsiX).expect("xhcid: failed to enable MSI-X"); + println!("Enabled MSI-X"); + } + + dbg!(self.pcid_handle.feature_info(PciFeature::MsiX).unwrap()); + dbg!(self.pcid_handle.feature_info(PciFeature::Msi).unwrap()); + let erstz = 1; println!(" - Write ERSTZ: {}", erstz); self.run.ints[0].erstsz.write(erstz); let erdp = self.cmd.erdp(); println!(" - Write ERDP: {:X}", erdp); - self.run.ints[0].erdp.write(erdp as u64); + self.run.ints[0].erdp.write(erdp as u64 | (1 << 3)); let erstba = self.cmd.erstba(); println!(" - Write ERSTBA: {:X}", erstba); @@ -318,13 +338,14 @@ impl Xhci { self.run.ints[0].imod.write(0); println!(" - Enable interrupts"); - self.run.ints[0].iman.writef(1, true); // clear interrupt pending if set earlier by the BIOS self.run.ints[0].iman.writef(1 << 1, true); + } + self.op.usb_cmd.writef(1 << 2, true); // Set run/stop to 1 println!(" - Start"); - self.op.usb_cmd.writef(1 | 1 << 2, true); + self.op.usb_cmd.writef(1, true); // Wait until controller is running println!(" - Wait for running"); @@ -332,6 +353,8 @@ impl Xhci { println!(" - Waiting for XHCI running"); } + println!("IP={}", self.run.ints[0].iman.readf(1)); + // Ring command doorbell println!(" - Ring doorbell"); self.dbs[0].write(0); @@ -356,6 +379,7 @@ impl Xhci { } pub fn probe(&mut self) -> Result<()> { + println!("XHCI capabilities: {:?}", self.capabilities_iter().collect::>()); for i in 0..self.ports.len() { let (data, state, speed, flags) = { let port = &self.ports[i]; @@ -554,10 +578,12 @@ impl Xhci { // Since using MSI and MSI-X implies having no IRQ sharing whatsoever, the IP bit // doesn't have to be touched. println!("Successfully received MSI/MSI-X interrupt, IP={}, EHB={}", self.run.ints[0].iman.readf(1), self.run.ints[0].erdp.readf(3)); - println!("MSI-X PB={}", self.msix_info.as_ref().unwrap().pba(0)); + println!("MSI-X PB={}", self.msix_info.as_mut().unwrap().pba(0)); + let entry = self.msix_info.as_mut().unwrap().table_entry_pointer(0); + println!("MSI-X entry (addr_lo, addr_hi, msg_data, vec_ctl: {:#0x} {:#0x} {:#0x} {:#0x}", entry.addr_lo.read(), entry.addr_hi.read(), entry.msg_data.read(), entry.vec_ctl.read()); true } else if self.run.ints[0].iman.readf(1) { - // If MSI and/or MSI-X are not used, the interrupt has to be shared, and thus there is + // 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. self.run.ints[0].iman.writef(1, true); @@ -567,6 +593,7 @@ impl Xhci { // The interrupt came from a different device. false } + } /// Handle an IRQ event. pub fn on_irq(&mut self) { diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index 20d8e81c9c..1abfc8b056 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -216,16 +216,20 @@ impl Xhci { cmd_name: &str, f: F, ) -> Result { - self.run.ints[0].erdp.write(self.cmd.erdp()); + self.run.ints[0].erdp.write(self.cmd.erdp() | (1 << 3)); let (cmd, cycle, event) = self.cmd.next(); f(cmd, cycle); + println!("INTE={}", self.op.usb_cmd.readf(1 << 2)); + println!("IP={}", self.run.ints[0].iman.readf(1)); self.dbs[0].write(0); + println!("IP={}", self.run.ints[0].iman.readf(1)); - while event.data.read() == 0 { + while event.data.read() == 0/* || self.run.ints[0].iman.readf(1)*/ { println!(" - {} Waiting for event", cmd_name); } + println!("IP={}", self.run.ints[0].iman.readf(1)); if event.completion_code() != TrbCompletionCode::Success as u8 || event.trb_type() != TrbType::CommandCompletion as u8 @@ -239,7 +243,7 @@ impl Xhci { cmd.reserved(false); event.reserved(false); - self.run.ints[0].erdp.write(self.cmd.erdp()); + self.run.ints[0].erdp.write(self.cmd.erdp() | (1 << 3)); Ok(ret) } pub fn execute_control_transfer( @@ -299,7 +303,7 @@ impl Xhci { event.clone() }; - self.run.ints[0].erdp.write(self.cmd.erdp()); + self.run.ints[0].erdp.write(self.cmd.erdp() | (1 << 3)); Ok(cloned_trb) } @@ -385,7 +389,7 @@ impl Xhci { cloned_trb }; - self.run.ints[0].erdp.write(self.cmd.erdp()); + self.run.ints[0].erdp.write(self.cmd.erdp() | (1 << 3)); Ok(cloned_trb) } @@ -995,7 +999,7 @@ impl Xhci { // TODO: Should the descriptors be stored in PortState? - run.ints[0].erdp.write(cmd.erdp()); + run.ints[0].erdp.write(cmd.erdp() | (1 << 3)); let mut dev = Device { ring,