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:
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user