diff --git a/Cargo.lock b/Cargo.lock index 5364d127f1..47e84816d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -196,9 +196,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -527,7 +527,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "crc", "log", "uuid", @@ -698,7 +698,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "libc", "redox_syscall 0.4.1", ] @@ -956,6 +956,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "pci_types" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831e5bebf010674bc2e8070b892948120d4c453c71f37387e1ffea5636620dbe" +dependencies = [ + "bit_field", + "bitflags 2.4.2", +] + [[package]] name = "pcid" version = "0.1.0" @@ -968,6 +978,7 @@ dependencies = [ "libc", "log", "paw", + "pci_types", "plain", "redox-log", "redox_syscall 0.4.1", @@ -1151,7 +1162,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "475e252d7add4825405d2248d530d33e22364ac5477eab816b56efbeec1e2712" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "libredox", "redox_syscall 0.4.1", ] @@ -1727,7 +1738,7 @@ dependencies = [ name = "virtio-core" version = "0.1.0" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "common", "crossbeam-queue", "futures", diff --git a/pcid/Cargo.toml b/pcid/Cargo.toml index 6c276cc52b..794002fb18 100644 --- a/pcid/Cargo.toml +++ b/pcid/Cargo.toml @@ -19,6 +19,7 @@ byteorder = "1.2" libc = "0.2" log = "0.4" paw = "1.0" +pci_types = "0.6.1" plain = "0.2" redox-log = "0.1" redox_syscall = "0.4" diff --git a/pcid/src/cfg_access/fallback.rs b/pcid/src/cfg_access/fallback.rs index 90023961f7..65682e171f 100644 --- a/pcid/src/cfg_access/fallback.rs +++ b/pcid/src/cfg_access/fallback.rs @@ -6,8 +6,7 @@ use std::sync::Mutex; use syscall::io::{Io as _, Pio}; use log::info; - -use crate::pci::{CfgAccess, PciAddress}; +use pci_types::{ConfigRegionAccess, PciAddress}; pub(crate) struct Pci { lock: Mutex<()>, @@ -58,7 +57,11 @@ impl Pci { } } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -impl CfgAccess for Pci { +impl ConfigRegionAccess for Pci { + fn function_exists(&self, _address: PciAddress) -> bool { + todo!(); + } + unsafe fn read(&self, address: PciAddress, offset: u16) -> u32 { let _guard = self.lock.lock().unwrap(); @@ -86,7 +89,11 @@ impl CfgAccess for Pci { } } #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -impl CfgAccess for Pci { +impl ConfigRegionAccess for Pci { + fn function_exists(&self, _address: PciAddress) -> bool { + todo!(); + } + unsafe fn read(&self, addr: PciAddress, offset: u16) -> u32 { let _guard = self.lock.lock().unwrap(); todo!("Pci::CfgAccess::read on this architecture") diff --git a/pcid/src/cfg_access/mod.rs b/pcid/src/cfg_access/mod.rs index 0925b21d03..fd7f6e706a 100644 --- a/pcid/src/cfg_access/mod.rs +++ b/pcid/src/cfg_access/mod.rs @@ -2,8 +2,8 @@ use std::sync::Mutex; use std::{fmt, fs, io, mem, ptr, slice}; use log::info; +use pci_types::{ConfigRegionAccess, PciAddress}; -use crate::pci::{CfgAccess, PciAddress}; use fallback::Pci; mod fallback; @@ -221,7 +221,11 @@ impl Pcie { } } -impl CfgAccess for Pcie { +impl ConfigRegionAccess for Pcie { + fn function_exists(&self, _address: PciAddress) -> bool { + todo!(); + } + unsafe fn read(&self, address: PciAddress, offset: u16) -> u32 { let _guard = self.lock.lock().unwrap(); diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 4f7fd64703..4c01b88282 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -26,9 +26,29 @@ pub enum LegacyInterruptPin { IntD = 4, } +#[derive(Serialize, Deserialize)] +#[serde(remote = "PciAddress")] +struct PciAddressDef { + #[serde(getter = "PciAddress::segment")] + segment: u16, + #[serde(getter = "PciAddress::bus")] + bus: u8, + #[serde(getter = "PciAddress::device")] + device: u8, + #[serde(getter = "PciAddress::function")] + function: u8, +} + +impl From for PciAddress { + fn from(value: PciAddressDef) -> Self { + PciAddress::new(value.segment, value.bus, value.device, value.function) + } +} + #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub struct PciFunction { /// Address of the PCI function. + #[serde(with = "PciAddressDef")] pub addr: PciAddress, /// PCI Base Address Registers diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 793505276b..bd61bdf4c9 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -5,13 +5,14 @@ use std::process::Command; use std::thread; use std::sync::{Arc, Mutex}; +use pci_types::{ConfigRegionAccess, PciAddress}; use structopt::StructOpt; use log::{debug, error, info, warn, trace}; use redox_log::{OutputBuilder, RedoxLogger}; use crate::cfg_access::Pcie; use crate::config::Config; -use crate::pci::{CfgAccess, PciAddress, PciBar, PciClass, PciFunc}; +use crate::pci::{PciBar, PciClass, PciFunc}; use crate::pci::cap::Capability as PciCapability; use crate::pci::func::{ConfigReader, ConfigWriter}; use crate::pci_header::{PciHeader, PciHeaderError, PciHeaderType}; @@ -40,7 +41,7 @@ pub struct DriverHandler { state: Arc, } -fn with_pci_func_raw T>(pci: &dyn CfgAccess, addr: PciAddress, function: F) -> T { +fn with_pci_func_raw T>(pci: &dyn ConfigRegionAccess, addr: PciAddress, function: F) -> T { let func = PciFunc { pci, addr, @@ -204,7 +205,7 @@ pub struct State { pcie: Pcie, } impl State { - fn preferred_cfg_access(&self) -> &dyn CfgAccess { + fn preferred_cfg_access(&self) -> &dyn ConfigRegionAccess { &self.pcie } } diff --git a/pcid/src/pci/func.rs b/pcid/src/pci/func.rs index d6c7e93b70..7bdabff43d 100644 --- a/pcid/src/pci/func.rs +++ b/pcid/src/pci/func.rs @@ -1,6 +1,5 @@ use byteorder::{ByteOrder, LittleEndian}; - -use super::{CfgAccess, PciAddress}; +use pci_types::{ConfigRegionAccess, PciAddress}; pub trait ConfigReader { unsafe fn read_range(&self, offset: u16, len: u16) -> Vec { @@ -33,7 +32,7 @@ pub trait ConfigWriter { } pub struct PciFunc<'pci> { - pub pci: &'pci dyn CfgAccess, + pub pci: &'pci dyn ConfigRegionAccess, pub addr: PciAddress, } diff --git a/pcid/src/pci/mod.rs b/pcid/src/pci/mod.rs index 8f5e661ab7..f0eb8b558a 100644 --- a/pcid/src/pci/mod.rs +++ b/pcid/src/pci/mod.rs @@ -1,12 +1,8 @@ -use std::fmt; - -use bit_field::BitField; -use serde::{Deserialize, Serialize}; - pub use self::bar::PciBar; pub use self::class::PciClass; pub use self::func::PciFunc; pub use self::id::FullDeviceId; +pub use pci_types::PciAddress; mod bar; pub mod cap; @@ -14,69 +10,3 @@ mod class; pub mod func; mod id; pub mod msi; - -pub trait CfgAccess { - unsafe fn read(&self, addr: PciAddress, offset: u16) -> u32; - unsafe fn write(&self, addr: PciAddress, offset: u16, value: u32); -} - -// Copied from the pci_types crate, version 0.6.1. It has been modified to add serde support. -// FIXME If we start using it in the future use the upstream version instead. -/// The address of a PCIe function. -/// -/// PCIe supports 65536 segments, each with 256 buses, each with 32 slots, each with 8 possible functions. We pack this into a `u32`: -/// -/// ```ignore -/// 32 16 8 3 0 -/// +-------------------------------+---------------+---------+------+ -/// | segment | bus | device | func | -/// +-------------------------------+---------------+---------+------+ -/// ``` -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)] -pub struct PciAddress(u32); - -impl PciAddress { - pub fn new(segment: u16, bus: u8, device: u8, function: u8) -> PciAddress { - let mut result = 0; - result.set_bits(0..3, function as u32); - result.set_bits(3..8, device as u32); - result.set_bits(8..16, bus as u32); - result.set_bits(16..32, segment as u32); - PciAddress(result) - } - - pub fn segment(&self) -> u16 { - self.0.get_bits(16..32) as u16 - } - - pub fn bus(&self) -> u8 { - self.0.get_bits(8..16) as u8 - } - - pub fn device(&self) -> u8 { - self.0.get_bits(3..8) as u8 - } - - pub fn function(&self) -> u8 { - self.0.get_bits(0..3) as u8 - } -} - -impl fmt::Display for PciAddress { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{:02x}-{:02x}:{:02x}.{}", - self.segment(), - self.bus(), - self.device(), - self.function() - ) - } -} - -impl fmt::Debug for PciAddress { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self) - } -} diff --git a/pcid/src/pci_header.rs b/pcid/src/pci_header.rs index f904e1e930..183b5254a4 100644 --- a/pcid/src/pci_header.rs +++ b/pcid/src/pci_header.rs @@ -1,8 +1,9 @@ use bitflags::bitflags; use byteorder::{ByteOrder, LittleEndian}; +use pci_types::{ConfigRegionAccess, PciAddress}; use serde::{Deserialize, Serialize}; -use crate::pci::{CfgAccess, FullDeviceId, PciAddress, PciBar, PciClass}; +use crate::pci::{FullDeviceId, PciBar, PciClass}; #[derive(Debug, PartialEq)] pub enum PciHeaderError { @@ -89,7 +90,7 @@ impl PciHeader { /// Parse the bytes found in the Configuration Space of the PCI device into /// a more usable PciHeader. pub fn from_reader( - cfg_access: &dyn CfgAccess, + cfg_access: &dyn ConfigRegionAccess, addr: PciAddress, ) -> Result { if unsafe { cfg_access.read(addr, 0) } != 0xffffffff { @@ -308,15 +309,21 @@ impl PciHeader { mod test { use std::convert::TryInto; + use pci_types::{ConfigRegionAccess, PciAddress}; + use super::{PciHeader, PciHeaderError, PciHeaderType}; - use crate::pci::{CfgAccess, PciAddress, PciBar, PciClass}; + use crate::pci::{PciBar, PciClass}; struct TestCfgAccess<'a> { addr: PciAddress, bytes: &'a [u8], } - impl CfgAccess for TestCfgAccess<'_> { + impl ConfigRegionAccess for TestCfgAccess<'_> { + fn function_exists(&self, _address: PciAddress) -> bool { + unreachable!(); + } + unsafe fn read(&self, addr: PciAddress, offset: u16) -> u32 { assert_eq!(addr, self.addr); let offset = offset as usize; @@ -329,6 +336,7 @@ mod test { } } + #[rustfmt::skip] const IGB_DEV_BYTES: [u8; 256] = [ 0x86, 0x80, 0x33, 0x15, 0x07, 0x04, 0x10, 0x00, 0x03, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x58, 0xf7,