can someone explain...[ PCI interrupts]
jhb at freebsd.org
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 elischer.org>
> Julian Elischer <julian at elischer.org> 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
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 FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-current