From 2b5ed69a06cb57e9b05ff26d490f7d1c491dd962 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:34:54 +0100 Subject: [PATCH] Use PciAddress in a couple more places --- nvmed/src/main.rs | 4 +- pcid/src/driver_interface/mod.rs | 17 +++---- pcid/src/main.rs | 81 ++++++++++++-------------------- pcid/src/pci/mod.rs | 5 +- 4 files changed, 41 insertions(+), 66 deletions(-) diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index 9074dcc4d7..2fed31c18c 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -11,7 +11,7 @@ use std::{slice, usize}; use pcid_interface::{PciBar, PciFeature, PciFeatureInfo, PciFunction, PcidServerHandle}; use syscall::{ - Event, Mmio, Packet, Result, SchemeBlockMut, + Event, Mmio, Packet, Result, SchemeBlockMut, PAGE_SIZE, }; use redox_log::{OutputBuilder, RedoxLogger}; @@ -299,7 +299,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .fetch_config() .expect("nvmed: failed to fetch config"); - let mut scheme_name = format!("disk.pci-{:x}+{:x}+{:x}-nvme", pci_config.func.bus_num, pci_config.func.dev_num, pci_config.func.func_num); + let scheme_name = format!("disk.pci-{}-nvme", pci_config.func.addr); let _logger_ref = setup_logging(&scheme_name); diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index e563c6d06a..1132423793 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -4,12 +4,12 @@ use std::{env, io}; use std::os::unix::io::{FromRawFd, RawFd}; -use serde::{Serialize, Deserialize, de::DeserializeOwned}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use thiserror::Error; pub use crate::pci::cap::Capability; pub use crate::pci::msi; -pub use crate::pci::{PciBar, PciHeader}; +pub use crate::pci::{PciAddress, PciBar, PciHeader}; pub mod irq_helpers; @@ -28,14 +28,8 @@ pub enum LegacyInterruptPin { #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub struct PciFunction { - /// Number of PCI bus - pub bus_num: u8, - - /// Number of PCI device - pub dev_num: u8, - - /// Number of PCI function - pub func_num: u8, + /// Address of the PCI function. + pub addr: PciAddress, /// PCI Base Address Registers pub bars: [PciBar; 6], @@ -58,7 +52,8 @@ pub struct PciFunction { } impl PciFunction { pub fn name(&self) -> String { - format!("pci-{:>02X}.{:>02X}.{:>02X}", self.bus_num, self.dev_num, self.func_num) + // FIXME stop replacing : with - once it is a valid character in scheme names + format!("pci-{}", self.addr).replace(':', "-") } } diff --git a/pcid/src/main.rs b/pcid/src/main.rs index ccdcc52aa3..0806a7701a 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -34,24 +34,22 @@ struct Args { pub struct DriverHandler { config: config::DriverConfig, - bus_num: u8, - dev_num: u8, - func_num: u8, + addr: PciAddress, header: PciHeader, capabilities: Vec<(u8, PciCapability)>, state: Arc, } -fn with_pci_func_raw T>(pci: &dyn CfgAccess, bus_num: u8, dev_num: u8, func_num: u8, function: F) -> T { +fn with_pci_func_raw T>(pci: &dyn CfgAccess, addr: PciAddress, function: F) -> T { let func = PciFunc { pci, - addr: PciAddress::new(0, bus_num, dev_num, func_num), + addr, }; function(&func) } impl DriverHandler { fn with_pci_func_raw T>(&self, function: F) -> T { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, function) + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, function) } fn respond(&mut self, request: driver_interface::PcidClientRequest, args: &driver_interface::SubdriverArguments) -> driver_interface::PcidClientResponse { use driver_interface::*; @@ -81,7 +79,7 @@ impl DriverHandler { None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)), }; unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { capability.set_enabled(true); capability.write_message_control(func, offset); }); @@ -94,7 +92,7 @@ impl DriverHandler { None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)), }; unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { capability.set_msix_enabled(true); capability.write_a(func, offset); }); @@ -154,7 +152,7 @@ impl DriverHandler { info.set_mask_bits(mask_bits); } unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { info.write_all(func, offset); }); } @@ -166,7 +164,7 @@ impl DriverHandler { if let Some(mask) = function_mask { info.set_function_mask(mask); unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { info.write_a(func, offset); }); } @@ -178,7 +176,7 @@ impl DriverHandler { } PcidClientRequest::ReadConfig(offset) => { let value = unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { func.read_u32(offset) }) }; @@ -186,7 +184,7 @@ impl DriverHandler { }, PcidClientRequest::WriteConfig(offset, value) => { unsafe { - with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + with_pci_func_raw(self.state.preferred_cfg_access(), self.addr, |func| { func.write_u32(offset, value); }); } @@ -222,13 +220,12 @@ impl State { } } -fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, - dev_num: u8, func_num: u8, header: PciHeader) { +fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, header: PciHeader) { let pci = state.preferred_cfg_access(); let raw_class: u8 = header.class().into(); - let mut string = format!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}", - bus_num, dev_num, func_num, header.vendor_id(), header.device_id(), raw_class, + let mut string = format!("PCI {} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}", + addr, header.vendor_id(), header.device_id(), raw_class, header.subclass(), header.interface(), header.revision(), header.class()); match header.class() { PciClass::Legacy if header.subclass() == 1 => string.push_str(" VGA CTL"), @@ -319,9 +316,9 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, if let Some(ref args) = driver.command { // Enable bus mastering, memory space, and I/O space unsafe { - let mut data = pci.read(PciAddress::new(0, bus_num, dev_num, func_num), 0x04); + let mut data = pci.read(addr, 0x04); data |= 7; - pci.write(PciAddress::new(0, bus_num, dev_num, func_num), 0x04, data); + pci.write(addr, 0x04, data); } // Set IRQ line to 9 if not set @@ -329,14 +326,14 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, let mut interrupt_pin; unsafe { - let mut data = pci.read(PciAddress::new(0, bus_num, dev_num, func_num), 0x3C); + let mut data = pci.read(addr, 0x3C); irq = (data & 0xFF) as u8; interrupt_pin = ((data & 0x0000_FF00) >> 8) as u8; if irq == 0xFF { irq = 9; } data = (data & 0xFFFFFF00) | irq as u32; - pci.write(PciAddress::new(0, bus_num, dev_num, func_num), 0x3C, data); + pci.write(addr, 0x3C, data); }; // Find BAR sizes @@ -355,25 +352,11 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, let offset = 0x10 + (i as u8) * 4; - let original = pci.read( - PciAddress::new(0, bus_num, dev_num, func_num), - offset.into(), - ); - pci.write( - PciAddress::new(0, bus_num, dev_num, func_num), - offset.into(), - 0xFFFFFFFF, - ); + let original = pci.read(addr, offset.into()); + pci.write(addr, offset.into(), 0xFFFFFFFF); - let new = pci.read( - PciAddress::new(0, bus_num, dev_num, func_num), - offset.into(), - ); - pci.write( - PciAddress::new(0, bus_num, dev_num, func_num), - offset.into(), - original, - ); + let new = pci.read(addr, offset.into()); + pci.write(addr, offset.into(), original); let masked = if new & 1 == 1 { new & 0xFFFFFFFC @@ -393,7 +376,7 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, let capabilities = if header.status() & (1 << 4) != 0 { let func = PciFunc { pci: state.preferred_cfg_access(), - addr: PciAddress::new(0, bus_num, dev_num, func_num), + addr }; crate::pci::cap::CapabilitiesIter { inner: crate::pci::cap::CapabilityOffsetsIter::new(header.cap_pointer(), &func) }.collect::>() } else { @@ -419,9 +402,7 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, let func = driver_interface::PciFunction { bars, bar_sizes, - bus_num, - dev_num, - func_num, + addr, devid: header.device_id(), legacy_interrupt_line: irq, legacy_interrupt_pin, @@ -437,9 +418,9 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, let mut command = Command::new(program); for arg in args { let arg = match arg.as_str() { - "$BUS" => format!("{:>02X}", bus_num), - "$DEV" => format!("{:>02X}", dev_num), - "$FUNC" => format!("{:>02X}", func_num), + "$BUS" => format!("{:>02X}", addr.bus()), + "$DEV" => format!("{:>02X}", addr.device()), + "$FUNC" => format!("{:>02X}", addr.function()), "$NAME" => func.name(), "$BAR0" => format!("{}", bars[0]), "$BAR1" => format!("{}", bars[1]), @@ -489,9 +470,7 @@ fn handle_parsed_header(state: Arc, config: &Config, bus_num: u8, match command.envs(envs).spawn() { Ok(mut child) => { let driver_handler = DriverHandler { - bus_num, - dev_num, - func_num, + addr, config: driver.clone(), header, state: Arc::clone(&state), @@ -618,16 +597,16 @@ fn main(args: Args) { let bus = PciBus { num: bus_num }; 'dev: for dev in bus.devs() { for func in dev.funcs(pci) { - let func_num = func.addr.function(); + let func_addr = func.addr; match PciHeader::from_reader(func) { Ok(header) => { - handle_parsed_header(Arc::clone(&state), &config, bus.num, dev.num, func_num, header); + handle_parsed_header(Arc::clone(&state), &config, func_addr, header); if let PciHeader::PciToPci { secondary_bus_num, .. } = header { bus_nums.push(secondary_bus_num); } } Err(PciHeaderError::NoDevice) => { - if func_num == 0 { + if func_addr.function() == 0 { if dev.num == 0 { trace!("PCI {:>02X}: no bus", bus.num); continue 'bus; diff --git a/pcid/src/pci/mod.rs b/pcid/src/pci/mod.rs index 708da62150..84baf13f53 100644 --- a/pcid/src/pci/mod.rs +++ b/pcid/src/pci/mod.rs @@ -3,6 +3,7 @@ use std::fmt; use std::sync::{Mutex, Once}; use bit_field::BitField; +use serde::{Deserialize, Serialize}; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use syscall::io::{Io as _, Pio}; @@ -29,7 +30,7 @@ pub trait CfgAccess { unsafe fn write(&self, addr: PciAddress, offset: u16, value: u32); } -// Copied from the pci_types crate, version 0.6.1. +// 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. /// @@ -41,7 +42,7 @@ pub trait CfgAccess { /// | segment | bus | device | func | /// +-------------------------------+---------------+---------+------+ /// ``` -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)] pub struct PciAddress(u32); impl PciAddress {