LinuxBIOS and Vxworks
Kevin Hester
kevinh at ispiri.com
Tue Dec 10 21:25:01 CET 2002
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 at 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
More information about the coreboot
mailing list