Skip to main content

csv_rs/api/guest/
rtmr.rs

1// Copyright (C) Hygon Info Technologies Ltd.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6use 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    /// The rtmr version used in the guest.
39    pub version: u16,
40    /// The state of the guest's rtmr.
41    pub state: u8,
42}
43
44impl CsvGuestUserRtmrStatus {
45    /// Create a new rtmr_status request.
46    pub fn new() -> Self {
47        Self::default()
48    }
49}
50
51#[repr(C, packed)]
52#[derive(Debug)]
53pub struct CsvGuestUserRtmrStart {
54    /// The rtmr version requested by the caller.
55    pub version: u16,
56}
57
58impl CsvGuestUserRtmrStart {
59    /// Create a new rtmr_start request.
60    pub fn new(version: u16) -> Self {
61        Self { version }
62    }
63}
64
65#[repr(C, packed)]
66#[derive(Debug)]
67pub struct CsvGuestUserRtmrRead {
68    /// The bitmap specified the rtmr registers to read.
69    pub bitmap: u32,
70    /// The buffer to store the first rtmr register returned by the firmware.
71    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    /// The index of the specified rtmr register.
111    pub index: u8,
112    /// The reserved field, just for alignment.
113    pub rsvd: u8,
114    /// The length of the data to be extended.
115    pub data_len: u16,
116    /// The data to be extened.
117    pub data: [u8; CSV_RTMR_EXTEND_LEN],
118}
119
120impl CsvGuestUserRtmrExtend {
121    /// Create a new rtmr_extend request.
122    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}