Skip to content
Open
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
50 changes: 50 additions & 0 deletions src/aml/interrupt_model_used.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use alloc::vec;
use core::str::FromStr;

use crate::{
Handler,
aml::{
AmlError,
Interpreter,
namespace::AmlName,
object::{Object, WrappedObject},
},
};

/// See <https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html?highlight=_pic#pic-method>.
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub enum InterruptModelUsed {
/// 0 - PIC mode
PicMode,
/// 1 - APIC mode
ApicMode,
/// 2 - SAPIC mode
SapicMode,
}

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

impl<H> Interpreter<H>
where
H: Handler,
{
/// Calls the [`\_PIC` method](https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html?highlight=_pic#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