use heterob::{bit_numbering::Lsb, endianness::Le, Seq, P2, P6};
use super::{ExtendedCapabilityDataError, ExtendedCapabilityHeaderPlaceholder};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RootComplexRegisterBlockHeader {
pub vendor_id: u16,
pub device_id: u16,
pub rcrb_capabilities: RcrbCapabilities,
pub rcrb_control: RcrbControl,
}
impl RootComplexRegisterBlockHeader {
pub const SIZE: usize = 0x14;
}
impl From<[u8; Self::SIZE]> for RootComplexRegisterBlockHeader {
fn from(bytes: [u8; Self::SIZE]) -> Self {
let Le((
ExtendedCapabilityHeaderPlaceholder,
vendor_id,
device_id,
rcrb_capabilities,
rcrb_control,
rsvdz,
)) = P6(bytes).into();
let _: u32 = rsvdz;
Self {
vendor_id,
device_id,
rcrb_capabilities: From::<u32>::from(rcrb_capabilities),
rcrb_control: From::<u32>::from(rcrb_control),
}
}
}
impl TryFrom<&[u8]> for RootComplexRegisterBlockHeader {
type Error = ExtendedCapabilityDataError;
fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
let Seq { head, .. } = slice.try_into().map_err(|_| ExtendedCapabilityDataError {
name: "RCRB Header",
size: Self::SIZE,
})?;
Ok(From::<[u8; Self::SIZE]>::from(head))
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RcrbCapabilities {
pub crs_software_visibility: bool,
}
impl From<u32> for RcrbCapabilities {
fn from(dword: u32) -> Self {
let Lsb((crs_software_visibility, ())) = P2::<_, 1, 31>(dword).into();
Self {
crs_software_visibility,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RcrbControl {
pub crs_software_visibility_enable: bool,
}
impl From<u32> for RcrbControl {
fn from(dword: u32) -> Self {
let Lsb((crs_software_visibility_enable, ())) = P2::<_, 1, 31>(dword).into();
Self {
crs_software_visibility_enable,
}
}
}