[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