浏览代码

Add initial support for the HPET (#16)

gegy1000 6 年之前
父节点
当前提交
c5975fb771
共有 4 个文件被更改,包括 92 次插入23 次删除
  1. 3 23
      src/fadt.rs
  2. 56 0
      src/hpet.rs
  3. 27 0
      src/lib.rs
  4. 6 0
      src/sdt.rs

+ 3 - 23
src/fadt.rs

@@ -1,14 +1,5 @@
 use sdt::SdtHeader;
-use {AcpiError, PhysicalMapping};
-
-#[repr(C, packed)]
-struct GenericAddress {
-    address_space: u8,
-    bit_width: u8,
-    bit_offset: u8,
-    access_size: u8,
-    address: u64,
-}
+use {AcpiError, GenericAddress, PhysicalMapping};
 
 #[repr(C, packed)]
 pub struct Fadt {
@@ -82,21 +73,10 @@ pub fn parse_fadt(mapping: &PhysicalMapping<Fadt>) -> Result<(), AcpiError> {
 
 #[cfg(test)]
 mod tests {
-    use fadt::{Fadt, GenericAddress};
+    use fadt::Fadt;
     use sdt::SdtHeader;
     use std::mem;
-
-    impl GenericAddress {
-        fn make_testcase() -> GenericAddress {
-            GenericAddress {
-                address_space: 0 as u8,
-                bit_width: 0 as u8,
-                bit_offset: 0 as u8,
-                access_size: 0 as u8,
-                address: 0 as u64,
-            }
-        }
-    }
+    use GenericAddress;
 
     impl Fadt {
         fn make_testcase(

+ 56 - 0
src/hpet.rs

@@ -0,0 +1,56 @@
+use sdt::SdtHeader;
+use {AcpiError, GenericAddress, PhysicalMapping};
+
+#[repr(C, packed)]
+pub struct Hpet {
+    header: SdtHeader,
+
+    event_timer_block_id: u32,
+    base_address: GenericAddress,
+    hpet_number: u8,
+    clock_tick_unit: u16,
+    page_protection_oem: u8,
+}
+
+pub fn parse_hpet(mapping: &PhysicalMapping<Hpet>) -> Result<(), AcpiError> {
+    (*mapping).header.validate(b"HPET")?;
+
+    Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+    use hpet::Hpet;
+    use sdt::SdtHeader;
+    use std::mem;
+    use GenericAddress;
+
+    impl Hpet {
+        fn make_testcase(
+            oem_id: [u8; 6],
+            oem_table_id: [u8; 8],
+            oem_revision: u32,
+            creator_id: u32,
+            creator_revision: u32,
+        ) -> Hpet {
+            Hpet {
+                header: SdtHeader::make_testcase(
+                    *b"HPET",
+                    mem::size_of::<Hpet>() as u32,
+                    1,
+                    3, //checksum
+                    oem_id,
+                    oem_table_id,
+                    oem_revision,
+                    creator_id,
+                    creator_revision,
+                ),
+                event_timer_block_id: 0,
+                base_address: GenericAddress::make_testcase(),
+                hpet_number: 0,
+                clock_tick_unit: 0,
+                page_protection_oem: 0,
+            }
+        }
+    }
+}

+ 27 - 0
src/lib.rs

@@ -8,6 +8,7 @@ extern crate std;
 extern crate log;
 
 mod fadt;
+mod hpet;
 mod rsdp;
 mod sdt;
 
@@ -31,6 +32,15 @@ pub enum AcpiError {
     FadtIncorrectSignature,
 }
 
+#[repr(C, packed)]
+pub struct GenericAddress {
+    address_space: u8,
+    bit_width: u8,
+    bit_offset: u8,
+    access_size: u8,
+    address: u64,
+}
+
 /// Describes a physical mapping created by `AcpiHandler::map_physical_region` and unmapped by
 /// `AcpiHandler::unmap_physical_region`. The region mapped must be at least `size_of::<T>()`
 /// bytes, but may be bigger.
@@ -146,3 +156,20 @@ where
     handler.unmap_physical_region(mapping);
     Ok(())
 }
+
+#[cfg(test)]
+mod tests {
+    use GenericAddress;
+
+    impl GenericAddress {
+        pub(crate) fn make_testcase() -> GenericAddress {
+            GenericAddress {
+                address_space: 0 as u8,
+                bit_width: 0 as u8,
+                bit_offset: 0 as u8,
+                access_size: 0 as u8,
+                address: 0 as u64,
+            }
+        }
+    }
+}

+ 6 - 0
src/sdt.rs

@@ -1,5 +1,6 @@
 use core::str;
 use fadt::Fadt;
+use hpet::Hpet;
 use {AcpiError, AcpiHandler};
 
 /// All SDTs share the same header, and are `length` bytes long. The signature tells us which SDT
@@ -123,6 +124,11 @@ where
                 ::fadt::parse_fadt(&fadt_mapping)?;
                 handler.unmap_physical_region(fadt_mapping);
             }
+            "HPET" => {
+                let hpet_mapping = handler.map_physical_region::<Hpet>(physical_address);
+                ::hpet::parse_hpet(&hpet_mapping)?;
+                handler.unmap_physical_region(hpet_mapping);
+            }
 
             _ => {
                 /*