-
-
Notifications
You must be signed in to change notification settings - Fork 88
Add functions to get and clear pending events for Pm1EventRegisterBlock #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| use crate::{AcpiError, Handler, address::MappedGas, sdt::fadt::Fadt}; | ||
| use bit_field::BitField; | ||
| use bitflags::{Flags, bitflags}; | ||
|
|
||
| pub struct FixedRegisters<H: Handler> { | ||
| pub pm1_event_registers: Pm1EventRegisterBlock<H>, | ||
|
|
@@ -58,6 +59,19 @@ pub enum Pm1Event { | |
| Wake = 15, | ||
| } | ||
|
|
||
| bitflags! { | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
| pub struct Pm1EventFlags: u16 { | ||
| const TIMER = 1 << 0; | ||
| const GLOBAL_LOCK = 1 << 5; | ||
| const POWER_BUTTON = 1 << 8; | ||
| const SLEEP_BUTTON = 1 << 9; | ||
| const RTC = 1 << 10; | ||
| const PCIE_WAKE = 1 << 14; | ||
| const WAKE = 1 << 15; | ||
| } | ||
| } | ||
|
|
||
| impl<H> Pm1EventRegisterBlock<H> | ||
| where | ||
| H: Handler, | ||
|
|
@@ -95,6 +109,25 @@ where | |
|
|
||
| Ok(pm1a | pm1b) | ||
| } | ||
|
|
||
| pub fn pending_events(&self) -> Pm1EventFlags { | ||
| let bits = { | ||
| let mut bits = self.pm1a.read_u16(0); | ||
| if let Some(pm1b) = &self.pm1b { | ||
| bits |= pm1b.read_u16(0); | ||
| } | ||
| bits | ||
| }; | ||
| Pm1EventFlags::from_bits_retain(bits) | ||
| } | ||
|
|
||
| pub fn clear_events(&self, events: Pm1EventFlags) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't read the spec on this in quite a while (but remember wiring this up locally ages ago) - is it a useful API to clear all events, or would it be better to clear a specific event that you've handled (I assume by writing with an individual bit set)?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way I have it now where you specify which events to clear is better. If you clear all events, you might miss an event.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies, I somehow misread this as clearing all the events. Yes, this is good. |
||
| let bits = events.known_bits(); | ||
| self.pm1a.write_u16(0, bits); | ||
| if let Some(pm1b) = &self.pm1b { | ||
| pm1b.write_u16(0, bits); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub struct Pm1ControlRegisterBlock<H: Handler> { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if a cleaner way of doing this would be to have a method to derive a
GenericAddresswith a different access width from another one? (i.e. 'split' the GAS into the different registers?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do that. Then we could make functions for getting the status register and getting the control register. Would the derived GAS use lifetimes or Arc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a random thought - splitting a
MappedGashas the potential to create fun withPhysicalMapping::drop, because you'll need to ensure thePhysicalMappinggets dropped only once. So if you create two newMappedGasobjects you could:MappedGasHandlers inManuallyDropor similar - but then the splitMappedGasobjects have a different type to the originals.I suppose what I'm trying to say is to be careful 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yes, very true Martin 😬
I wonder if the safest way would be to have a 'cast' effectively
fn cast(self) -> MappedGasand some sort of way to duplicate a mapping, but that does seem inefficient? Maybe this isn't so bad after all?