Alas, it doesn't read the pirq table. That would be damn smart and such a feature could be built with a function that uses pci_assign_irqs and the pirq table.
The reason I decided to not use the PIRQ table was it seemed like some important information may be missing. For instance, this is the pirq table I created for the Epia:
const struct irq_routing_table intel_irq_routing_table = { PIRQ_SIGNATURE, /* u32 signature */ PIRQ_VERSION, /* u16 version */ 32+16*5, /* there can be total 5 devices on the bus */ 0, /* Where the interrupt router lies (bus) */ 0x88, /* Where the interrupt router lies (dev) */ 0x1c20, /* IRQs devoted exclusively to PCI usage */ 0x1106, /* Vendor Via */ 0x8231, /* Device 8231 southbridge */ 0, /* Crap (miniport) */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ 0x5e, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ { /* PCI slot */ {0,0xa0, {{0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}}, 0x1, 0},
/* Unused */ {0,0x98, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0x2, 0},
/* Unknown */ {0,0x50, {{0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}, {0x2, 0xdeb8}}, 0x3, 0},
/* Southbridge internal */ {0,0x88, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0x4, 0},
/* 8231 Ethernet */ {0,0x90, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0, 0}, } };
Most of these values were captured from the standard Award bios that came with the board - the remaining fields were fixed/added by me. The troubling thing is the IRQ bitmaps that were passed in for each of the slots, notice that all of the IRQ bitmaps are 0xdeb8. The standard BIOS is apparently using this to indicate that a large number of options are available for assigning IRQs to each of these slots.
The thing that seems to be missing in the PIRQ table is information about how these various IRQs are connected on the backplane and within the southbridge. i.e. within the via vt8601 southbridge there is only four PINTA-D mappings to IRQs . Each one of these PINTx signals can be mapped to any IRQ, but by definition all of the signals on PINTx are sharing the same IRQ. The OS that is using the pirq table is not free to manipulate these independently.
It seems like this sharing of IRQs can be described by the link value fields in the pirq table. For instance, the 8231 Ethernet in the table above shows a 0x1 for its PINTA link value. The fact that the southbridge internal entry also shows 0x1 for PINTA link value means that both of those PINTAs must be bound to the same IRQ.
So, where does this leave us?
We could make a function that uses the pirq table and pci_assign_irqs, but it would require us assigning a particular meaning to the link value fields in the pirq table. If we can use the link value fields as we wish, then we can use the PIRQ pci_exclusive_irq bitmask followed by the remaining slot specific irq bitmaps.
Unfortunately, reading my "pci system architecture" book says that these link value fields must be interpreted as specified by the manufacturer of the interrupt router (the southbridge?).
How do you think we should handle this? I looked at a few PCs/chipsets around the office, and they all seem to use similar mappings of this link value field.
I was reluctant to get into the realm of mapping arbitrary pirq tables to IRQs and I was lazy, so I only added pci_assign_irqs. For a particular mainboard it is pretty painless to use, for instance the Epia uses:
// Our default IRQ bindings for each of the four devices static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 }; static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 }; static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
/* Our IDSEL mappings are as follows
PCI slot is AD31 (device 15) (00:14.0) Southbridge is AD28 (device 12) (00:11.0) */ static void pci_routing_fixup(void) { struct pci_dev *dev;
dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0); if (dev != NULL) { /* initialize PCI interupts - these assignments depend on the PCB routing of PINTA-D
PINTA = IRQ11 PINTB = IRQ5 PINTC = IRQ10 PINTD = IRQ12 */ pci_write_config_byte(dev, 0x55, 0xb0); pci_write_config_byte(dev, 0x56, 0xa5); pci_write_config_byte(dev, 0x57, 0xc0); }
// Standard southbridge components pci_assign_irqs(0, 0x11, southbridgeIrqs);
// Ethernet built into southbridge pci_assign_irqs(0, 0x12, enetIrqs); pci_assign_irqs(0, 0x14, slotIrqs); }
If folks think we can trust the link value fields to show interrupt sharing, then all is well. I'm happy to make a new function that given an arbitrary pirq table will make default IRQ assignments.
Kevin
On Tuesday 10 December 2002 17:36, Eric W. Biederman wrote:
Kevin Hester kevinh@ispiri.com writes:
Hi,
It has been a couple of years since I was futzing with the ugly beast that is vxWorks ;-). However, I don't think the Intel BSPs are 'plug-and-play'. I.e. vxWorks counts on the BIOS setting up the IRQ bindings for all PCI devices.
It seems to me that most of the current linuxbios ROMs don't setup the PCI IRQs - they rely on the fact that linux is able to use the pirq table and do it's own PCI IRQ assignment. If you are using vxWorks you may need to make sure your mainboard.c is assigning IRQs to all PCI devices.
I just sent Andrew a patch which does this for the Via Epia motherboard. After this is checked in you should search the source for pci_assign_irqs for example usage.
Does this use the pirq tables or does it do something else? As much as possible I would like to have a single source table so we don't run into strange maintenance issues.
Assigning initial irqs, and reporting them in pci space is something very much in the scope of LinuxBIOS. It just hasn't come up much before now so the code is not there yet...
Eric