diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index aedbf86f77..cc6dad2392 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -175,6 +175,8 @@ pub enum PcidClientRequest { FeatureStatus(PciFeature), FeatureInfo(PciFeature), SetFeatureInfo(SetFeatureInfo), + ReadConfig(u16), + WriteConfig(u16, u32), } #[derive(Debug, Serialize, Deserialize)] @@ -195,6 +197,8 @@ pub enum PcidClientResponse { Error(PcidServerResponseError), FeatureInfo(PciFeature, PciFeatureInfo), SetFeatureInfo(PciFeature), + ReadConfig(u32), + WriteConfig, } // TODO: Ideally, pcid might have its own scheme, like lots of other Redox drivers, where this kind of IPC is done. Otherwise, instead of writing serde messages over @@ -296,4 +300,18 @@ impl PcidServerHandle { other => Err(PcidClientHandleError::InvalidResponse(other)), } } + pub unsafe fn read_config(&mut self, offset: u16) -> Result { + self.send(&PcidClientRequest::ReadConfig(offset))?; + match self.recv()? { + PcidClientResponse::ReadConfig(value) => Ok(value), + other => Err(PcidClientHandleError::InvalidResponse(other)), + } + } + pub unsafe fn write_config(&mut self, offset: u16, value: u32) -> Result<()> { + self.send(&PcidClientRequest::WriteConfig(offset, value))?; + match self.recv()? { + PcidClientResponse::WriteConfig => Ok(()), + other => Err(PcidClientHandleError::InvalidResponse(other)), + } + } } diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 3dee0e8963..a298739c6d 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -12,6 +12,7 @@ use redox_log::{OutputBuilder, RedoxLogger}; use crate::config::Config; use crate::pci::{CfgAccess, Pci, PciIter, PciBar, PciBus, PciClass, PciDev, PciFunc, PciHeader, PciHeaderError, PciHeaderType}; use crate::pci::cap::Capability as PciCapability; +use crate::pci::func::{ConfigReader, ConfigWriter}; use crate::pcie::Pcie; mod config; @@ -180,6 +181,22 @@ impl DriverHandler { return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(PciFeature::MsiX)); } } + 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| { + func.read_u32(offset) + }) + }; + return PcidClientResponse::ReadConfig(value); + }, + PcidClientRequest::WriteConfig(offset, value) => { + unsafe { + with_pci_func_raw(self.state.preferred_cfg_access(), self.bus_num, self.dev_num, self.func_num, |func| { + func.write_u32(offset, value); + }); + } + return PcidClientResponse::WriteConfig; + } } } fn handle_spawn(mut self, pcid_to_client_write: Option, pcid_from_client_read: Option, args: driver_interface::SubdriverArguments) { diff --git a/pcid/src/pci/mod.rs b/pcid/src/pci/mod.rs index 033693b2c1..e1a18b472f 100644 --- a/pcid/src/pci/mod.rs +++ b/pcid/src/pci/mod.rs @@ -18,7 +18,7 @@ mod bus; pub mod cap; mod class; mod dev; -mod func; +pub mod func; pub mod header; pub mod msi;