From f6c3d349658720aa7488d6a40b85a965d3f29c5b Mon Sep 17 00:00:00 2001 From: Rajas Paranjpe <52586855+ChocolateLoverRaj@users.noreply.github.com> Date: Sat, 19 Sep 2026 11:36:30 -0700 Subject: [PATCH] Add `set_interrupt_model_used` method for calling `\_PIC` Tested on QEMU q35 and Lenovo Ideapad Z560. --- src/aml/interrupt_model_used.rs | 50 +++++++++++++++++++++++++++++++++ src/aml/mod.rs | 2 ++ src/aml/pci_routing.rs | 4 +++ 3 files changed, 56 insertions(+) create mode 100644 src/aml/interrupt_model_used.rs diff --git a/src/aml/interrupt_model_used.rs b/src/aml/interrupt_model_used.rs new file mode 100644 index 00000000..f6f3f40a --- /dev/null +++ b/src/aml/interrupt_model_used.rs @@ -0,0 +1,50 @@ +use alloc::vec; +use core::str::FromStr; + +use crate::{ + Handler, + aml::{ + AmlError, + Interpreter, + namespace::AmlName, + object::{Object, WrappedObject}, + }, +}; + +/// See . +#[non_exhaustive] +#[derive(Debug, Clone, Copy)] +pub enum InterruptModelUsed { + /// 0 - PIC mode + PicMode, + /// 1 - APIC mode + ApicMode, + /// 2 - SAPIC mode + SapicMode, +} + +impl From for Object { + fn from(value: InterruptModelUsed) -> Self { + Self::Integer(match value { + InterruptModelUsed::PicMode => 0, + InterruptModelUsed::ApicMode => 1, + InterruptModelUsed::SapicMode => 2, + }) + } +} + +impl Interpreter +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 { + Ok(self + .evaluate_if_present( + AmlName::from_str(r#"\_PIC"#).expect("valid name"), + vec![WrappedObject::new(model.into())], + )? + .is_some()) + } +} diff --git a/src/aml/mod.rs b/src/aml/mod.rs index 44ef3583..b3e5dcf3 100644 --- a/src/aml/mod.rs +++ b/src/aml/mod.rs @@ -16,6 +16,7 @@ * - Fuzzing and guarantee panic-free interpretation */ +mod interrupt_model_used; pub mod namespace; pub mod object; pub mod op_region; @@ -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::{ diff --git a/src/aml/pci_routing.rs b/src/aml/pci_routing.rs index 47df1b13..4cbb48aa 100644 --- a/src/aml/pci_routing.rs +++ b/src/aml/pci_routing.rs @@ -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,