diff --git a/awkernel_drivers/src/pcie.rs b/awkernel_drivers/src/pcie.rs index 8ff5c4c53..b24167f70 100644 --- a/awkernel_drivers/src/pcie.rs +++ b/awkernel_drivers/src/pcie.rs @@ -103,6 +103,9 @@ impl fmt::Display for PCIeDeviceErr { } pub(crate) mod registers { + use alloc::vec::Vec; + use core::fmt; + use bitflags::bitflags; bitflags! { @@ -139,6 +142,92 @@ pub(crate) mod registers { } } + impl fmt::Display for StatusCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut status_flags = Vec::new(); + + if self.contains(Self::DETECTED_PARITY_ERROR) { + status_flags.push("Detected Parity Error"); + } + if self.contains(Self::SIGNALED_SYSTEM_ERROR) { + status_flags.push("Signaled System Error"); + } + if self.contains(Self::RECEIVED_MASTER_ABORT) { + status_flags.push("Received Master Abort"); + } + if self.contains(Self::RECEIVED_TARGET_ABORT) { + status_flags.push("Received Target Abort"); + } + if self.contains(Self::SIGNALED_TARGET_ABORT) { + status_flags.push("Signaled Target Abort"); + } + if self.contains(Self::MASTER_DATA_PARITY_ERROR) { + status_flags.push("Master Data Parity Error"); + } + if self.contains(Self::FAST_BACK_TO_BACK_CAPABLE) { + status_flags.push("Fast Back-to-Back Capable"); + } + if self.contains(Self::CAPABLE_66MHZ) { + status_flags.push("66MHz Capable"); + } + if self.contains(Self::CAPABILITIES_LIST) { + status_flags.push("Capabilities List"); + } + if self.contains(Self::INTERRUPT_STATUS) { + status_flags.push("Interrupt Status"); + } + + let mut command_flags = Vec::new(); + + if self.contains(Self::INTERRUPT_DISABLE) { + command_flags.push("Interrupt Disable"); + } + + if self.contains(Self::FAST_BACK_TO_BACK_ENABLE) { + command_flags.push("Fast Back-to-Back Enable"); + } + + if self.contains(Self::SERR_ENABLE) { + command_flags.push("SERR Enable"); + } + + if self.contains(Self::PARITY_ERROR_RESPONSE) { + command_flags.push("Parity Error Response"); + } + + if self.contains(Self::VGA_PALETTE_SNOOP) { + command_flags.push("VGA Palette Snoop"); + } + + if self.contains(Self::MEMORY_WRITE_AND_INVALIDATE_ENABLE) { + command_flags.push("Memory Write and Invalidate Enable"); + } + + if self.contains(Self::SPECIAL_CYCLES) { + command_flags.push("Special Cycles"); + } + + if self.contains(Self::BUS_MASTER) { + command_flags.push("Bus Master"); + } + + if self.contains(Self::MEMORY_SPACE) { + command_flags.push("Memory Space"); + } + + if self.contains(Self::IO_SPACE) { + command_flags.push("IO Space"); + } + + write!( + f, + "status = [{}], command = [{}]", + status_flags.join(", "), + command_flags.join(", ") + ) + } + } + pub const HEADER_TYPE_GENERAL_DEVICE: u8 = 0; pub const HEADER_TYPE_PCI_TO_PCI_BRIDGE: u8 = 1; pub const HEADER_TYPE_PCI_TO_CARDBUS_BRIDGE: u8 = 2; @@ -241,6 +330,10 @@ impl PCIeDevice for UnknownDevice { name.into() } + fn config_space(&self) -> Option { + None + } + fn children(&self) -> Option<&Vec> { // UnknownDevice represents a terminal device and always returns None. None @@ -419,6 +512,10 @@ impl PCIeDevice for PCIeBus { } } + fn config_space(&self) -> Option { + self.info.as_ref().map(|info| info.config_space.clone()) + } + fn children(&self) -> Option<&Vec> { Some(&self.devices) } @@ -432,7 +529,16 @@ impl fmt::Display for PCIeBus { fn print_pcie_devices(device: &dyn PCIeDevice, f: &mut fmt::Formatter, indent: u8) -> fmt::Result { let indent_str = " ".repeat(indent as usize * 4); - write!(f, "{}{}\r\n", indent_str, device.device_name())?; + write!(f, "{}{}", indent_str, device.device_name())?; + + if let Some(config_space) = device.config_space() { + let status_command = config_space.read_u32(registers::STATUS_COMMAND); + let status_command = registers::StatusCommand::from_bits_truncate(status_command); + + write!(f, ", {}\r\n", status_command)?; + } else { + write!(f, "\r\n")?; + } if let Some(children) = device.children() { for child in children.iter() { @@ -1055,6 +1161,10 @@ impl PCIeInfo { pub trait PCIeDevice { fn device_name(&self) -> Cow<'static, str>; + fn config_space(&self) -> Option { + None + } + fn children(&self) -> Option<&Vec> { None } diff --git a/awkernel_drivers/src/pcie/intel/igb.rs b/awkernel_drivers/src/pcie/intel/igb.rs index 2748988cc..aaac69760 100644 --- a/awkernel_drivers/src/pcie/intel/igb.rs +++ b/awkernel_drivers/src/pcie/intel/igb.rs @@ -1998,6 +1998,11 @@ impl PCIeDevice for Igb { let name = format!("{bfd}: {DEVICE_NAME} ({mac_type:?})"); name.into() } + + fn config_space(&self) -> Option { + let inner = self.inner.read(); + Some(inner.info.config_space.clone()) + } } impl NetDevice for Igb { diff --git a/awkernel_drivers/src/pcie/intel/igc.rs b/awkernel_drivers/src/pcie/intel/igc.rs index a83105bf7..42c205026 100644 --- a/awkernel_drivers/src/pcie/intel/igc.rs +++ b/awkernel_drivers/src/pcie/intel/igc.rs @@ -281,6 +281,11 @@ impl PCIeDevice for Igc { fn device_name(&self) -> Cow<'static, str> { "Intel I225/I226 2.5 GbE".into() } + + fn config_space(&self) -> Option { + let inner = self.inner.read(); + Some(inner.info.config_space.clone()) + } } impl NetDevice for Igc { diff --git a/awkernel_drivers/src/pcie/intel/ixgbe.rs b/awkernel_drivers/src/pcie/intel/ixgbe.rs index 5db4ddd17..0fa2ed04f 100644 --- a/awkernel_drivers/src/pcie/intel/ixgbe.rs +++ b/awkernel_drivers/src/pcie/intel/ixgbe.rs @@ -2054,6 +2054,11 @@ impl PCIeDevice for Ixgbe { let name = format!("{bfd}: {DEVICE_NAME} ({mac_type:?})"); name.into() } + + fn config_space(&self) -> Option { + let inner = self.inner.read(); + Some(inner.info.config_space.clone()) + } } impl NetDevice for Ixgbe {