Browse Source

Extract AML table info properly

Isaac Woods 6 years ago
parent
commit
98fe2ebe52
3 changed files with 41 additions and 14 deletions
  1. 18 6
      acpi/src/fadt.rs
  2. 21 6
      acpi/src/lib.rs
  3. 2 2
      acpi/src/sdt.rs

+ 18 - 6
acpi/src/fadt.rs

@@ -1,4 +1,12 @@
-use crate::{sdt::SdtHeader, Acpi, AcpiError, AcpiHandler, GenericAddress, PhysicalMapping};
+use crate::{
+    sdt::SdtHeader,
+    Acpi,
+    AcpiError,
+    AcpiHandler,
+    AmlTable,
+    GenericAddress,
+    PhysicalMapping,
+};
 
 type ExtendedField<T> = crate::sdt::ExtendedField<T, typenum::U2>;
 
@@ -84,15 +92,19 @@ where
     let fadt = &*mapping;
     fadt.header.validate(b"FACP")?;
 
-    unsafe {
-        acpi.dsdt_address = fadt
-            .x_dsdt_address
+    let dsdt_address = unsafe {
+        fadt.x_dsdt_address
             .get(fadt.header.revision())
             .filter(|p| *p != 0)
             .or(Some(fadt.dsdt_address as u64))
             .filter(|p| *p != 0)
-            .map(|p| p as usize);
-    }
+            .map(|p| p as usize)
+    };
+
+    acpi.dsdt = dsdt_address.map(|address| {
+        let dsdt_header = crate::sdt::peek_at_sdt_header(handler, address);
+        AmlTable::new(address, dsdt_header.length())
+    });
 
     Ok(())
 }

+ 21 - 6
acpi/src/lib.rs

@@ -104,6 +104,21 @@ pub struct Processor {
     pub is_ap: bool,
 }
 
+#[derive(Debug)]
+pub struct AmlTable {
+    /// Physical address of the start of the AML stream (excluding the table header).
+    pub address: usize,
+    /// Length (in bytes) of the AML stream.
+    pub length: u32,
+}
+
+impl AmlTable {
+    /// Create an `AmlTable` from the address and length of the table **including the SDT header**.
+    pub(crate) fn new(address: usize, length: u32) -> AmlTable {
+        AmlTable {
+            address: address + mem::size_of::<SdtHeader>(),
+            length: length - mem::size_of::<SdtHeader>() as u32,
+        }
     }
 }
 
@@ -119,11 +134,11 @@ pub struct Acpi {
     interrupt_model: Option<InterruptModel>,
     hpet: Option<HpetInfo>,
 
-    /// The physical address of the DSDT, if we manage to find it.
-    dsdt_address: Option<usize>,
+    /// Info about the DSDT, if we find it.
+    dsdt: Option<AmlTable>,
 
-    /// The physical addresses of the SSDTs, if there are any,
-    ssdt_addresses: Vec<usize>,
+    /// Info about any SSDTs, if there are any.
+    ssdts: Vec<AmlTable>,
 }
 
 impl Acpi {
@@ -206,8 +221,8 @@ where
         application_processors: Vec::new(),
         interrupt_model: None,
         hpet: None,
-        dsdt_address: None,
-        ssdt_addresses: Vec::with_capacity(0),
+        dsdt: None,
+        ssdts: Vec::with_capacity(0),
     };
 
     let header = sdt::peek_at_sdt_header(handler, physical_address);

+ 2 - 2
acpi/src/sdt.rs

@@ -1,4 +1,4 @@
-use crate::{fadt::Fadt, hpet::HpetTable, madt::Madt, Acpi, AcpiError, AcpiHandler};
+use crate::{fadt::Fadt, hpet::HpetTable, madt::Madt, Acpi, AcpiError, AcpiHandler, AmlTable};
 use core::{marker::PhantomData, mem, str};
 use log::{trace, warn};
 use typenum::Unsigned;
@@ -198,7 +198,7 @@ where
             handler.unmap_physical_region(madt_mapping);
         }
 
-        "SSDT" => acpi.ssdt_addresses.push(physical_address),
+        "SSDT" => acpi.ssdts.push(AmlTable::new(physical_address, header.length())),
 
         signature => {
             /*