[SeaBIOS] [PATCH] Don't overallocate mptable
Gleb Natapov
gleb at redhat.com
Sun Dec 27 12:43:14 CET 2009
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:
> 1. The bus does not share its memory address space with another bus.
> 2. The bus does not share its I/O address space with another bus.
> 3. The bus does not share interrupt lines with another bus.
> 4. 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.
More information about the SeaBIOS
mailing list