use crate::BinaryGuid;
use r_efi::efi;
use zerocopy::FromBytes;
pub const SIGNATURE: u32 = u32::from_le_bytes([b'M', b'S', b'U', b'P']);
pub const REVISION: u32 = 1;
pub const MM_SUPERVISOR_REQUEST_HANDLER_GUID: BinaryGuid =
BinaryGuid::from_string("8c633b23-1260-4ea6-830f-7ddc97382111");
#[derive(Debug, Clone, Copy, zerocopy_derive::FromBytes, zerocopy_derive::IntoBytes, zerocopy_derive::Immutable)]
#[repr(C)]
pub struct MmSupervisorRequestHeader {
pub signature: u32,
pub revision: u32,
pub request: u32,
pub reserved: u32,
pub result: u64,
}
impl MmSupervisorRequestHeader {
pub const SIZE: usize = core::mem::size_of::<Self>();
pub fn is_valid(&self) -> bool {
self.signature == SIGNATURE && self.revision <= REVISION
}
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
Self::read_from_bytes(bytes.get(..Self::SIZE)?).ok()
}
}
#[derive(
Debug,
Clone,
Copy,
zerocopy_derive::FromBytes,
zerocopy_derive::IntoBytes,
zerocopy_derive::Immutable,
zerocopy_derive::KnownLayout
)]
#[repr(C)]
pub struct MmSupervisorVersionInfo {
pub version: u32,
pub patch_level: u32,
pub max_supervisor_request_level: u64,
}
impl MmSupervisorVersionInfo {
pub const SIZE: usize = core::mem::size_of::<Self>();
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
Self::read_from_bytes(bytes.get(..Self::SIZE)?).ok()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RequestType {
UnblockMem = 0x0001,
FetchPolicy = 0x0002,
VersionInfo = 0x0003,
CommUpdate = 0x0004,
}
impl RequestType {
pub const MAX_REQUEST_TYPE: u64 = Self::CommUpdate as u64;
}
impl TryFrom<u32> for RequestType {
type Error = u32;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0x0001 => Ok(Self::UnblockMem),
0x0002 => Ok(Self::FetchPolicy),
0x0003 => Ok(Self::VersionInfo),
0x0004 => Ok(Self::CommUpdate),
other => Err(other),
}
}
}
impl From<RequestType> for u32 {
fn from(request_type: RequestType) -> Self {
request_type as u32
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResponseType {
InvalidRequest,
InvalidDataBuffer,
CommBufferInitError,
}
impl From<ResponseType> for efi::Status {
fn from(response_type: ResponseType) -> Self {
match response_type {
ResponseType::InvalidRequest => efi::Status::INVALID_PARAMETER,
ResponseType::InvalidDataBuffer => efi::Status::BUFFER_TOO_SMALL,
ResponseType::CommBufferInitError => efi::Status::DEVICE_ERROR,
}
}
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct MmSupervisorUnblockMemoryParams {
pub memory_descriptor: efi::MemoryDescriptor,
pub identifier_guid: BinaryGuid,
}
impl MmSupervisorUnblockMemoryParams {
pub const SIZE: usize = core::mem::size_of::<Self>();
}