From bf4ef0ca83cf333e308cdeed2929ad659d62d40e Mon Sep 17 00:00:00 2001 From: Rajas Paranjpe <52586855+ChocolateLoverRaj@users.noreply.github.com> Date: Sat, 19 Sep 2026 11:51:16 -0700 Subject: [PATCH 1/2] Create `pci_routing::Pin::from_pci_interrupt_pin` convenience fn. Tested on QEMU q35. --- src/aml/pci_routing.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/aml/pci_routing.rs b/src/aml/pci_routing.rs index 47df1b13..7259a8ee 100644 --- a/src/aml/pci_routing.rs +++ b/src/aml/pci_routing.rs @@ -21,6 +21,24 @@ pub enum Pin { IntD, } +#[derive(Debug, Clone, Copy)] +pub struct InvalidPciInterruptPinError(pub u8); + +impl Pin { + /// If the PCI interrupt pin is `0`, that means that the PCI device doesn't use an interrupt pin, + /// and `Ok(None)` will be returned. + pub fn from_pci_interrupt_pin(pin: u8) -> Result, InvalidPciInterruptPinError> { + match pin { + 0 => Ok(None), + 1 => Ok(Some(Self::IntA)), + 2 => Ok(Some(Self::IntB)), + 3 => Ok(Some(Self::IntC)), + 4 => Ok(Some(Self::IntD)), + pin => Err(InvalidPciInterruptPinError(pin)), + } + } +} + #[derive(Debug)] pub enum PciRouteType { /// The interrupt is hard-coded to a specific GSI From 0c19597f8fc53f997abb59ca8c29afad3141b9fc Mon Sep 17 00:00:00 2001 From: Rajas Paranjpe <52586855+ChocolateLoverRaj@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:53:39 -0700 Subject: [PATCH 2/2] Add Pin::from_prt_package_pin and improve docs --- src/aml/pci_routing.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/aml/pci_routing.rs b/src/aml/pci_routing.rs index 7259a8ee..3d81e00e 100644 --- a/src/aml/pci_routing.rs +++ b/src/aml/pci_routing.rs @@ -24,9 +24,12 @@ pub enum Pin { #[derive(Debug, Clone, Copy)] pub struct InvalidPciInterruptPinError(pub u8); +#[derive(Debug, Clone, Copy)] +pub struct InvalidPrtPackagePin(pub u8); + impl Pin { - /// If the PCI interrupt pin is `0`, that means that the PCI device doesn't use an interrupt pin, - /// and `Ok(None)` will be returned. + /// The [pin byte in the PCI configuration space](https://wiki.osdev.org/PCI#Header_Type_0x0) represents INTA-INTD as 1-4. + /// 0 means that the PCI device doesn't use an interrupt pin, in which case `Ok(None)` will be returned. pub fn from_pci_interrupt_pin(pin: u8) -> Result, InvalidPciInterruptPinError> { match pin { 0 => Ok(None), @@ -37,6 +40,18 @@ impl Pin { pin => Err(InvalidPciInterruptPinError(pin)), } } + + /// The [ACPI PCI Routing Table](https://uefi.org/specs/ACPI/6.6/06_Device_Configuration.html#prt-pci-routing-table) + /// represents INTA-INTD as 0-3. + pub fn from_prt_package_pin(pin: u8) -> Result { + match pin { + 0 => Ok(Self::IntA), + 1 => Ok(Self::IntB), + 2 => Ok(Self::IntC), + 3 => Ok(Self::IntD), + pin => Err(InvalidPrtPackagePin(pin)), + } + } } #[derive(Debug)] @@ -115,13 +130,11 @@ impl PciRoutingTable { }; let device = address.get_bits(16..32).try_into().map_err(|_| AmlError::PrtInvalidAddress)?; let function = address.get_bits(0..16).try_into().map_err(|_| AmlError::PrtInvalidAddress)?; - let pin = match *pin_package[1] { - Object::Integer(0) => Pin::IntA, - Object::Integer(1) => Pin::IntB, - Object::Integer(2) => Pin::IntC, - Object::Integer(3) => Pin::IntD, + let pin_byte = match *pin_package[1] { + Object::Integer(byte) => byte as u8, _ => return Err(AmlError::PrtInvalidPin), }; + let pin = Pin::from_prt_package_pin(pin_byte).map_err(|_| AmlError::PrtInvalidPin)?; /* * A `NamePath` source is a reference to a name that we haven't resolved yet. We