On Thu, Dec 24, 2009 at 02:41:48PM -0500, Kevin O'Connor wrote:
On Thu, Dec 24, 2009 at 08:16:19PM +0200, Gleb Natapov wrote:
Ah so pci_bdf_to_bus(bdf) > 0 for the bus behind PCI-to-PCI bridge?
Yes - if it is configured properly (which pciinit.c doesn't).
I don't wee why you read spec this way. Can you point me to the part of the spec that makes you think so?
The purpose of the table is to relay to the OS info the OS can't find on its own - a pci-to-pci bridge on an add-on card is fully auto-detectable. The mpspec doesn't seem to require bridges of add-on cards be listed - from the spec:
Each bus in a system must have a unique BUS ID if any one of the following criteria are true:
- The bus does not share its memory address space with another bus.
- The bus does not share its I/O address space with another bus.
- The bus does not share interrupt lines with another bus.
- Any aspect of the bus as an independent entity is software visible (such as PCI configuration space).
The first three clearly don't apply. The fourth seems ambiguous to me.
To me it looks like the fourth was included specifically to cover PCI buses.
That said, I don't see any reason why they couldn't be listed. However, the code right now would produce incorrect results for bus > 0.
Unfortunately yes. We need to have one more loop to find all PCI buses and create bus entry for each. May be something like patch below?
diff --git a/src/mptable.c b/src/mptable.c index 2409fcf..54fef36 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -23,7 +23,7 @@ mptable_init(void) // Allocate memory int length = (sizeof(struct mptable_config_s) + sizeof(struct mpt_cpu) * MaxCountCPUs - + sizeof(struct mpt_bus) * 2 + + sizeof(struct mpt_bus) * 5 + sizeof(struct mpt_ioapic) + sizeof(struct mpt_intsrc) * 34); struct mptable_config_s *config = malloc_fseg(length); @@ -83,19 +83,28 @@ mptable_init(void) } int entrycount = cpu - cpus;
- /* isa bus */ struct mpt_bus *bus = (void*)cpu; - memset(bus, 0, sizeof(*bus)); - bus->type = MPT_TYPE_BUS; - bus->busid = 1; - memcpy(bus->bustype, "ISA ", sizeof(bus->bustype)); - entrycount++; + unsigned long busmask = 0; + int bdf, max; + foreachpci(bdf, max) { + int curbus = pci_bdf_to_bus(bdf); + if (busmask & (1 << curbus)) + continue; + busmask |= (1 << curbus); + memset(bus, 0, sizeof(*bus)); + bus->type = MPT_TYPE_BUS; + bus->busid = curbus; + memcpy(bus->bustype, "PCI ", sizeof(bus->bustype)); + bus++; + entrycount++; + }
- bus++; + /* isa bus */ + int isabusid; memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; - bus->busid = 0; - memcpy(bus->bustype, "PCI ", sizeof(bus->bustype)); + isabusid = bus->busid = __fls(busmask) + 1; + memcpy(bus->bustype, "ISA ", sizeof(bus->bustype)); entrycount++;
/* ioapic */ @@ -111,7 +120,7 @@ mptable_init(void)
/* irqs */ struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs; - int bdf, max, dev = -1; + int dev = -1; unsigned short mask = 0, pinmask;
foreachpci(bdf, max) { @@ -131,7 +140,7 @@ mptable_init(void) intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = 0; /* INT */ intsrc->irqflag = 1; /* active high */ - intsrc->srcbus = 0; /* PCI bus */ + intsrc->srcbus = pci_bdf_to_bus(bdf); /* PCI bus */ intsrc->srcbusirq = (dev << 2) | (pin - 1); intsrc->dstapic = ioapic_id; intsrc->dstirq = irq; @@ -145,7 +154,7 @@ mptable_init(void) intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = 0; /* INT */ intsrc->irqflag = 0; /* conform to bus spec */ - intsrc->srcbus = 1; /* ISA bus */ + intsrc->srcbus = isabusid; /* ISA bus */ intsrc->srcbusirq = i; intsrc->dstapic = ioapic_id; intsrc->dstirq = i; @@ -165,7 +174,7 @@ mptable_init(void) intsrc->type = MPT_TYPE_LOCAL_INT; intsrc->irqtype = 3; /* ExtINT */ intsrc->irqflag = 0; /* PO, EL default */ - intsrc->srcbus = 1; /* ISA */ + intsrc->srcbus = isabusid; /* ISA */ intsrc->srcbusirq = 0; intsrc->dstapic = 0; /* BSP == APIC #0 */ intsrc->dstirq = 0; /* LINTIN0 */ @@ -175,7 +184,7 @@ mptable_init(void) intsrc->type = MPT_TYPE_LOCAL_INT; intsrc->irqtype = 1; /* NMI */ intsrc->irqflag = 0; /* PO, EL default */ - intsrc->srcbus = 1; /* ISA */ + intsrc->srcbus = isabusid; /* ISA */ intsrc->srcbusirq = 0; intsrc->dstapic = 0; /* BSP == APIC #0 */ intsrc->dstirq = 1; /* LINTIN1 */ -- Gleb.