1use std::{
7 io::{Error, ErrorKind},
8 ptr,
9};
10
11pub const CSV_RTMR_VERSION_MAX: u16 = 1;
12pub const CSV_RTMR_VERSION_MIN: u16 = 1;
13
14pub const CSV_RTMR_REG_SIZE: usize = 32;
15pub const CSV_RTMR_EXTEND_LEN: usize = CSV_RTMR_REG_SIZE;
16
17pub const CSV_RTMR_REG_NUM: usize = 5;
18pub const CSV_RTMR_REG_INDEX_MAX: usize = CSV_RTMR_REG_NUM - 1;
19
20#[repr(u16)]
21pub enum CsvGuestUserRtmrSubcmd {
22 Status = 0x1,
23 Start = 0x2,
24 Read = 0x3,
25 Extend = 0x4,
26}
27
28#[repr(u8)]
29pub enum CsvGuestRtmrStatus {
30 Uninit = 0x0,
31 Init = 0x1,
32 Working = 0x2,
33}
34
35#[repr(C, packed)]
36#[derive(Debug, Default)]
37pub struct CsvGuestUserRtmrStatus {
38 pub version: u16,
40 pub state: u8,
42}
43
44impl CsvGuestUserRtmrStatus {
45 pub fn new() -> Self {
47 Self::default()
48 }
49}
50
51#[repr(C, packed)]
52#[derive(Debug)]
53pub struct CsvGuestUserRtmrStart {
54 pub version: u16,
56}
57
58impl CsvGuestUserRtmrStart {
59 pub fn new(version: u16) -> Self {
61 Self { version }
62 }
63}
64
65#[repr(C, packed)]
66#[derive(Debug)]
67pub struct CsvGuestUserRtmrRead {
68 pub bitmap: u32,
70 pub data: [u8; CSV_RTMR_REG_SIZE],
72}
73
74impl CsvGuestUserRtmrRead {
75 pub fn new(bitmap: u32) -> Self {
76 Self {
77 bitmap,
78 data: [0; CSV_RTMR_REG_SIZE],
79 }
80 }
81
82 pub fn allocate_with_capacity(bitmap: u32, num_regs: usize) -> (Box<[u8]>, &'static mut Self) {
83 let total_size = std::mem::size_of::<Self>() + (num_regs - 1) * CSV_RTMR_REG_SIZE;
84 let mut buffer = vec![0u8; total_size].into_boxed_slice();
85
86 let read = CsvGuestUserRtmrRead {
87 bitmap,
88 data: [0; CSV_RTMR_REG_SIZE],
89 };
90
91 unsafe {
92 let ptr = buffer.as_mut_ptr() as *mut Self;
93 ptr::write(ptr, read);
94
95 (buffer, &mut *ptr)
96 }
97 }
98
99 pub fn get_read_reg(&self, bit: usize) -> &[u8; CSV_RTMR_REG_SIZE] {
100 unsafe {
101 let ptr = self.data.as_ptr().add(bit * CSV_RTMR_REG_SIZE) as *const _;
102 &*ptr
103 }
104 }
105}
106
107#[repr(C, packed)]
108#[derive(Debug)]
109pub struct CsvGuestUserRtmrExtend {
110 pub index: u8,
112 pub rsvd: u8,
114 pub data_len: u16,
116 pub data: [u8; CSV_RTMR_EXTEND_LEN],
118}
119
120impl CsvGuestUserRtmrExtend {
121 pub fn new(index: u8, data: &[u8]) -> Result<Self, Error> {
123 if data.len() < CSV_RTMR_EXTEND_LEN {
124 Err(Error::new(
125 ErrorKind::InvalidInput,
126 format!("invalid length: expected >= {}", CSV_RTMR_EXTEND_LEN),
127 ))
128 } else {
129 let mut array = [0u8; CSV_RTMR_EXTEND_LEN];
130
131 array[0..CSV_RTMR_EXTEND_LEN].copy_from_slice(&data[0..CSV_RTMR_EXTEND_LEN]);
132
133 Ok(Self {
134 index,
135 rsvd: 0,
136 data_len: CSV_RTMR_EXTEND_LEN as u16,
137 data: array,
138 })
139 }
140 }
141}