use std::{
io::{Error, ErrorKind},
ptr,
};
pub const CSV_RTMR_VERSION_MAX: u16 = 1;
pub const CSV_RTMR_VERSION_MIN: u16 = 1;
pub const CSV_RTMR_REG_SIZE: usize = 32;
pub const CSV_RTMR_EXTEND_LEN: usize = CSV_RTMR_REG_SIZE;
pub const CSV_RTMR_REG_NUM: usize = 5;
pub const CSV_RTMR_REG_INDEX_MAX: usize = CSV_RTMR_REG_NUM - 1;
#[repr(u16)]
pub enum CsvGuestUserRtmrSubcmd {
Status = 0x1,
Start = 0x2,
Read = 0x3,
Extend = 0x4,
}
#[repr(u8)]
pub enum CsvGuestRtmrStatus {
Uninit = 0x0,
Init = 0x1,
Working = 0x2,
}
#[repr(C, packed)]
#[derive(Debug, Default)]
pub struct CsvGuestUserRtmrStatus {
pub version: u16,
pub state: u8,
}
impl CsvGuestUserRtmrStatus {
pub fn new() -> Self {
Self::default()
}
}
#[repr(C, packed)]
#[derive(Debug)]
pub struct CsvGuestUserRtmrStart {
pub version: u16,
}
impl CsvGuestUserRtmrStart {
pub fn new(version: u16) -> Self {
Self { version }
}
}
#[repr(C, packed)]
#[derive(Debug)]
pub struct CsvGuestUserRtmrRead {
pub bitmap: u32,
pub data: [u8; CSV_RTMR_REG_SIZE],
}
impl CsvGuestUserRtmrRead {
pub fn new(bitmap: u32) -> Self {
Self {
bitmap,
data: [0; CSV_RTMR_REG_SIZE],
}
}
pub fn allocate_with_capacity(bitmap: u32, num_regs: usize) -> (Box<[u8]>, &'static mut Self) {
let total_size = std::mem::size_of::<Self>() + (num_regs - 1) * CSV_RTMR_REG_SIZE;
let mut buffer = vec![0u8; total_size].into_boxed_slice();
let read = CsvGuestUserRtmrRead {
bitmap,
data: [0; CSV_RTMR_REG_SIZE],
};
unsafe {
let ptr = buffer.as_mut_ptr() as *mut Self;
ptr::write(ptr, read);
(buffer, &mut *ptr)
}
}
pub fn get_read_reg(&self, bit: usize) -> &[u8; CSV_RTMR_REG_SIZE] {
unsafe {
let ptr = self.data.as_ptr().add(bit * CSV_RTMR_REG_SIZE) as *const _;
&*ptr
}
}
}
#[repr(C, packed)]
#[derive(Debug)]
pub struct CsvGuestUserRtmrExtend {
pub index: u8,
pub rsvd: u8,
pub data_len: u16,
pub data: [u8; CSV_RTMR_EXTEND_LEN],
}
impl CsvGuestUserRtmrExtend {
pub fn new(index: u8, data: &[u8]) -> Result<Self, Error> {
if data.len() < CSV_RTMR_EXTEND_LEN {
Err(Error::new(
ErrorKind::InvalidInput,
format!("invalid length: expected >= {}", CSV_RTMR_EXTEND_LEN),
))
} else {
let mut array = [0u8; CSV_RTMR_EXTEND_LEN];
array[0..CSV_RTMR_EXTEND_LEN].copy_from_slice(&data[0..CSV_RTMR_EXTEND_LEN]);
Ok(Self {
index,
rsvd: 0,
data_len: CSV_RTMR_EXTEND_LEN as u16,
data: array,
})
}
}
}