Bladeren bron

Fix bug in extended field handling in the FADT

Before, we would report the existance of these optional fields if the
extended version of the field exists, even if its zero. For all of the
fields, if the extended field is zero (it's not entirely clear whether
we need to check the entire structure, or just the address?), we drop back
to the original field.
Isaac Woods 4 jaren geleden
bovenliggende
commit
0d7b29c46f
1 gewijzigde bestanden met toevoegingen van 107 en 91 verwijderingen
  1. 107 91
      acpi/src/fadt.rs

+ 107 - 91
acpi/src/fadt.rs

@@ -34,7 +34,7 @@ pub struct Fadt {
     firmware_ctrl: u32,
     dsdt_address: u32,
 
-    // used in acpi 1.0; compatibility only, should be zero
+    // Used in acpi 1.0; compatibility only, should be zero
     _reserved: u8,
 
     preferred_pm_profile: u8,
@@ -168,138 +168,154 @@ impl Fadt {
 
     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(),
-            })
+            if raw.address != 0x0 {
+                return Ok(GenericAddress::from_raw(raw)?);
+            }
         }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
-    }
 
-    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 {
+        if self.pm1b_event_block != 0 {
+            Ok(Some(GenericAddress {
                 address_space: AddressSpace::SystemIo,
-                bit_width: self.pm1_control_length * 8,
+                bit_width: self.pm1_event_length * 8,
                 bit_offset: 0,
                 access_size: AccessSize::Undefined,
-                address: self.pm1a_control_block.into(),
-            })
+                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) } {
+            if raw.address != 0x0 {
+                return Ok(GenericAddress::from_raw(raw)?);
+            }
+        }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
+
+        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)
+            if raw.address != 0x0 {
+                return Ok(Some(GenericAddress::from_raw(raw)?));
             }
         }
+
+        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> {