Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/aml/interrupt_model_used.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use alloc::vec;
use core::str::FromStr;

use crate::{
Handler,
aml::{
AmlError,
BaseInterpreter,
namespace::AmlName,
object::{Object, WrappedObject},
op_region::RegionHandler,
},
};

/// See the [the docs for the `\_PIC` method](https://uefi.org/specs/ACPI/6.6/05_ACPI_Software_Programming_Model.html#pic-method).
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub enum InterruptModelUsed {
/// 0 - PIC mode
PicMode,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to either add the values to the first three, or remove from the last three?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left the first 3 to 0,1,2 implicitly, there's no reason not to add the values to them, I just felt lazy ig. The important thing is that 3 is left as Reserved.

/// 1 - APIC mode
ApicMode,
/// 2 - SAPIC mode
SapicMode,
/// 4 – GIC model
GicModel = 4,
/// 5 – LPIC model
LpicModel = 5,
/// 6 – RINTC model
RintcModel = 6,
}

impl From<InterruptModelUsed> for Object {
fn from(value: InterruptModelUsed) -> Self {
Self::Integer(match value {
InterruptModelUsed::PicMode => 0,
InterruptModelUsed::ApicMode => 1,
InterruptModelUsed::SapicMode => 2,
InterruptModelUsed::GicModel => 4,
InterruptModelUsed::LpicModel => 5,
InterruptModelUsed::RintcModel => 6,
})
}
}

impl<H, R> BaseInterpreter<H, R>
where
H: Handler,
R: RegionHandler + ?Sized,
{
/// Calls the [`\_PIC` method](https://uefi.org/specs/ACPI/6.6/05_ACPI_Software_Programming_Model.html#pic-method).
/// The method is optional, so if it doesn't exist this function returns success. Returns `true` is the method was called, `false` if it doesn't exist.
pub fn set_interrupt_model_used(&self, model: InterruptModelUsed) -> Result<bool, AmlError> {
Ok(self
.evaluate_if_present(
AmlName::from_str(r#"\_PIC"#).expect("valid name"),
vec![WrappedObject::new(model.into())],
)?
.is_some())
}
}
2 changes: 2 additions & 0 deletions src/aml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* - Fuzzing and guarantee panic-free interpretation
*/

mod interrupt_model_used;
pub mod namespace;
pub mod object;
pub mod op_region;
Expand Down Expand Up @@ -47,6 +48,7 @@ use core::{
str::FromStr,
sync::atomic::{AtomicU64, Ordering},
};
pub use interrupt_model_used::InterruptModelUsed;
use log::{error, info, trace, warn};
use namespace::{AmlName, Namespace, NamespaceLevelKind};
use object::{
Expand Down
4 changes: 4 additions & 0 deletions src/aml/pci_routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ impl PciRoutingTable {
/// `AmlError::InvalidOperationOnObject` if the value passed is not a package, or if any of the
/// values within it are not packages. Returns the various `AmlError::Prt*` errors if the
/// internal structure of the entries is invalid.
///
/// Before calling this method, `\_PIC` should be called. See [`Interpreter::set_interrupt_model_used`].
/// The evaluation of `_PRT` can depend on the interrupt model being used. If `\_PIC` is not called,
/// the evaluation of PCI interrupts to GSI numbers can return incorrect results.
pub fn from_prt_path(
prt_path: AmlName,
interpreter: &Interpreter<impl Handler>,
Expand Down
Loading