PCI-PCI bridge interrupt routing

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yr
Member
Member
Posts: 31
Joined: Sat Mar 28, 2015 12:50 pm

PCI-PCI bridge interrupt routing

Post by yr »

I'm having some trouble figuring out interrupt pin routing for a device on a secondary PCI bus. Below is the PCI device enumeration obtained via the brute force method:

Code: Select all

[pci]  Address Vendor Device    Class Header IntLine IntPin Description
[pci] -----------------------------------------------------------------
[pci] 00:00.00   8086   7190 06:00:00     00       0      0 Host bridge
[pci] 00:01.00   8086   7191 06:04:00     01       0      0 PCI bridge - Normal decode
[pci] 00:07.00   8086   7110 06:01:00     80       0      0 ISA bridge
[pci] 00:07.01   8086   7111 01:01:8a     00     255      0 IDE interface - ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering
[pci] 00:07.03   8086   7113 06:80:00     80       0      0 Bridge
[pci] 00:07.07   15ad   0740 08:80:00     00     255      1 System peripheral
[pci] 00:0f.00   15ad   0405 03:00:00     00     255      1 VGA compatible controller - VGA controller
[pci] 00:11.00   15ad   0790 06:04:01     01     255      0 PCI bridge - Subtractive decode
[pci] 00:15.00   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.01   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.02   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.03   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.04   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.05   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.06   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:15.07   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.00   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.01   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.02   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.03   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.04   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.05   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.06   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:16.07   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.00   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.01   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.02   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.03   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.04   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.05   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.06   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:17.07   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.00   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.01   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.02   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.03   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.04   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.05   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.06   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 00:18.07   15ad   07a0 06:04:00     81     255      0 PCI bridge - Normal decode
[pci] 02:00.00   8086   100f 02:00:00     00     255      1 Ethernet controller
[pci] 02:01.00   1274   1371 04:01:00     00     255      1 Multimedia audio controller
[pci] 02:03.00   15ad   07e0 01:06:01     00     255      1 SATA controller - AHCI 1.0
I'm trying to figure out the global interrupt for the SATA controller. As you can see from the above table, it's on bus 2 and linked to pin 1 (INTA#). Looking at bus numbers on the PCI bridges, I get the following:

Code: Select all

PCI-PCI bridge (00:01.00): primary bus 0, secondary bus 1, subordinate bus 1
PCI-PCI bridge (00:11.00): primary bus 0, secondary bus 2, subordinate bus 2
PCI-PCI bridge (00:15.00): primary bus 0, secondary bus 3, subordinate bus 3
...
This indicates that bus 2 is behind device 00:11.00. However, as you can see from the PCI enumeration, there is no interrupt pin for that device. The IRQ routing table for bus 0 is as below. But I'm not sure how to determine the relevant entry without knowing the pin?

Code: Select all

[acpi]         IRQ Routing:
[acpi]             Device  Pin  Source     SourceIndex
[acpi]             -----------------------------------
[acpi]              0x0f     0  0                16
[acpi]              0x0f     1  0                17
[acpi]              0x0f     2  0                18
[acpi]              0x0f     3  0                19
[acpi]              0x10     0  0                17
[acpi]              0x10     1  0                18
[acpi]              0x10     2  0                19
[acpi]              0x10     3  0                16
[acpi]              0x11     0  0                18
[acpi]              0x11     1  0                19
[acpi]              0x11     2  0                16
[acpi]              0x11     3  0                17
[acpi]              0x12     0  0                19
[acpi]              0x12     1  0                16
[acpi]              0x12     2  0                17
[acpi]              0x12     3  0                18
[acpi]              0x13     0  0                16
[acpi]              0x13     1  0                17
[acpi]              0x13     2  0                18
[acpi]              0x13     3  0                19
[acpi]              0x14     0  0                17
[acpi]              0x14     1  0                18
[acpi]              0x14     2  0                19
[acpi]              0x14     3  0                16
[acpi]              0x15     0  0                18
[acpi]              0x15     1  0                19
[acpi]              0x15     2  0                16
[acpi]              0x15     3  0                17
[acpi]              0x16     0  0                19
[acpi]              0x16     1  0                16
[acpi]              0x16     2  0                17
[acpi]              0x16     3  0                18
[acpi]              0x17     0  0                16
[acpi]              0x17     1  0                17
[acpi]              0x17     2  0                18
[acpi]              0x17     3  0                19
[acpi]              0x18     0  0                17
[acpi]              0x18     1  0                18
[acpi]              0x18     2  0                19
[acpi]              0x18     3  0                16
[acpi]              0x19     0  0                18
[acpi]              0x19     1  0                19
[acpi]              0x19     2  0                16
[acpi]              0x19     3  0                17
[acpi]              0x1a     0  0                19
[acpi]              0x1a     1  0                16
[acpi]              0x1a     2  0                17
[acpi]              0x1a     3  0                18
[acpi]              0x1b     0  0                16
[acpi]              0x1b     1  0                17
[acpi]              0x1b     2  0                18
[acpi]              0x1b     3  0                19
[acpi]              0x1c     0  0                17
[acpi]              0x1c     1  0                18
[acpi]              0x1c     2  0                19
[acpi]              0x1c     3  0                16
[acpi]              0x1d     0  0                18
[acpi]              0x1d     1  0                19
[acpi]              0x1d     2  0                16
[acpi]              0x1d     3  0                17
[acpi]              0x1e     0  0                19
[acpi]              0x1e     1  0                16
[acpi]              0x1e     2  0                17
[acpi]              0x1e     3  0                18
[acpi]              0x1f     0  0                16
[acpi]              0x1f     1  0                17
[acpi]              0x1f     2  0                18
[acpi]              0x1f     3  0                19
[acpi]              0x07     0  0                16
[acpi]              0x07     1  0                17
[acpi]              0x07     2  0                18
[acpi]              0x07     3  0                19
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: PCI-PCI bridge interrupt routing

Post by Korona »

You need to query the _PRT of the bridge, not the _PRT of the root bridge. Only if such a _PRT does not exist (e.g., because the bridge is on an expansion card), you want to fallback to the default routing given in the PCI bridge specification.

EDIT: to find the _PRT of the bridge, you need to recursively find the bridge via its _ADR inside the parent bus.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
yr
Member
Member
Posts: 31
Joined: Sat Mar 28, 2015 12:50 pm

Re: PCI-PCI bridge interrupt routing

Post by yr »

Doesn't look like there's a _PRT for the bridge. Here's the list of relevant ACPI objects:

Code: Select all

...
[acpi]     \_SB.PCI0.P2P0
[acpi]     \_SB.PCI0.P2P0._ADR
[acpi]     \_SB.PCI0.P2P0._HPP
[acpi]     \_SB.PCI0.P2P0._PRW
[acpi]     \_SB.PCI0.P2P0.BSTA
[acpi]     \_SB.PCI0.P2P0.BEJ0
[acpi]     \_SB.PCI0.P2P0.BDSM
[acpi]     \_SB.PCI0.P2P0.REGS
[acpi]     \_SB.PCI0.P2P0.ID
[acpi]     \_SB.PCI0.P2P0._STA
[acpi]     \_SB.PCI0.P2P0.OSHP
[acpi]     \_SB.PCI0.P2P0.PPHR
[acpi]     \_SB.PCI0.P2P0.S1F0
[acpi]     \_SB.PCI0.P2P0.S1F0._ADR
[acpi]     \_SB.PCI0.P2P0.S1F0._SUN
[acpi]     \_SB.PCI0.P2P0.S1F0.REGS
[acpi]     \_SB.PCI0.P2P0.S1F0.ID
[acpi]     \_SB.PCI0.P2P0.S1F0._STA
[acpi]     \_SB.PCI0.P2P0.S1F0._EJ0
[acpi]     \_SB.PCI0.P2P0.S1F0._DSM
[acpi]     \_SB.PCI0.P2P0.S1F0._PRW
[acpi]     \_SB.PCI0.P2P0.S2F0
[acpi]     \_SB.PCI0.P2P0.S2F0._ADR
[acpi]     \_SB.PCI0.P2P0.S2F0._SUN
[acpi]     \_SB.PCI0.P2P0.S2F0.REGS
[acpi]     \_SB.PCI0.P2P0.S2F0.ID
[acpi]     \_SB.PCI0.P2P0.S2F0._STA
[acpi]     \_SB.PCI0.P2P0.S2F0._EJ0
[acpi]     \_SB.PCI0.P2P0.S2F0._DSM
[acpi]     \_SB.PCI0.P2P0.S2F0._PRW
[acpi]     \_SB.PCI0.P2P0.S3F0
[acpi]     \_SB.PCI0.P2P0.S3F0._ADR
[acpi]     \_SB.PCI0.P2P0.S3F0._SUN
[acpi]     \_SB.PCI0.P2P0.S3F0.REGS
[acpi]     \_SB.PCI0.P2P0.S3F0.ID
[acpi]     \_SB.PCI0.P2P0.S3F0._STA
[acpi]     \_SB.PCI0.P2P0.S3F0._EJ0
[acpi]     \_SB.PCI0.P2P0.S3F0._DSM
[acpi]     \_SB.PCI0.P2P0.S3F0._PRW
...
So presumably I have to assume default routing? The PCI bridge specification says:
A bridge is not required to route interrupts that originate on the PCI bus connected to the secondary interface of the bridge through the bridge.
...
Device 0 on a secondary bus will have its INTA# line connected to the INTA# line of the connector. Device 1 will have its INTA# line connected to INTB# of the connector. This sequence continues and then wraps around once INTD# has been assigned.
...
Note that Table 9-1 does not specify the routing of a bridge’s interrupt pin (if implemented) to the interrupt pins of the add-in connector. Assuming that the bridge is a single function device, its interrupt pin is required to be connected to INTA# by the PCI Local Bus Specification.
I'm not sure how to interpret this. In my case, the config for the bridge device (00:11.00) doesn't have a valid interrupt pin (0). Does that matter? Or is the only relevant bit here the routing of the device pins on the secondary bus? Since the SATA controller (02:03.00) is the fourth device on the secondary bus, is its INTA# line connected to INTD# on 00:11.00, implying routing to GSI 17?
Post Reply