diff --git a/local/recipes/drivers/redox-driver-sys/source/src/pcid_client.rs b/local/recipes/drivers/redox-driver-sys/source/src/pcid_client.rs index 1bb0cf5dd..7b6e8103e 100644 --- a/local/recipes/drivers/redox-driver-sys/source/src/pcid_client.rs +++ b/local/recipes/drivers/redox-driver-sys/source/src/pcid_client.rs @@ -5,13 +5,54 @@ use std::path::Path; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use crate::pci::{PciBarInfo, PciBarKind, PciDeviceInfo, PciLocation, PCI_HEADER_TYPE_NORMAL}; + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub enum PciBar { + None, + Memory32 { addr: u32, size: u32 }, + Memory64 { addr: u64, size: u64 }, + Port(u16), +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub struct LegacyInterruptLine { + pub irq: u8, + pub phandled: Option<(u32, [u32; 3], usize)>, +} + +#[derive(Clone, Copy, Debug, 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, +} + #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub struct PciFunction { pub segment: u16, pub bus: u8, pub device: u8, pub function: u8, - pub irq: Option, + pub bars: [PciBar; 6], + pub rom: Option, + pub legacy_interrupt_line: Option, + pub full_device_id: FullDeviceId, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub struct PciRom { + pub addr: u32, + pub size: u32, + pub enabled: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SubdriverArguments { + pub func: PciFunction, } #[derive(Debug, Serialize, Deserialize)] @@ -25,7 +66,7 @@ pub enum PcidClientRequest { #[derive(Debug, Serialize, Deserialize)] pub enum PcidClientResponse { EnabledDevice, - Config(PciFunction), + Config(SubdriverArguments), ReadConfig(u32), WriteConfig, Error(String), @@ -63,8 +104,6 @@ impl PcidClient { fn send(&mut self, msg: &T) -> Result<(), std::io::Error> { let data = bincode::serialize(msg) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; - let len = data.len() as u64; - self.channel.write_all(&len.to_le_bytes())?; self.channel.write_all(&data)?; Ok(()) } @@ -88,7 +127,7 @@ impl PcidClient { pub fn request_config(&mut self) -> Result { self.send(&PcidClientRequest::RequestConfig)?; match self.recv()? { - PcidClientResponse::Config(func) => Ok(func), + PcidClientResponse::Config(args) => Ok(args.func), other => Err(std::io::Error::new( std::io::ErrorKind::InvalidData, format!("unexpected response: {other:?}"), @@ -133,3 +172,66 @@ impl PcidClient { self.channel.into_raw_fd() } } + +impl PciFunction { + pub fn location(&self) -> PciLocation { + PciLocation { + segment: self.segment, + bus: self.bus, + device: self.device, + function: self.function, + } + } + + pub fn device_info(&self) -> PciDeviceInfo { + PciDeviceInfo { + location: self.location(), + vendor_id: self.full_device_id.vendor_id, + device_id: self.full_device_id.device_id, + subsystem_vendor_id: 0xffff, + subsystem_device_id: 0xffff, + revision: self.full_device_id.revision, + class_code: self.full_device_id.class, + subclass: self.full_device_id.subclass, + prog_if: self.full_device_id.interface, + header_type: PCI_HEADER_TYPE_NORMAL, + irq: self.legacy_interrupt_line.map(|irq| u32::from(irq.irq)), + bars: self + .bars + .iter() + .enumerate() + .map(|(index, bar)| match *bar { + PciBar::None => PciBarInfo { + index, + kind: PciBarKind::None, + addr: 0, + size: 0, + prefetchable: false, + }, + PciBar::Memory32 { addr, size } => PciBarInfo { + index, + kind: PciBarKind::Memory32, + addr: u64::from(addr), + size: u64::from(size), + prefetchable: false, + }, + PciBar::Memory64 { addr, size } => PciBarInfo { + index, + kind: PciBarKind::Memory64, + addr, + size, + prefetchable: false, + }, + PciBar::Port(port) => PciBarInfo { + index, + kind: PciBarKind::Io, + addr: u64::from(port), + size: 0, + prefetchable: false, + }, + }) + .collect(), + capabilities: Vec::new(), + } + } +}