acpica_bindings/interface/types/
tables.rs

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