From 1890293e86616c813e08155609cc3802b2c76c52 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 21 Jan 2024 15:18:56 +0100 Subject: [PATCH] Introduce a FullDeviceId type and pass it in pcid_interface --- ihdad/src/main.rs | 3 +- pcid/src/config.rs | 22 +++---- pcid/src/driver_interface/mod.rs | 8 +-- pcid/src/main.rs | 5 +- pcid/src/pci/header.rs | 108 +++++++++++-------------------- pcid/src/pci/id.rs | 12 ++++ pcid/src/pci/mod.rs | 2 + virtio-blkd/src/main.rs | 2 +- virtio-core/src/probe.rs | 2 +- virtio-gpud/src/main.rs | 2 +- virtio-netd/src/main.rs | 2 +- 11 files changed, 72 insertions(+), 96 deletions(-) create mode 100644 pcid/src/pci/id.rs diff --git a/ihdad/src/main.rs b/ihdad/src/main.rs index d91013cc47..16ab7ea4a9 100755 --- a/ihdad/src/main.rs +++ b/ihdad/src/main.rs @@ -185,7 +185,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut irq_file = get_int_method(&mut pcid_handle).expect("ihdad: no interrupt file"); { - let vend_prod:u32 = ((pci_config.func.venid as u32) << 16) | (pci_config.func.devid as u32); + let vend_prod: u32 = ((pci_config.func.full_device_id.vendor_id as u32) << 16) + | (pci_config.func.full_device_id.device_id as u32); let device = Arc::new(RefCell::new(unsafe { hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") })); let socket_fd = syscall::open(":audiohw", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ihdad: failed to create hda scheme"); diff --git a/pcid/src/config.rs b/pcid/src/config.rs index 6c79e7eb63..df82e437d4 100644 --- a/pcid/src/config.rs +++ b/pcid/src/config.rs @@ -3,7 +3,7 @@ use std::ops::Range; use serde::Deserialize; -use crate::pci::PciHeader; +use crate::pci::FullDeviceId; #[derive(Clone, Debug, Default, Deserialize)] pub struct Config { @@ -24,21 +24,21 @@ pub struct DriverConfig { } impl DriverConfig { - pub fn match_function(&self, header: &PciHeader) -> bool { + pub fn match_function(&self, id: &FullDeviceId) -> bool { if let Some(class) = self.class { - if class != header.class().into() { + if class != id.class { return false; } } if let Some(subclass) = self.subclass { - if subclass != header.subclass() { + if subclass != id.subclass { return false; } } if let Some(interface) = self.interface { - if interface != header.interface() { + if interface != id.interface { return false; } } @@ -49,12 +49,12 @@ impl DriverConfig { let vendor_without_prefix = vendor.trim_start_matches("0x"); let vendor = i64::from_str_radix(vendor_without_prefix, 16).unwrap() as u16; - if vendor != header.vendor_id() { + if vendor != id.vendor_id { continue; } for device in devices { - if *device == header.device_id() { + if *device == id.device_id { device_found = true; break; } @@ -65,22 +65,20 @@ impl DriverConfig { } } else { if let Some(vendor) = self.vendor { - if vendor != header.vendor_id() { + if vendor != id.vendor_id { return false; } } if let Some(device) = self.device { - if device != header.device_id() { + if device != id.device_id { return false; } } } if let Some(ref device_id_range) = self.device_id_range { - if header.device_id() < device_id_range.start - || device_id_range.end <= header.device_id() - { + if id.device_id < device_id_range.start || device_id_range.end <= id.device_id { return false; } } diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 1132423793..b7cb34a7f0 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -9,7 +9,7 @@ use thiserror::Error; pub use crate::pci::cap::Capability; pub use crate::pci::msi; -pub use crate::pci::{PciAddress, PciBar, PciHeader}; +pub use crate::pci::{FullDeviceId, PciAddress, PciBar, PciHeader}; pub mod irq_helpers; @@ -45,10 +45,8 @@ pub struct PciFunction { /// Legacy interrupt pin (INTx#), none if INTx# interrupts aren't supported at all. pub legacy_interrupt_pin: Option, - /// Vendor ID - pub venid: u16, - /// Device ID - pub devid: u16, + /// All identifying information of the PCI function. + pub full_device_id: FullDeviceId, } impl PciFunction { pub fn name(&self) -> String { diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 8db92b7cbf..f8725429e2 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -265,7 +265,7 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he info!("{}", string); for driver in config.drivers.iter() { - if !driver.match_function(&header) { + if !driver.match_function(header.full_device_id()) { continue; } @@ -362,10 +362,9 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he bars, bar_sizes, addr, - devid: header.device_id(), legacy_interrupt_line: irq, legacy_interrupt_pin, - venid: header.vendor_id(), + full_device_id: header.full_device_id().clone(), }; let subdriver_args = driver_interface::SubdriverArguments { diff --git a/pcid/src/pci/header.rs b/pcid/src/pci/header.rs index 2c7b0556ff..7f5a6adafa 100644 --- a/pcid/src/pci/header.rs +++ b/pcid/src/pci/header.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use super::bar::PciBar; use super::class::PciClass; use super::func::ConfigReader; +use super::id::FullDeviceId; #[derive(Debug, PartialEq)] pub enum PciHeaderError { @@ -31,14 +32,9 @@ bitflags! { #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] pub struct SharedPciHeader { - vendor_id: u16, - device_id: u16, + full_device_id: FullDeviceId, command: u16, status: u16, - revision: u8, - interface: u8, - subclass: u8, - class: PciClass, cache_line_size: u8, latency_timer: u8, header_type: PciHeaderType, @@ -127,20 +123,22 @@ impl PciHeader { let revision = bytes[8]; let interface = bytes[9]; let subclass = bytes[10]; - let class = PciClass::from(bytes[11]); + let class = bytes[11]; let cache_line_size = bytes[12]; let latency_timer = bytes[13]; let header_type = PciHeaderType::from_bits_truncate(bytes[14]); let bist = bytes[15]; let shared = SharedPciHeader { + full_device_id: FullDeviceId { vendor_id, device_id, + class, + subclass, + interface, + revision, + }, command, status, - revision, - interface, - subclass, - class, cache_line_size, latency_timer, header_type, @@ -245,88 +243,56 @@ impl PciHeader { } } - /// Return the Vendor ID field. - pub fn vendor_id(&self) -> u16 { + /// Return all identifying information of the PCI function. + pub fn full_device_id(&self) -> &FullDeviceId { match self { - &PciHeader::General { - shared: SharedPciHeader { vendor_id, .. }, + PciHeader::General { + shared: + SharedPciHeader { + full_device_id: device_id, + .. + }, .. } - | &PciHeader::PciToPci { - shared: SharedPciHeader { vendor_id, .. }, - .. - } => vendor_id, - } - } - - /// Return the Device ID field. - pub fn device_id(&self) -> u16 { - match self { - &PciHeader::General { - shared: SharedPciHeader { device_id, .. }, - .. - } - | &PciHeader::PciToPci { - shared: SharedPciHeader { device_id, .. }, + | PciHeader::PciToPci { + shared: + SharedPciHeader { + full_device_id: device_id, + .. + }, .. } => device_id, } } + /// Return the Vendor ID field. + pub fn vendor_id(&self) -> u16 { + self.full_device_id().vendor_id + } + + /// Return the Device ID field. + pub fn device_id(&self) -> u16 { + self.full_device_id().device_id + } + /// Return the Revision field. pub fn revision(&self) -> u8 { - match self { - &PciHeader::General { - shared: SharedPciHeader { revision, .. }, - .. - } - | &PciHeader::PciToPci { - shared: SharedPciHeader { revision, .. }, - .. - } => revision, - } + self.full_device_id().revision } /// Return the Interface field. pub fn interface(&self) -> u8 { - match self { - &PciHeader::General { - shared: SharedPciHeader { interface, .. }, - .. - } - | &PciHeader::PciToPci { - shared: SharedPciHeader { interface, .. }, - .. - } => interface, - } + self.full_device_id().interface } /// Return the Subclass field. pub fn subclass(&self) -> u8 { - match self { - &PciHeader::General { - shared: SharedPciHeader { subclass, .. }, - .. - } - | &PciHeader::PciToPci { - shared: SharedPciHeader { subclass, .. }, - .. - } => subclass, - } + self.full_device_id().subclass } /// Return the Class field. pub fn class(&self) -> PciClass { - match self { - &PciHeader::General { - shared: SharedPciHeader { class, .. }, - .. - } - | &PciHeader::PciToPci { - shared: SharedPciHeader { class, .. }, - .. - } => class, - } + PciClass::from(self.full_device_id().class) } /// Return the Headers BARs. diff --git a/pcid/src/pci/id.rs b/pcid/src/pci/id.rs new file mode 100644 index 0000000000..9a59d660f6 --- /dev/null +++ b/pcid/src/pci/id.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +/// All identifying information of a PCI function. +#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] +pub struct FullDeviceId { + pub vendor_id: u16, + pub device_id: u16, + pub class: u8, + pub subclass: u8, + pub interface: u8, + pub revision: u8, +} diff --git a/pcid/src/pci/mod.rs b/pcid/src/pci/mod.rs index 6d39cbdb8f..264a3f35dd 100644 --- a/pcid/src/pci/mod.rs +++ b/pcid/src/pci/mod.rs @@ -7,12 +7,14 @@ pub use self::bar::PciBar; pub use self::class::PciClass; pub use self::func::PciFunc; pub use self::header::{PciHeader, PciHeaderError, PciHeaderType}; +pub use self::id::FullDeviceId; mod bar; pub mod cap; mod class; pub mod func; pub mod header; +mod id; pub mod msi; pub trait CfgAccess { diff --git a/virtio-blkd/src/main.rs b/virtio-blkd/src/main.rs index e280f62b6a..c6b3727a16 100644 --- a/virtio-blkd/src/main.rs +++ b/virtio-blkd/src/main.rs @@ -116,7 +116,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { // 0x1001 - virtio-blk let pci_config = pcid_handle.fetch_config()?; - assert_eq!(pci_config.func.devid, 0x1001); + assert_eq!(pci_config.func.full_device_id.device_id, 0x1001); log::info!("virtio-blk: initiating startup sequence :^)"); let device = virtio_core::probe_device(&mut pcid_handle)?; diff --git a/virtio-core/src/probe.rs b/virtio-core/src/probe.rs index 157ffa0f1f..c0c5ec3e1f 100644 --- a/virtio-core/src/probe.rs +++ b/virtio-core/src/probe.rs @@ -64,7 +64,7 @@ pub fn probe_device(pcid_handle: &mut PcidServerHandle) -> Result let pci_header = pcid_handle.fetch_header()?; assert_eq!( - pci_config.func.venid, 6900, + pci_config.func.full_device_id.vendor_id, 6900, "virtio_core::probe_device: not a virtio device" ); diff --git a/virtio-gpud/src/main.rs b/virtio-gpud/src/main.rs index 4d16d87a97..8a80510fbc 100644 --- a/virtio-gpud/src/main.rs +++ b/virtio-gpud/src/main.rs @@ -416,7 +416,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { // 0x1050 - virtio-gpu let pci_config = pcid_handle.fetch_config()?; - assert_eq!(pci_config.func.devid, 0x1050); + assert_eq!(pci_config.func.full_device_id.device_id, 0x1050); log::info!("virtio-gpu: initiating startup sequence :^)"); let device = DEVICE.try_call_once(|| virtio_core::probe_device(&mut pcid_handle))?; diff --git a/virtio-netd/src/main.rs b/virtio-netd/src/main.rs index c99b2c4577..c3113ed753 100644 --- a/virtio-netd/src/main.rs +++ b/virtio-netd/src/main.rs @@ -38,7 +38,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> Result<(), Error> { // 0x1000 - virtio-net let pci_config = pcid_handle.fetch_config()?; - assert_eq!(pci_config.func.devid, 0x1000); + assert_eq!(pci_config.func.full_device_id.device_id, 0x1000); log::info!("virtio-net: initiating startup sequence :^)"); let device = virtio_core::probe_device(&mut pcid_handle)?;