Procházet zdrojové kódy

Create public GenericAddress representation, rename current to RawGenericAddress

Isaac Woods před 4 roky
rodič
revize
eee897782c
4 změnil soubory, kde provedl 112 přidání a 24 odebrání
  1. 12 12
      acpi/src/fadt.rs
  2. 2 2
      acpi/src/hpet.rs
  3. 1 10
      acpi/src/lib.rs
  4. 97 0
      acpi/src/platform/address.rs

+ 12 - 12
acpi/src/fadt.rs

@@ -1,8 +1,8 @@
 use crate::{
+    platform::address::RawGenericAddress,
     sdt::{ExtendedField, SdtHeader},
     AcpiError,
     AcpiTable,
-    GenericAddress,
 };
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -71,22 +71,22 @@ pub struct Fadt {
     iapc_boot_arch: u16,
     _reserved2: u8, // must be 0
     flags: u32,
-    reset_reg: GenericAddress,
+    reset_reg: RawGenericAddress,
     reset_value: u8,
     arm_boot_arch: u16,
     fadt_minor_version: u8,
     x_firmware_ctrl: ExtendedField<u64, 2>,
     x_dsdt_address: ExtendedField<u64, 2>,
-    x_pm1a_event_block: ExtendedField<GenericAddress, 2>,
-    x_pm1b_event_block: ExtendedField<GenericAddress, 2>,
-    x_pm1a_control_block: ExtendedField<GenericAddress, 2>,
-    x_pm1b_control_block: ExtendedField<GenericAddress, 2>,
-    x_pm2_control_block: ExtendedField<GenericAddress, 2>,
-    x_pm_timer_block: ExtendedField<GenericAddress, 2>,
-    x_gpe0_block: ExtendedField<GenericAddress, 2>,
-    x_gpe1_block: ExtendedField<GenericAddress, 2>,
-    sleep_control_reg: ExtendedField<GenericAddress, 2>,
-    sleep_status_reg: ExtendedField<GenericAddress, 2>,
+    x_pm1a_event_block: ExtendedField<RawGenericAddress, 2>,
+    x_pm1b_event_block: ExtendedField<RawGenericAddress, 2>,
+    x_pm1a_control_block: ExtendedField<RawGenericAddress, 2>,
+    x_pm1b_control_block: ExtendedField<RawGenericAddress, 2>,
+    x_pm2_control_block: ExtendedField<RawGenericAddress, 2>,
+    x_pm_timer_block: ExtendedField<RawGenericAddress, 2>,
+    x_gpe0_block: ExtendedField<RawGenericAddress, 2>,
+    x_gpe1_block: ExtendedField<RawGenericAddress, 2>,
+    sleep_control_reg: ExtendedField<RawGenericAddress, 2>,
+    sleep_status_reg: ExtendedField<RawGenericAddress, 2>,
     hypervisor_vendor_id: ExtendedField<u64, 2>,
 }
 

+ 2 - 2
acpi/src/hpet.rs

@@ -1,4 +1,4 @@
-use crate::{sdt::SdtHeader, AcpiError, AcpiHandler, AcpiTable, AcpiTables, GenericAddress};
+use crate::{platform::address::RawGenericAddress, sdt::SdtHeader, AcpiError, AcpiHandler, AcpiTable, AcpiTables};
 use bit_field::BitField;
 
 #[derive(Debug)]
@@ -56,7 +56,7 @@ impl HpetInfo {
 pub(crate) struct HpetTable {
     header: SdtHeader,
     event_timer_block_id: u32,
-    base_address: GenericAddress,
+    base_address: RawGenericAddress,
     hpet_number: u8,
     clock_tick_unit: u16,
     page_protection_oem: u8,

+ 1 - 10
acpi/src/lib.rs

@@ -83,6 +83,7 @@ pub enum AcpiError {
     TableMissing(Signature),
     InvalidDsdtAddress,
     InvalidMadt(MadtError),
+    InvalidGenericAddress,
 }
 
 pub struct AcpiTables<H>
@@ -301,13 +302,3 @@ impl AmlTable {
         }
     }
 }
-
-#[derive(Clone, Copy, Debug)]
-#[repr(C, packed)]
-pub(crate) struct GenericAddress {
-    address_space: u8,
-    bit_width: u8,
-    bit_offset: u8,
-    access_size: u8,
-    address: u64,
-}

+ 97 - 0
acpi/src/platform/address.rs

@@ -0,0 +1,97 @@
+//! ACPI defines a Generic Address Structure (GAS), which provides a versatile way to describe register locations
+//! in a wide range of address spaces.
+
+use crate::AcpiError;
+
+/// This is the raw form of a Generic Address Structure, and follows the layout found in the ACPI tables. It does
+/// not form part of the public API, and should be turned into a `GenericAddress` for most use-cases.
+#[derive(Clone, Copy, Debug)]
+#[repr(C, packed)]
+pub(crate) struct RawGenericAddress {
+    pub address_space: u8,
+    pub bit_width: u8,
+    pub bit_offset: u8,
+    pub access_size: u8,
+    pub address: u64,
+}
+
+#[derive(Clone, Copy, Debug)]
+pub enum AddressSpace {
+    SystemMemory,
+    SystemIo,
+    /// Describes a register in the configuration space of a PCI device in segment `0`, on bus `0`. The `address`
+    /// field is of the format:
+    /// ```ignore
+    /// 64              48              32              16               0
+    ///  +---------------+---------------+---------------+---------------+
+    ///  |  reserved (0) |    device     |   function    |    offset     |
+    ///  +---------------+---------------+---------------+---------------+
+    /// ```
+    PciConfigSpace,
+    EmbeddedController,
+    SMBus,
+    SystemCmos,
+    PciBarTarget,
+    Ipmi,
+    GeneralIo,
+    GenericSerialBus,
+    PlatformCommunicationsChannel,
+    FunctionalFixedHardware,
+    OemDefined(u8),
+}
+
+#[derive(Clone, Copy, Debug)]
+pub enum AccessSize {
+    Undefined,
+    ByteAccess,
+    WordAccess,
+    DWordAccess,
+    QWordAccess,
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct GenericAddress {
+    pub address_space: AddressSpace,
+    pub bit_width: u8,
+    pub bit_offset: u8,
+    pub access_size: AccessSize,
+    pub address: u64,
+}
+
+impl GenericAddress {
+    pub(crate) fn from_raw(raw: RawGenericAddress) -> Result<GenericAddress, AcpiError> {
+        let address_space = match raw.address_space {
+            0x00 => AddressSpace::SystemMemory,
+            0x01 => AddressSpace::SystemIo,
+            0x02 => AddressSpace::PciConfigSpace,
+            0x03 => AddressSpace::EmbeddedController,
+            0x04 => AddressSpace::SMBus,
+            0x05 => AddressSpace::SystemCmos,
+            0x06 => AddressSpace::PciBarTarget,
+            0x07 => AddressSpace::Ipmi,
+            0x08 => AddressSpace::GeneralIo,
+            0x09 => AddressSpace::GenericSerialBus,
+            0x0a => AddressSpace::PlatformCommunicationsChannel,
+            0x0b..=0x7e => return Err(AcpiError::InvalidGenericAddress),
+            0x7f => AddressSpace::FunctionalFixedHardware,
+            0x80..=0xbf => return Err(AcpiError::InvalidGenericAddress),
+            0xc0..=0xff => AddressSpace::OemDefined(raw.address_space),
+        };
+        let access_size = match raw.access_size {
+            0 => AccessSize::Undefined,
+            1 => AccessSize::ByteAccess,
+            2 => AccessSize::WordAccess,
+            3 => AccessSize::DWordAccess,
+            4 => AccessSize::QWordAccess,
+            _ => return Err(AcpiError::InvalidGenericAddress),
+        };
+
+        Ok(GenericAddress {
+            address_space,
+            bit_width: raw.bit_width,
+            bit_offset: raw.bit_offset,
+            access_size,
+            address: raw.address,
+        })
+    }
+}