can someone explain...[ PCI interrupts]

John Baldwin jhb at
Wed Dec 7 06:02:04 PST 2005

On Wednesday 07 December 2005 01:16 am, M. Warner Losh wrote:
> In message: <43961758.4020407 at>
>             Julian Elischer <julian at> writes:
> : How much is set up by the BIOS and how much is set up by the OS (4.x and
> : -current).
> On 4.x, the BIOS (PCI BIOS) is called to route interrupts from the PIR
> table when such a table exists.  On current, ACPI routines are called
> (if acpi is enabled), with a fallback to the PIR.  Both use the
> MPTABLE when an APIC i in voled.

Actually, the MP Table is only used for !ACPI.  For ACPI + APIC, you enumerate 
APICs (both local and I/O) via the MADT, and for each I/O APIC, the MADT 
specifies the IRQ cookie value of the first intpin.  Then, you call the _PIC 
method to tell the BIOS you are using the APICs.  Then, all the _PRT methods 
check a saved copy of that argument to _PIC and return different arrays 
(packages in ACPI parlance) based on that, so that the _PRT's basically 
return two different things for the two different modes.  The MP Table isn't 
used at all.

> : In this world of multiple PCI to PCI bridges, how much latitude doe the
> : OS have in
> : deciding where an interrupt turns up?
> : (in 4.x and -current)
> Somehwere between none and a bunch.  It all has to do with what
> interrupt controllers are available and how the interrupt lines are
> wired.  Some systems force you to use the 'barberpole' for interrupts,
> while others wire them all to the same interrupts while others allow
> smome limited sleections.

Well, links have limited selection, everything else is hard-wired. :)

> : Who is making those decisions? Is it the BIOS and 4.x is just playing
> : along?
> Kinda, except when it isn't.  The BIOS usually assigns an interrupt,
> and we play along.  However, usually is a lot less often than it used
> to be so we're now more typically routing ourselves.

Well, we use the BIOS set IRQs for heuristics.  For example, $PIR has no way 
of telling you what IRQ given link is already routed to, so when we probe the 
$PIR, we do a bunch of PCI config accesses to the IRQ register to sniff out 
what it looks like the BIOS has done and then use those IRQs for link 
devices.  For ACPI we do the same thing as a fallback for when _CRS on a link 
device doesn't work.  This approach only works for links routed via ISA IRQs 
though.  For APIC routing (except for the early SMP boxes that still used 
only ISA IRQs), the BIOS IRQ values are worthless so we ignore them.

> : Linux and -current on teh same box a;;ocate way different irqs, and
> : they agree about it.. i.e. Linux and -current assign my 4 port card IRQs
> : 18,19,19,16.
> Resources are alloacted differently between the OS and the BIOS.
> Looks like Linux has a slightly different algorithm for assigning
> interrupts to free APIC pins.  Notice that in all cases the middle two
> are shared.  That detail is likely in the MPTables for the device in
> question.

Linux is doing what FreeBSD 5.2+ does. :)   Here what is happening is that we 
are doing the swizzle across the PCI-PCI bridge on the 4-port card and 
routing on the parent sideof the bridge via ACPI or MP Table.  It sounds like 
this 4-port card does something brain damaged such that the middle two 
devices swizzle to the same INTx on the parent side of the bridge.  (E.g., 
the devices are at "slots" 0, 1, 5, 6 on the card instead of the more typical 
0, 1, 2, 3.  It could also be that it is 0, 1, 2, 3, but device 2 is using 
INTD rather than INTA.)

John Baldwin <jhb at>  <><
"Power Users Use the Power to Serve"  =

More information about the freebsd-current mailing list