acpica_bindings/interface/types/tables.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
//! Contains the types for specific ACPI tables.
use core::fmt::Debug;
use crate::bindings::types::tables::FfiAcpiTableHeader;
pub mod fadt;
pub mod madt;
pub mod mcfg;
pub mod uefi;
pub use madt::Madt;
pub use uefi::Uefi;
/// Master ACPI Table Header. This common header is used by all ACPI tables
/// except the RSDP and FACS.
///
/// For more info on individual fields, see [the ACPI spec]
///
/// [the ACPI spec]: https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#system-description-table-header
pub struct AcpiTableHeader<'a>(&'a FfiAcpiTableHeader);
impl<'a> AcpiTableHeader<'a> {
pub(crate) fn from_ffi(ffi_header: &'a FfiAcpiTableHeader) -> Self {
Self(ffi_header)
}
pub(crate) fn as_ffi(&self) -> &FfiAcpiTableHeader {
self.0
}
}
impl<'a> Debug for AcpiTableHeader<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("AcpiTableHeader")
.field("signature", &self.signature())
.field("length", &self.length())
.field("revision", &self.revision())
.field("checksum", &self.checksum())
.field("oem_id", &self.oem_id())
.field("oem_table_id", &self.oem_table_id())
.field("oem_revision", &self.oem_revision())
.field("asl_compiler_id", &self.creator_id())
.field("asl_compiler_revision", &self.creator_revision())
.finish()
}
}
impl<'a> AcpiTableHeader<'a> {
/// The table's signature. This is a 4-byte ASCII string indicating what kind of data the table contains.
#[must_use]
#[allow(clippy::missing_panics_doc)] // ACPICA already checks that the string is ASCII
pub fn signature(&self) -> &str {
core::str::from_utf8(&self.0.signature).unwrap()
}
/// The length of the table in bytes
#[must_use]
pub fn length(&self) -> u32 {
self.0.length
}
/// The revision number of the table
#[must_use]
pub fn revision(&self) -> u8 {
self.0.revision
}
/// The table's checksum. This byte is set to make all the bytes in the table sum to 0 (mod 0xff)
#[must_use]
pub fn checksum(&self) -> u8 {
self.0.checksum
}
/// A string identifying the OEM
#[must_use]
#[allow(clippy::missing_panics_doc)] // ACPICA already checks that the string is ASCII
pub fn oem_id(&self) -> &str {
core::str::from_utf8(&self.0.oem_id).unwrap()
}
/// An OEM-provided string to identify this particular instance of a table
#[must_use]
#[allow(clippy::missing_panics_doc)] // ACPICA already checks that the string is ASCII
pub fn oem_table_id(&self) -> &str {
core::str::from_utf8(&self.0.oem_table_id).unwrap()
}
/// The table's revision number (larger is newer)
#[must_use]
pub fn oem_revision(&self) -> u32 {
self.0.oem_revision
}
/// An ASCII string identifying the tool used to create the table.
/// If the table contains AML code, this identifies the ASL compiler.
#[must_use]
#[allow(clippy::missing_panics_doc)] // ACPICA already checks that the string is ASCII
pub fn creator_id(&self) -> &str {
core::str::from_utf8(&self.0.asl_compiler_id).unwrap()
}
/// The revision number of the tool used to create the table (larger is newer)
/// If the table contains AML code, this is the revision number of the ASL compiler.
#[must_use]
pub fn creator_revision(&self) -> u32 {
self.0.asl_compiler_revision
}
/// Gets the rest of the table (all the table's data apart from the header) as a byte slice
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn content(&self) -> &'a [u8] {
// SAFETY: The rest of the table is the data, starting at the byte offset `data_offset` from the start of the table
unsafe {
let whole_table = core::slice::from_raw_parts(
(self.0 as *const FfiAcpiTableHeader).cast::<u8>(),
self.length().try_into().unwrap(),
);
&whole_table[36..]
}
}
}