|
@@ -1,5 +1,5 @@
|
|
|
use crate::{fadt::Fadt, hpet::HpetTable, madt::Madt, mcfg::Mcfg, Acpi, AcpiError, AcpiHandler, AmlTable};
|
|
|
-use core::{mem, mem::MaybeUninit, str};
|
|
|
+use core::{fmt, mem, mem::MaybeUninit, str};
|
|
|
use log::{trace, warn};
|
|
|
|
|
|
pub const ACPI_VERSION_2_0: u8 = 20;
|
|
@@ -60,7 +60,7 @@ impl<T: Copy, const MIN_VERSION: u8> ExtendedField<T, MIN_VERSION> {
|
|
|
#[derive(Clone, Copy)]
|
|
|
#[repr(C, packed)]
|
|
|
pub struct SdtHeader {
|
|
|
- signature: [u8; 4],
|
|
|
+ pub signature: Signature,
|
|
|
pub length: u32,
|
|
|
pub revision: u8,
|
|
|
pub checksum: u8,
|
|
@@ -77,20 +77,20 @@ impl SdtHeader {
|
|
|
/// b) The checksum of the SDT
|
|
|
///
|
|
|
/// This assumes that the whole SDT is mapped.
|
|
|
- pub fn validate(&self, signature: &[u8; 4]) -> Result<(), AcpiError> {
|
|
|
+ pub fn validate(&self, signature: Signature) -> Result<(), AcpiError> {
|
|
|
// Check the signature
|
|
|
- if &self.signature != signature {
|
|
|
- return Err(AcpiError::SdtInvalidSignature(*signature));
|
|
|
+ if self.signature != signature {
|
|
|
+ return Err(AcpiError::SdtInvalidSignature(signature));
|
|
|
}
|
|
|
|
|
|
// Check the OEM id
|
|
|
if str::from_utf8(&self.oem_id).is_err() {
|
|
|
- return Err(AcpiError::SdtInvalidOemId(*signature));
|
|
|
+ return Err(AcpiError::SdtInvalidOemId(signature));
|
|
|
}
|
|
|
|
|
|
// Check the OEM table id
|
|
|
if str::from_utf8(&self.oem_table_id).is_err() {
|
|
|
- return Err(AcpiError::SdtInvalidTableId(*signature));
|
|
|
+ return Err(AcpiError::SdtInvalidTableId(signature));
|
|
|
}
|
|
|
|
|
|
// Validate the checksum
|
|
@@ -101,7 +101,7 @@ impl SdtHeader {
|
|
|
}
|
|
|
|
|
|
if sum > 0 {
|
|
|
- return Err(AcpiError::SdtInvalidChecksum(*signature));
|
|
|
+ return Err(AcpiError::SdtInvalidChecksum(signature));
|
|
|
}
|
|
|
|
|
|
Ok(())
|
|
@@ -118,6 +118,36 @@ impl SdtHeader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[derive(Clone, Copy, PartialEq, Eq)]
|
|
|
+#[repr(transparent)]
|
|
|
+pub struct Signature([u8; 4]);
|
|
|
+
|
|
|
+impl Signature {
|
|
|
+ pub const RSDT: Signature = Signature(*b"RSDT");
|
|
|
+ pub const XSDT: Signature = Signature(*b"XSDT");
|
|
|
+ pub const FADT: Signature = Signature(*b"FACP");
|
|
|
+ pub const HPET: Signature = Signature(*b"HPET");
|
|
|
+ pub const MADT: Signature = Signature(*b"APIC");
|
|
|
+ pub const MCFG: Signature = Signature(*b"MCFG");
|
|
|
+ pub const SSDT: Signature = Signature(*b"SSDT");
|
|
|
+
|
|
|
+ pub fn as_str(&self) -> &str {
|
|
|
+ str::from_utf8(&self.0).unwrap()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl fmt::Display for Signature {
|
|
|
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
+ write!(f, "{}", self.as_str())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl fmt::Debug for Signature {
|
|
|
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
+ write!(f, "\"{}\"", self.as_str())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/// Takes the physical address of an SDT, and maps, clones and unmaps its header. Useful for
|
|
|
/// finding out how big it is to map it correctly later.
|
|
|
pub(crate) fn peek_at_sdt_header<H>(handler: &mut H, physical_address: usize) -> SdtHeader
|
|
@@ -144,33 +174,33 @@ where
|
|
|
* For a recognised signature, a new physical mapping should be created with the correct type
|
|
|
* and length, and then the dispatched to the correct function to actually parse the table.
|
|
|
*/
|
|
|
- "FACP" => {
|
|
|
match header.signature {
|
|
|
+ Signature::FADT => {
|
|
|
let fadt_mapping = handler.map_physical_region::<Fadt>(physical_address, mem::size_of::<Fadt>());
|
|
|
crate::fadt::parse_fadt(acpi, handler, &fadt_mapping)?;
|
|
|
handler.unmap_physical_region(fadt_mapping);
|
|
|
}
|
|
|
|
|
|
- "HPET" => {
|
|
|
+ Signature::HPET => {
|
|
|
let hpet_mapping =
|
|
|
handler.map_physical_region::<HpetTable>(physical_address, mem::size_of::<HpetTable>());
|
|
|
crate::hpet::parse_hpet(acpi, &hpet_mapping)?;
|
|
|
handler.unmap_physical_region(hpet_mapping);
|
|
|
}
|
|
|
|
|
|
- "APIC" => {
|
|
|
- let madt_mapping = handler.map_physical_region::<Madt>(physical_address, header.length() as usize);
|
|
|
+ Signature::MADT => {
|
|
|
+ let madt_mapping = handler.map_physical_region::<Madt>(physical_address, header.length as usize);
|
|
|
crate::madt::parse_madt(acpi, handler, &madt_mapping)?;
|
|
|
handler.unmap_physical_region(madt_mapping);
|
|
|
}
|
|
|
|
|
|
- "MCFG" => {
|
|
|
- let mcfg_mapping = handler.map_physical_region::<Mcfg>(physical_address, header.length() as usize);
|
|
|
+ Signature::MCFG => {
|
|
|
+ let mcfg_mapping = handler.map_physical_region::<Mcfg>(physical_address, header.length as usize);
|
|
|
crate::mcfg::parse_mcfg(acpi, &mcfg_mapping)?;
|
|
|
handler.unmap_physical_region(mcfg_mapping);
|
|
|
}
|
|
|
|
|
|
- "SSDT" => acpi.ssdts.push(AmlTable::new(physical_address, header.length())),
|
|
|
+ Signature::SSDT => acpi.ssdts.push(AmlTable::new(physical_address, header.length)),
|
|
|
|
|
|
signature => {
|
|
|
/*
|