浏览代码

Add methods for the FADT register blocks

Isaac Woods 4 年之前
父节点
当前提交
b0c65c4781
共有 1 个文件被更改,包括 154 次插入19 次删除
  1. 154 19
      acpi/src/fadt.rs

+ 154 - 19
acpi/src/fadt.rs

@@ -1,5 +1,5 @@
 use crate::{
-    platform::address::{GenericAddress, RawGenericAddress},
+    platform::address::{AccessSize, AddressSpace, GenericAddress, RawGenericAddress},
     sdt::{ExtendedField, SdtHeader},
     AcpiError,
     AcpiTable,
@@ -92,11 +92,13 @@ pub struct Fadt {
     pub day_alarm: u8,
     pub month_alarm: u8,
     pub century: u8,
+    // TODO: expose through a type
     iapc_boot_arch: u16,
     _reserved2: u8, // must be 0
     pub flags: Flags,
     reset_reg: RawGenericAddress,
     pub reset_value: u8,
+    // TODO: expose through a type
     arm_boot_arch: u16,
     fadt_minor_version: u8,
     x_firmware_ctrl: ExtendedField<u64, 2>,
@@ -164,26 +166,159 @@ impl Fadt {
         }
     }
 
-    pub fn pm_timer_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
-        let raw = unsafe {
-            self.x_pm_timer_block.access(self.header().revision).or_else(|| {
-                if self.pm_timer_block != 0 {
-                    Some(RawGenericAddress {
-                        address_space: 1,
-                        bit_width: 0,
-                        bit_offset: 0,
-                        access_size: self.pm_timer_length,
-                        address: self.pm_timer_block.into(),
-                    })
-                } else {
-                    None
-                }
+    pub fn pm1a_event_block(&self) -> Result<GenericAddress, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm1a_event_block.access(self.header().revision) } {
+            Ok(GenericAddress::from_raw(raw)?)
+        } else {
+            Ok(GenericAddress {
+                address_space: AddressSpace::SystemIo,
+                bit_width: self.pm1_event_length * 8,
+                bit_offset: 0,
+                access_size: AccessSize::Undefined,
+                address: self.pm1a_event_block.into(),
+            })
+        }
+    }
+
+    pub fn pm1b_event_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm1b_event_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.pm1b_event_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.pm1_event_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.pm1b_event_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn pm1a_control_block(&self) -> Result<GenericAddress, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm1a_control_block.access(self.header().revision) } {
+            Ok(GenericAddress::from_raw(raw)?)
+        } else {
+            Ok(GenericAddress {
+                address_space: AddressSpace::SystemIo,
+                bit_width: self.pm1_control_length * 8,
+                bit_offset: 0,
+                access_size: AccessSize::Undefined,
+                address: self.pm1a_control_block.into(),
             })
-        };
+        }
+    }
+
+    pub fn pm1b_control_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm1b_control_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.pm1b_control_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.pm1_control_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.pm1b_control_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn pm2_control_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm2_control_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.pm2_control_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.pm2_control_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.pm2_control_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn pm_timer_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_pm_timer_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.pm_timer_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.pm_timer_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.pm_timer_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn gpe0_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_gpe0_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.gpe0_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.gpe0_block_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.gpe0_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn gpe1_block(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.x_gpe1_block.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            if self.gpe1_block != 0 {
+                Ok(Some(GenericAddress {
+                    address_space: AddressSpace::SystemIo,
+                    bit_width: self.gpe1_block_length * 8,
+                    bit_offset: 0,
+                    access_size: AccessSize::Undefined,
+                    address: self.gpe1_block.into(),
+                }))
+            } else {
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn reset_register(&self) -> Result<GenericAddress, AcpiError> {
+        GenericAddress::from_raw(self.reset_reg)
+    }
+
+    pub fn sleep_control_register(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.sleep_control_reg.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            Ok(None)
+        }
+    }
 
-        match raw {
-            Some(raw) => Ok(Some(GenericAddress::from_raw(raw)?)),
-            None => Ok(None),
+    pub fn sleep_status_register(&self) -> Result<Option<GenericAddress>, AcpiError> {
+        if let Some(raw) = unsafe { self.sleep_status_reg.access(self.header().revision) } {
+            Ok(Some(GenericAddress::from_raw(raw)?))
+        } else {
+            Ok(None)
         }
     }
 }