Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 111 additions & 1 deletion awkernel_drivers/src/pcie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ impl fmt::Display for PCIeDeviceErr {
}

pub(crate) mod registers {
use alloc::vec::Vec;
use core::fmt;

use bitflags::bitflags;

bitflags! {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -241,6 +330,10 @@ impl PCIeDevice for UnknownDevice {
name.into()
}

fn config_space(&self) -> Option<ConfigSpace> {
None
}

fn children(&self) -> Option<&Vec<ChildDevice>> {
// UnknownDevice represents a terminal device and always returns None.
None
Expand Down Expand Up @@ -419,6 +512,10 @@ impl PCIeDevice for PCIeBus {
}
}

fn config_space(&self) -> Option<ConfigSpace> {
self.info.as_ref().map(|info| info.config_space.clone())
}

fn children(&self) -> Option<&Vec<ChildDevice>> {
Some(&self.devices)
}
Expand All @@ -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() {
Expand Down Expand Up @@ -1055,6 +1161,10 @@ impl PCIeInfo {
pub trait PCIeDevice {
fn device_name(&self) -> Cow<'static, str>;

fn config_space(&self) -> Option<ConfigSpace> {
None
}

fn children(&self) -> Option<&Vec<ChildDevice>> {
None
}
Expand Down
5 changes: 5 additions & 0 deletions awkernel_drivers/src/pcie/intel/igb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,11 @@ impl PCIeDevice for Igb {
let name = format!("{bfd}: {DEVICE_NAME} ({mac_type:?})");
name.into()
}

fn config_space(&self) -> Option<crate::pcie::config_space::ConfigSpace> {
let inner = self.inner.read();
Some(inner.info.config_space.clone())
}
}

impl NetDevice for Igb {
Expand Down
5 changes: 5 additions & 0 deletions awkernel_drivers/src/pcie/intel/igc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<crate::pcie::config_space::ConfigSpace> {
let inner = self.inner.read();
Some(inner.info.config_space.clone())
}
}

impl NetDevice for Igc {
Expand Down
5 changes: 5 additions & 0 deletions awkernel_drivers/src/pcie/intel/ixgbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2054,6 +2054,11 @@ impl PCIeDevice for Ixgbe {
let name = format!("{bfd}: {DEVICE_NAME} ({mac_type:?})");
name.into()
}

fn config_space(&self) -> Option<crate::pcie::config_space::ConfigSpace> {
let inner = self.inner.read();
Some(inner.info.config_space.clone())
}
}

impl NetDevice for Ixgbe {
Expand Down
Loading