Files
RedBear-OS/pcid/src/driver_interface/cap.rs
T
bjorn3 15d2078a13 Handle daemonization of pcid in a better way
Currently pcid exits the main thread once it is done spawning drivers
and expects all background threads handling driver communication to stay
around. This only works as exitting the main thread on redox os
currently doesn't cause the whole process to die. This will have to be
fixed at some point for compatibility with programs that expect that
exitting the main thread kills all other threads in the process, at
which point pcid would break without the changes in this commit.
2024-07-20 15:11:34 +02:00

39 lines
1.3 KiB
Rust

use pci_types::capability::PciCapabilityAddress;
use pci_types::ConfigRegionAccess;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct VendorSpecificCapability {
pub data: Vec<u8>,
}
impl VendorSpecificCapability {
pub unsafe fn parse(addr: PciCapabilityAddress, access: &dyn ConfigRegionAccess) -> Self {
let dword = access.read(addr.address, addr.offset);
let next = (dword >> 8) & 0xFF;
let length = ((dword >> 16) & 0xFF) as u16;
log::info!(
"Vendor specific offset: {:#02x} next: {next:#02x} cap len: {length:#02x}",
addr.offset
);
let data = if length > 0 {
assert!(
length > 3 && length % 4 == 0,
"invalid range length: {}",
length
);
let mut raw_data = {
(addr.offset..addr.offset + length)
.step_by(4)
.flat_map(|offset| access.read(addr.address, offset).to_le_bytes())
.collect::<Vec<u8>>()
};
raw_data.drain(3..).collect()
} else {
log::warn!("Vendor specific capability is invalid");
Vec::new()
};
VendorSpecificCapability { data }
}
}