These two patches should make the mptable code easier to move out of SeaBIOS and into QEMU. The first patch stops the mptable from describing PCI-to-PCI bridges - I don't believe it was the goal (or a requirement) of the mptable to describe bridges. The second patch synchs the list of PCI irqs between the ACPI code and the mptable code. This has only been lightly tested.
Thoughts?
-Kevin
Kevin O'Connor (2): mptable: Don't describe pci-to-pci bridges. mptable: Use same PCI irqs as ACPI code.
src/acpi.c | 5 +---- src/config.h | 3 +++ src/mptable.c | 30 ++++++++++++++---------------- 3 files changed, 18 insertions(+), 20 deletions(-)
It should not be necessary to describe PCI-to-PCI bridges in the mptable. (The mptable was designed to fit in ROM, so it seems unlikely that it would be used for bridges that could be dynamically added.) Describing only the root bus should make it easier to port this content into QEMU.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/mptable.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/src/mptable.c b/src/mptable.c index 0f2d756..de188ca 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -65,30 +65,25 @@ mptable_setup(void) } int entrycount = cpu - cpus;
- // PCI buses + // PCI bus struct mpt_bus *buses = (void*)cpu, *bus = buses; - int lastbus = -1; - struct pci_device *pci; - foreachpci(pci) { - int curbus = pci_bdf_to_bus(pci->bdf); - if (curbus == lastbus) - continue; - lastbus = curbus; + if (PCIDevices) { memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; - bus->busid = curbus; + bus->busid = 0; memcpy(bus->bustype, "PCI ", sizeof(bus->bustype)); bus++; + entrycount++; }
/* isa bus */ - int isabusid; + int isabusid = bus - buses; memset(bus, 0, sizeof(*bus)); bus->type = MPT_TYPE_BUS; - isabusid = bus->busid = lastbus + 1; + bus->busid = isabusid; memcpy(bus->bustype, "ISA ", sizeof(bus->bustype)); bus++; - entrycount += bus - buses; + entrycount++;
/* ioapic */ u8 ioapic_id = BUILD_IOAPIC_ID; @@ -106,8 +101,11 @@ mptable_setup(void) int dev = -1; unsigned short mask = 0, pinmask = 0;
+ struct pci_device *pci; foreachpci(pci) { u16 bdf = pci->bdf; + if (pci_bdf_to_bus(bdf) != 0) + break; int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN); int irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE); if (pin == 0)
The ACPI code has a hardcoded list of PCI interrupts. Use that same list in the mptable code generation. This will ensure that both tables are in synch - it may also make the mptable easier to generate from QEMU.
Also, move the irq0_override lookup outside of the irq loop.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/acpi.c | 5 +---- src/config.h | 3 +++ src/mptable.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 119d1c1..d1cb653 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -131,9 +131,6 @@ struct madt_io_apic * lines start */ } PACKED;
-/* IRQs 5,9,10,11 */ -#define PCI_ISA_IRQ_MASK 0x0e20 - struct madt_intsrcovr { ACPI_SUB_HEADER_DEF u8 bus; @@ -372,7 +369,7 @@ build_madt(void) intsrcovr++; } for (i = 1; i < 16; i++) { - if (!(PCI_ISA_IRQ_MASK & (1 << i))) + if (!(BUILD_PCI_IRQS & (1 << i))) /* No need for a INT source override structure. */ continue; memset(intsrcovr, 0, sizeof(*intsrcovr)); diff --git a/src/config.h b/src/config.h index 8b888b9..64e3c92 100644 --- a/src/config.h +++ b/src/config.h @@ -53,6 +53,9 @@ #define BUILD_HPET_ADDRESS 0xfed00000 #define BUILD_APIC_ADDR 0xfee00000
+// PCI IRQS +#define BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11)) + // Important real-mode segments #define SEG_IVT 0x0000 #define SEG_BDA 0x0040 diff --git a/src/mptable.c b/src/mptable.c index de188ca..7d485eb 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -99,7 +99,7 @@ mptable_setup(void) /* irqs */ struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs; int dev = -1; - unsigned short mask = 0, pinmask = 0; + unsigned short pinmask = 0;
struct pci_device *pci; foreachpci(pci) { @@ -117,7 +117,6 @@ mptable_setup(void) if (pinmask & (1 << pin)) /* pin was seen already */ continue; pinmask |= (1 << pin); - mask |= (1 << irq); memset(intsrc, 0, sizeof(*intsrc)); intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = 0; /* INT */ @@ -129,9 +128,10 @@ mptable_setup(void) intsrc++; }
+ int irq0_override = romfile_loadint("etc/irq0-override", 0); for (i = 0; i < 16; i++) { memset(intsrc, 0, sizeof(*intsrc)); - if (mask & (1 << i)) + if (BUILD_PCI_IRQS & (1 << i)) continue; intsrc->type = MPT_TYPE_INTSRC; intsrc->irqtype = 0; /* INT */ @@ -140,7 +140,7 @@ mptable_setup(void) intsrc->srcbusirq = i; intsrc->dstapic = ioapic_id; intsrc->dstirq = i; - if (romfile_loadint("etc/irq0-override", 0)) { + if (irq0_override) { /* Destination 2 is covered by irq0->inti2 override (i == 0). Source IRQ 2 is unused */ if (i == 0)
Kevin O'Connor wrote:
Thoughts?
I wish this effort could go into coreboot instead, so that it could benefit more than only one machine.
//Peter
On Tue, Mar 19, 2013 at 02:09:05AM +0100, Peter Stuge wrote:
Kevin O'Connor wrote:
Thoughts?
I wish this effort could go into coreboot instead, so that it could benefit more than only one machine.
The code is QEMU specific. What other machines are you talking about?
-- Gleb.
On 03/19/13 02:09, Peter Stuge wrote:
Kevin O'Connor wrote:
Thoughts?
I wish this effort could go into coreboot instead, so that it could benefit more than only one machine.
The long-term plan is to generate the acpi tables in qemu, where qemu can adjust them to actually match the virtual hardware emulated. Then qemu will make them available via fw_cfg interface, where any firmware can pick them up (seabios, coreboot, ovmf, whatever).
Step one in this path (where we are at the moment) is to reduce dependencies between acpi tables and seabios internals.
cheers, Gerd
On Mon, Mar 18, 2013 at 08:38:59PM -0400, Kevin O'Connor wrote:
These two patches should make the mptable code easier to move out of SeaBIOS and into QEMU. The first patch stops the mptable from describing PCI-to-PCI bridges - I don't believe it was the goal (or a requirement) of the mptable to describe bridges. The second patch synchs the list of PCI irqs between the ACPI code and the mptable code. This has only been lightly tested.
Thoughts?
I wish I would remember why I added PCI bus enumeration code, but I think you are right. If there is more then one PCI domain then each one of them should be listed, but PCI-to-PCI bridges are part of the same bus.
-- Gleb.