feat: add redox-driver-sys pcid handoff client

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-05-07 20:52:33 +01:00
parent 6b97d076c3
commit e3a9a820ee
@@ -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<u8>,
pub bars: [PciBar; 6],
pub rom: Option<PciRom>,
pub legacy_interrupt_line: Option<LegacyInterruptLine>,
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<T: Serialize>(&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<PciFunction, std::io::Error> {
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(),
}
}
}