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