Start using the pci_types crate
This commit is contained in:
Generated
+17
-6
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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<PciAddressDef> 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
|
||||
|
||||
+4
-3
@@ -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<State>,
|
||||
}
|
||||
fn with_pci_func_raw<T, F: FnOnce(&PciFunc) -> T>(pci: &dyn CfgAccess, addr: PciAddress, function: F) -> T {
|
||||
fn with_pci_func_raw<T, F: FnOnce(&PciFunc) -> 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<u8> {
|
||||
@@ -33,7 +32,7 @@ pub trait ConfigWriter {
|
||||
}
|
||||
|
||||
pub struct PciFunc<'pci> {
|
||||
pub pci: &'pci dyn CfgAccess,
|
||||
pub pci: &'pci dyn ConfigRegionAccess,
|
||||
pub addr: PciAddress,
|
||||
}
|
||||
|
||||
|
||||
+1
-71
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-4
@@ -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<PciHeader, PciHeaderError> {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user