浏览代码

Add DSDT representation and mapping

Isaac Woods 7 年之前
父节点
当前提交
88d079446f
共有 4 个文件被更改,包括 59 次插入3 次删除
  1. 33 0
      src/dsdt.rs
  2. 24 2
      src/fadt.rs
  3. 1 0
      src/lib.rs
  4. 1 1
      src/sdt.rs

+ 33 - 0
src/dsdt.rs

@@ -0,0 +1,33 @@
+use core::{mem, slice};
+use sdt::SdtHeader;
+use {AcpiError, PhysicalMapping};
+
+/// Represents the Differentiated Definition Block (DSDT). This table contains the standard header,
+/// then an AML-encoded definition block.
+#[repr(C, packed)]
+pub struct Dsdt {
+    header: SdtHeader,
+}
+
+impl Dsdt {
+    pub fn validate(&self) -> Result<(), AcpiError> {
+        self.header.validate(b"DSDT")
+    }
+
+    /// Get the AML stream encoded in this table so it can be safely accessed
+    pub fn stream(&self) -> &[u8] {
+        assert!(self.header.length() as usize > mem::size_of::<SdtHeader>());
+        let stream_length = self.header.length() as usize - mem::size_of::<SdtHeader>();
+        let stream_ptr =
+            ((self as *const Dsdt as usize) + mem::size_of::<SdtHeader>()) as *const u8;
+        unsafe { slice::from_raw_parts(stream_ptr, stream_length) }
+    }
+}
+
+pub fn parse_dsdt(mapping: &PhysicalMapping<Dsdt>) -> Result<(), AcpiError> {
+    (*mapping).validate()?;
+
+    let stream = (*mapping).stream();
+    // TODO: pass off to the AML parser
+    unimplemented!();
+}

+ 24 - 2
src/fadt.rs

@@ -1,6 +1,14 @@
+use dsdt::{parse_dsdt, Dsdt};
 use sdt::SdtHeader;
-use {AcpiError, GenericAddress, PhysicalMapping};
+use {AcpiError, AcpiHandler, GenericAddress, PhysicalMapping};
 
+/// Represents the Fixed ACPI Description Table (FADT). This table contains various fixed hardware
+/// details, such as the addresses of the hardware register blocks. It also contains a pointer to
+/// the Differentiated Definition Block (DSDT).
+///
+/// In cases where the FADT contains both a 32-bit and 64-bit field for the same address, we should
+/// always prefer the 64-bit one. Only if it's zero or the CPU will not allow us to access that
+/// address should the 32-bit one be used.
 #[repr(C, packed)]
 pub struct Fadt {
     header: SdtHeader,
@@ -65,9 +73,23 @@ pub struct Fadt {
     hypervisor_vendor_id: u64,
 }
 
-pub fn parse_fadt(mapping: &PhysicalMapping<Fadt>) -> Result<(), AcpiError> {
+pub fn parse_fadt<H>(handler: &mut H, mapping: &PhysicalMapping<Fadt>) -> Result<(), AcpiError>
+where
+    H: AcpiHandler,
+{
     (*mapping).header.validate(b"FACP")?;
 
+    let dsdt_physical_address: usize = if (*mapping).x_dsdt_address != 0 {
+        (*mapping).x_dsdt_address as usize
+    } else {
+        (*mapping).dsdt_address as usize
+    };
+
+    // Parse the DSDT
+    let dsdt_mapping = handler.map_physical_region::<Dsdt>(dsdt_physical_address);
+    parse_dsdt(&dsdt_mapping)?;
+    handler.unmap_physical_region(dsdt_mapping);
+
     Ok(())
 }
 

+ 1 - 0
src/lib.rs

@@ -7,6 +7,7 @@ extern crate std;
 #[macro_use]
 extern crate log;
 
+mod dsdt;
 mod fadt;
 mod hpet;
 mod rsdp;

+ 1 - 1
src/sdt.rs

@@ -121,7 +121,7 @@ where
         match signature {
             "FACP" => {
                 let fadt_mapping = handler.map_physical_region::<Fadt>(physical_address);
-                ::fadt::parse_fadt(&fadt_mapping)?;
+                ::fadt::parse_fadt(handler, &fadt_mapping)?;
                 handler.unmap_physical_region(fadt_mapping);
             }
             "HPET" => {