Subject: Re: Enumerating PCI busses and pci_machdep code.
To: Peter Seebach <seebs@plethora.net>
From: Nathan J. Williams <nathanw@wasabisystems.com>
List: tech-ports
Date: 03/04/2006 00:35:19
seebs@plethora.net (Peter Seebach) writes:

> So... In pci_conf_interrupt, the swiz argument tells me how much swizzling
> to do, but how do I find out which of the vendor-provided interrupt tables
> I should be looking at?  Maybe I'm not following this.  The Linux code has
> a giant table, which is looked up by {idsel, pin}.  So, for instance, the
> table for idsel 17 (aka device 17) is
> 	{IRQA, IRQD, IRQC, IRQB},       /* IDSEL 17 - PCI slot 2 */
> (A-D == 26-29.)
> 
> What this seems to mean is that, if device 17 is a pci bus (PCI1), then I
> should probably be looking somewhere into this array for interrupts for
> any devices on this bus.  But... When I'm called with (bus 1, dev 4, pin 1),
> I don't know how to figure out that that's swizzled from (bus 0, dev 17)
> instead of from, say, (bus 0, dev 18).

You don't, and this is a weakness of the code... but in the typical
way of setting up PCI interrupts on multiple plug-in slots, you don't
need to. The reason is that the typical arrangement is for each slot
to have the same four interrupt lines, but rotated, so you have a
mapping from <device ID, interrupt pin> to <interrupt line> that looks
like this:

              A   B   C   D
 idsel 17    26  27  28  29
 idsel 18    27  28  29  26
 idsel 19    28  29  26  27
...

So the mapping for "bus != 0" is just 26 + (((dev - 17) + swiz + pin) % 4).
(Check my math. It's late at night...)

You can throw in another layer of indirection if the actual interrupt
line numbers aren't contiguous like that, as long as they rotate in
that pattern. If they don't... well, then you get to be a pioneer of
rearranging this interface so that it communicates both the net
swizzle and the relevant device number on the root bus (or whatever
bus has actual interrupt lines; you could have an arrangement on a
board with a primary bus and a pci-pci bridge to a secondary bus, but
with interrupt lines run directly from the CPU to both buses;
electrical load limits on the PCI bus make this a moderately sensible
arrangement).

> This is a sort of weird case, because it's an embedded board with pre-set
> interrupts, but it has PCI slots that can take expansion devices with
> bridges.

No, that's pretty normal, really.

        - Nathan