summary refs log tree commit diff
path: root/acpi_tables/src/rsdp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'acpi_tables/src/rsdp.rs')
-rw-r--r--acpi_tables/src/rsdp.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/acpi_tables/src/rsdp.rs b/acpi_tables/src/rsdp.rs
new file mode 100644
index 0000000..4bf64c9
--- /dev/null
+++ b/acpi_tables/src/rsdp.rs
@@ -0,0 +1,67 @@
+// Copyright 2020 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use data_model::DataInit;
+
+#[repr(packed)]
+#[derive(Clone, Copy, Default)]
+pub struct RSDP {
+    pub signature: [u8; 8],
+    pub checksum: u8,
+    pub oem_id: [u8; 6],
+    pub revision: u8,
+    _rsdt_addr: u32,
+    pub length: u32,
+    pub xsdt_addr: u64,
+    pub extended_checksum: u8,
+    _reserved: [u8; 3],
+}
+
+// Safe as RSDP structure only contains raw data
+unsafe impl DataInit for RSDP {}
+
+impl RSDP {
+    pub fn new(oem_id: [u8; 6], xsdt_addr: u64) -> Self {
+        let mut rsdp = RSDP {
+            signature: *b"RSD PTR ",
+            checksum: 0,
+            oem_id,
+            revision: 2,
+            _rsdt_addr: 0,
+            length: std::mem::size_of::<RSDP>() as u32,
+            xsdt_addr,
+            extended_checksum: 0,
+            _reserved: [0; 3],
+        };
+
+        rsdp.checksum = super::generate_checksum(&rsdp.as_slice()[0..19]);
+        rsdp.extended_checksum = super::generate_checksum(&rsdp.as_slice());
+        rsdp
+    }
+
+    pub fn len() -> usize {
+        std::mem::size_of::<RSDP>()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::RSDP;
+    use data_model::DataInit;
+
+    #[test]
+    fn test_rsdp() {
+        let rsdp = RSDP::new(*b"CHYPER", 0xdead_beef);
+        let sum = rsdp
+            .as_slice()
+            .iter()
+            .fold(0u8, |acc, x| acc.wrapping_add(*x));
+        assert_eq!(sum, 0);
+        let sum: u8 = rsdp
+            .as_slice()
+            .iter()
+            .fold(0u8, |acc, x| acc.wrapping_add(*x));
+        assert_eq!(sum, 0);
+    }
+}