Skip to content

Instantly share code, notes, and snippets.

@mcastelino
Last active June 1, 2022 22:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mcastelino/4acda7c2407f1c51e68f3f994d8ffc98 to your computer and use it in GitHub Desktop.
Save mcastelino/4acda7c2407f1c51e68f3f994d8ffc98 to your computer and use it in GitHub Desktop.
PCI Interrupt Routing

Debug outputs on a NUC

APCI PRT Table Dump

[    0.076942] ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 10 *11 12 14 15)
[    0.077030] ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 6 10 11 12 14 15) *0, disabled.
[    0.077111] ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 6 *10 11 12 14 15)
[    0.077191] ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 *10 11 12 14 15)
[    0.077270] ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 *5 6 10 11 12 14 15)
[    0.077352] ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 6 10 11 12 14 15) *0, disabled.
[    0.077432] ACPI: PCI Interrupt Link [LNKG] (IRQs *3 4 5 6 10 11 12 14 15)
[    0.077511] ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 6 10 *11 12 14 15)
  • This is how the PIRQ[D:A] and PIRQ[H:E] are mapped by firmware (I assume this is PIC mode).
PCI Interrupt Requests: In non-APIC mode the PIRQx# signals can
be routed to interrupts 3, 4, 5, 6, 7, 9, 10, 11, 12, 14 or 15 as
described in Section 5.8.6. Each PIRQx# line has a separate Route
Control register.

In APIC mode, these signals are connected to the internal I/O APIC in
the following fashion: PIRQA# is connected to IRQ16, PIRQB# to
IRQ17, PIRQC# to IRQ18, and PIRQD# to IRQ19. This frees the
legacy interrupts

Dumping the actual PIN mapping once the OS has booted up

lspci -b -vvv | grep "Interrupt: pin"
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin A routed to IRQ 5
        Interrupt: pin A routed to IRQ 3
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin B routed to IRQ 10
        Interrupt: pin C routed to IRQ 10

Note: From the PRT

       LNKA - 11
       LNKD - 10
       LNKE - 5
       LNKG - 3

Actual interrupts used

lspci -vvv | grep "Interrupt: pin"
        Interrupt: pin A routed to IRQ 43
        Interrupt: pin A routed to IRQ 48
        Interrupt: pin A routed to IRQ 44
        Interrupt: pin A routed to IRQ 47
        Interrupt: pin A routed to IRQ 46
        Interrupt: pin A routed to IRQ 45
        Interrupt: pin A routed to IRQ 23
        Interrupt: pin B routed to IRQ 42
        Interrupt: pin C routed to IRQ 18

This matches: PIRQC# to IRQ18 which is the mapping for pin C in APIC mode

Factoring in MSI

cat /proc/interrupts
    This shows all MSI capable devices have been mapped away.
    The only one still on pin based interrupts is IRQ18.
           CPU0       CPU1       CPU2       CPU3
  0:        120          0          0          0  IR-IO-APIC   2-edge      timer
  4:          0          9          0          0  IR-IO-APIC   4-edge      ttyS0
  8:          0          0          0          1  IR-IO-APIC   8-edge      rtc0
  9:          0        164          0          0  IR-IO-APIC   9-fasteoi   acpi
 18:          0          0          0          0  IR-IO-APIC  18-fasteoi   i801_smbus
 23:          0         33          0          0  IR-IO-APIC  23-fasteoi   ehci_hcd:usb1
 40:          0          0          0          0  DMAR-MSI   0-edge      dmar0
 41:          0          0          0          0  DMAR-MSI   1-edge      dmar1
 42:          0          0       5880          0  IR-PCI-MSI 512000-edge      ahci[0000:00:1f.2]
 43:          0          0          0       1305  IR-PCI-MSI 32768-edge      i915
 44:          0          0          0          0  IR-PCI-MSI 327680-edge      xhci_hcd
 45:          0          0        389          0  IR-PCI-MSI 442368-edge      snd_hda_intel:card1
 46:          0          0          0       8498  IR-PCI-MSI 409600-edge      eno1
 47:         13          0          0          0  IR-PCI-MSI 360448-edge      mei_me
 48:          0          0         90          0  IR-PCI-MSI 49152-edge      snd_hda_intel:card0

And 18 is not remapped as the device is not MSI capable

00:1f.3 SMBus: Intel Corporation 8 Series SMBus Controller (rev 04)
        Subsystem: Intel Corporation Device 2054
        Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin C routed to IRQ 18
        Region 0: Memory at f7c39000 (64-bit, non-prefetchable) [size=256]
        Region 4: I/O ports at f040 [size=32]
        Kernel driver in use: i801_smbus
        Kernel modules: i2c_i801

Debug outputs on Virtual Q35 (QEMU)

PRT Table

[    0.060061] ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
[    0.060118] ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
[    0.060172] ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
[    0.060225] ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
[    0.060279] ACPI: PCI Interrupt Link [LNKE] (IRQs 5 *10 11)
[    0.060333] ACPI: PCI Interrupt Link [LNKF] (IRQs 5 *10 11)
[    0.060386] ACPI: PCI Interrupt Link [LNKG] (IRQs 5 10 *11)
[    0.060439] ACPI: PCI Interrupt Link [LNKH] (IRQs 5 10 *11)
[    0.060462] ACPI: PCI Interrupt Link [GSIA] (IRQs *16)
[    0.060468] ACPI: PCI Interrupt Link [GSIB] (IRQs *17)
[    0.060473] ACPI: PCI Interrupt Link [GSIC] (IRQs *18)
[    0.060479] ACPI: PCI Interrupt Link [GSID] (IRQs *19)
[    0.060485] ACPI: PCI Interrupt Link [GSIE] (IRQs *20)
[    0.060490] ACPI: PCI Interrupt Link [GSIF] (IRQs *21)
[    0.060496] ACPI: PCI Interrupt Link [GSIG] (IRQs *22)
[    0.060502] ACPI: PCI Interrupt Link [GSIH] (IRQs *23)

lspci -b -vvv | grep IRQ

        Interrupt: pin ? routed to IRQ 255
        Interrupt: pin A routed to IRQ 10
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin A routed to IRQ 11
        Interrupt: pin ? routed to IRQ 255
        Interrupt: pin A routed to IRQ 10
        Interrupt: pin A routed to IRQ 10

Note: The 255s are the PCIe Host Bridge and the ISA Bridge

lspci -vvv | grep IRQ

        Interrupt: pin A routed to IRQ 21
        Interrupt: pin A routed to IRQ 22
        Interrupt: pin A routed to IRQ 23
        Interrupt: pin A routed to IRQ 26
        Interrupt: pin A routed to IRQ 10

Note: The non MSI device is at IRQ 10

00:1f.3 SMBus: Intel Corporation 82801I (ICH9 Family) SMBus Controller (rev 02)
       Subsystem: Red Hat, Inc. QEMU Virtual Machine
       Flags: bus master, fast devsel, latency 0, IRQ 10
       I/O ports at 6000 [size=64]

cat /proc/interrupts

 24:          0          0          0          0   PCI-MSI 49152-edge      virtio2-config
 25:       1639          0          0          0   PCI-MSI 49153-edge      virtio2-req.0
 26:          0          0          0          7   PCI-MSI 512000-edge      ahci[0000:00:1f.2]
 27:          0          0          0          0   PCI-MSI 16384-edge      virtio0-config
 28:          0         77          0          0   PCI-MSI 16385-edge      virtio0-input.0
 29:          0          0          1          0   PCI-MSI 16386-edge      virtio0-output.0

Actual APCI Table Info

Keep in mind all the devices were on PINA (ignoring the swizzling)

PRTA : APIC Mode PRTP : PIC Mode

    Scope (_SB)
    {
        Scope (PCI0)
        {
            Name (PRTP, Package (0x80)
            {
                Package (0x04)
                {
                    0xFFFF,
                    Zero,
                    LNKE,
                    Zero
                },

                Package (0x04)
                {
                    0xFFFF,
                    One,
                    LNKF,
                    Zero
                },
                Package (0x04)
                {
                    0xFFFF,
                    0x02,
                    LNKG,
                    Zero
                },
                Package (0x04)
                {
                    0xFFFF,
                    0x03,
                    LNKH,
                    Zero
                },
                ...
                                Package (0x04)
                {
                    0xFFFF,
                    0x03,
                    LNKH,
                    Zero
                },

                Package (0x04)
                {
                    0x0001FFFF,
                    Zero,
                    LNKF,
                    Zero
                },

                Package (0x04)
                {
                    0x0001FFFF,
                    One,
                    LNKG,
                    Zero
                },

                ...
                
                
        Name (PRTA, Package (0x80)
        {
            Package (0x04)
            {
                0xFFFF,
                Zero,
                GSIE,
                Zero
            },

            Package (0x04)
            {
                0xFFFF,
                One,
                GSIF,
                Zero
            },
            Package (0x04)
            {
                0xFFFF,
                0x02,
                GSIG,
                Zero
            },

            Package (0x04)
            {
                0xFFFF,
                0x03,
                GSIH,
                Zero
            },


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment