From 2a369cfba4bf3938b67dd4a43be674190e98291c Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 3 Oct 2023 10:59:01 +0300 Subject: [PATCH 1/2] acpi: expose PM1x fixed hardware feature registers --- acpi/src/fadt.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/acpi/src/fadt.rs b/acpi/src/fadt.rs index f97c4e61..2f6df91c 100644 --- a/acpi/src/fadt.rs +++ b/acpi/src/fadt.rs @@ -20,6 +20,20 @@ pub enum PowerProfile { Reserved(u8), } +/// PM1x status and enable registers. These registers are part of PM1x event blocks and provide +/// access to fixed hardware status/enable features like power button, power management timer etc. +#[derive(Debug, Clone)] +pub struct Pm1Registers { + /// PM1a fixed hardware status register + pub x_pm1a_status: GenericAddress, + /// PM1a fixed hardware enable register + pub x_pm1a_enable: GenericAddress, + /// PM1b fixed hardware status register + pub x_pm1b_status: Option, + /// PM1b fixed hardware enable register + pub x_pm1b_enable: Option, +} + /// Represents the Fixed ACPI Description Table (FADT). This table contains various fixed hardware /// details, such as the addresses of the hardware register blocks. It also contains a pointer to /// the Differentiated Definition Block (DSDT). @@ -346,6 +360,53 @@ impl Fadt { Ok(None) } } + + /// Returns the PM1x fixed hardware feature registers + pub fn pm1_registers(&self) -> Result { + let pm1a_event_block = self.pm1a_event_block()?; + let pm1b_event_block = self.pm1b_event_block()?; + let pm1_byte_width = pm1a_event_block.bit_width / 16; + + let x_pm1a_status = GenericAddress { + address_space: pm1a_event_block.address_space, + address: pm1a_event_block.address, + bit_width: pm1_byte_width * 8, + bit_offset: 0, + access_size: AccessSize::Undefined, + }; + let x_pm1a_enable = GenericAddress { + address_space: pm1a_event_block.address_space, + address: pm1a_event_block.address + pm1_byte_width as u64, + bit_width: pm1_byte_width * 8, + bit_offset: 0, + access_size: AccessSize::Undefined, + }; + + let (x_pm1b_status, x_pm1b_enable) = if let Some(pm1b) = pm1b_event_block { + ( + Some(GenericAddress { + address_space: pm1b.address_space, + address: pm1b.address, + bit_width: pm1_byte_width * 8, + bit_offset: 0, + access_size: AccessSize::Undefined, + }), + Some({ + GenericAddress { + address_space: pm1b.address_space, + address: pm1b.address + pm1_byte_width as u64, + bit_width: pm1_byte_width * 8, + bit_offset: 0, + access_size: AccessSize::Undefined, + } + }), + ) + } else { + (None, None) + }; + + Ok(Pm1Registers { x_pm1a_status, x_pm1a_enable, x_pm1b_status, x_pm1b_enable }) + } } #[derive(Clone, Copy, Debug)] From 408f8b402b4d3c2e8b7f808a67a3eb7f9ea929e8 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Tue, 3 Oct 2023 11:03:59 +0300 Subject: [PATCH 2/2] acpi: expose GPEn block lengths in FADT --- acpi/src/fadt.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/acpi/src/fadt.rs b/acpi/src/fadt.rs index 2f6df91c..913ae928 100644 --- a/acpi/src/fadt.rs +++ b/acpi/src/fadt.rs @@ -407,6 +407,26 @@ impl Fadt { Ok(Pm1Registers { x_pm1a_status, x_pm1a_enable, x_pm1b_status, x_pm1b_enable }) } + + /// Returns the length of General-Purpose Event register block 0 in bytes. + /// + /// # Note + /// + /// The GPE blocks are optional, their presence first needs to be checked through gpe0_block(). + #[inline] + pub const fn gpe0_block_length(&self) -> u8 { + self.gpe0_block_length + } + + /// Returns the length of General-Purpose Event register block 1 in bytes. + /// + /// # Note + /// + /// The GPE blocks are optional, their presence first needs to be checked through gpe0_block(). + #[inline] + pub const fn gpe1_block_length(&self) -> u8 { + self.gpe1_block_length + } } #[derive(Clone, Copy, Debug)]