[SeaBIOS] [PATCH v2 2/9] seabios: acpi: add mcfg table.

Jason Baron jbaron at redhat.com
Tue Oct 9 05:35:11 CEST 2012


From: Isaku Yamahata <yamahata at valinux.co.jp>

add mcfg table.
mcfg isn't populated at the moment. dev-q35 will use it later.

[jbaron at redhat.com: moved header from post.h -> acpi.h]
Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
Signed-off-by: Jason Baron <jbaron at redhat.com>
---
 src/acpi.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/acpi.h |   17 ++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/src/acpi.c b/src/acpi.c
index 6d239fa..780c0ac 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -13,6 +13,7 @@
 #include "pci_regs.h" // PCI_INTERRUPT_LINE
 #include "ioport.h" // inl
 #include "paravirt.h" // qemu_cfg_irq0_override
+#include "memmap.h"
 
 /****************************************************/
 /* ACPI tables init */
@@ -734,6 +735,77 @@ build_srat(void)
     return srat;
 }
 
+struct acpi_mcfg
+{
+    u32 nr;
+    struct acpi_table_mcfg *mcfg;
+    struct e820entry *e820;
+};
+
+static const struct pci_device_id mcfg_find_tbl[] = {
+    PCI_DEVICE_END,
+};
+
+static const struct pci_device_id mcfg_init_tbl[] = {
+    PCI_DEVICE_END,
+};
+
+static void *
+build_mcfg(void)
+{
+    struct pci_device *dev;
+    int bdf;
+
+    struct acpi_mcfg acpi_mcfg = {
+        .nr = 0,
+        .mcfg = NULL,
+        .e820 = NULL,
+    };
+    dev = pci_find_init_device(mcfg_find_tbl, &acpi_mcfg);
+    bdf = dev->bdf;
+    if (bdf < 0) {
+        return NULL;
+    }
+    if (acpi_mcfg.nr == 0) {
+        return NULL;
+    }
+
+    struct acpi_table_mcfg *mcfg;
+    int len = sizeof(*mcfg) + acpi_mcfg.nr * sizeof(mcfg->allocation[0]);
+    mcfg = malloc_high(len);
+    if (!mcfg) {
+        dprintf(1, "Not enough memory for mcfg table!\n");
+        return NULL;
+    }
+    memset(mcfg, 0, len);
+    acpi_mcfg.mcfg = mcfg;
+
+
+    struct e820entry *e820;
+    int e820_len = acpi_mcfg.nr * sizeof(*e820);
+    e820 = malloc_tmphigh(e820_len);
+    if (!e820) {
+        dprintf(1, "Not enough memory for e820 table!\n");
+        free(mcfg);
+        return NULL;
+    }
+    memset(e820, 0, e820_len);
+    acpi_mcfg.e820 = e820;
+
+    pci_init_device(mcfg_init_tbl, dev, &acpi_mcfg);
+
+    /* Linux checks if e820 covers mcfg area as reserved.
+     * If no, Linux thinks bios is buggy and won't use MCFG */
+    int i;
+    for (i = 0; i < acpi_mcfg.nr; i++) {
+        add_e820(e820[i].start, e820[i].size, E820_RESERVED);
+    }
+    free(e820);
+
+    build_header((void *)mcfg, MCFG_SIGNATURE, len, 1);
+    return mcfg;
+}
+
 static const struct pci_device_id acpi_find_tbl[] = {
     /* PIIX4 Power Management device. */
     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
@@ -774,6 +846,7 @@ acpi_bios_init(void)
     ACPI_INIT_TABLE(build_madt());
     ACPI_INIT_TABLE(build_hpet());
     ACPI_INIT_TABLE(build_srat());
+    ACPI_INIT_TABLE(build_mcfg());
 
     u16 i, external_tables = qemu_cfg_acpi_additional_tables();
 
diff --git a/src/acpi.h b/src/acpi.h
index cb21561..715d19d 100644
--- a/src/acpi.h
+++ b/src/acpi.h
@@ -107,4 +107,21 @@ struct bfld {
     u64 p1l;  /* pci window 1 (above 4g) - length */
 } PACKED;
 
+/* PCI fw r3.0 MCFG table. */
+/* Subtable */
+struct acpi_mcfg_allocation {
+    u64 address;                /* Base address, processor-relative */
+    u16 pci_segment;            /* PCI segment group number */
+    u8 start_bus_number;       /* Starting PCI Bus number */
+    u8 end_bus_number;         /* Final PCI Bus number */
+    u32 reserved;
+} PACKED;
+
+#define MCFG_SIGNATURE 0x4746434d       // MCFG
+struct acpi_table_mcfg {
+    ACPI_TABLE_HEADER_DEF;
+    u8 reserved[8];
+    struct acpi_mcfg_allocation allocation[0];
+} PACKED;
+
 #endif // acpi.h
-- 
1.7.1




More information about the SeaBIOS mailing list