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 1/2] 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, From 68d2b74252839f53caf5d8f205240492eb0e1372 Mon Sep 17 00:00:00 2001 From: Rajas Paranjpe <52586855+ChocolateLoverRaj@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:38:29 -0700 Subject: [PATCH 2/2] use interrupt model from ACPI 6.6 spec and impl for BaseInterpreter --- src/aml/interrupt_model_used.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/aml/interrupt_model_used.rs b/src/aml/interrupt_model_used.rs index f6f3f40a..cf25062b 100644 --- a/src/aml/interrupt_model_used.rs +++ b/src/aml/interrupt_model_used.rs @@ -5,13 +5,14 @@ use crate::{ Handler, aml::{ AmlError, - Interpreter, + BaseInterpreter, namespace::AmlName, object::{Object, WrappedObject}, + op_region::RegionHandler, }, }; -/// See . +/// 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 { @@ -21,6 +22,12 @@ pub enum InterruptModelUsed { ApicMode, /// 2 - SAPIC mode SapicMode, + /// 4 – GIC model + GicModel = 4, + /// 5 – LPIC model + LpicModel = 5, + /// 6 – RINTC model + RintcModel = 6, } impl From for Object { @@ -29,15 +36,19 @@ impl From for Object { InterruptModelUsed::PicMode => 0, InterruptModelUsed::ApicMode => 1, InterruptModelUsed::SapicMode => 2, + InterruptModelUsed::GicModel => 4, + InterruptModelUsed::LpicModel => 5, + InterruptModelUsed::RintcModel => 6, }) } } -impl Interpreter +impl BaseInterpreter where H: Handler, + R: RegionHandler + ?Sized, { - /// 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). + /// 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 { Ok(self