[SeaBIOS] [PATCH] seabios: acpi: add mcfg table.

Isaku Yamahata yamahata at valinux.co.jp
Fri Jul 30 04:51:58 CEST 2010


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

Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
---
 src/acpi.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/acpi.h |   17 ++++++++++++++++
 src/post.h |   14 +++++++++++++
 3 files changed, 93 insertions(+), 0 deletions(-)
 create mode 100644 src/post.h

diff --git a/src/acpi.c b/src/acpi.c
index e91f8e0..d61ae16 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -13,6 +13,7 @@
 #include "pci_regs.h" // PCI_INTERRUPT_LINE
 #include "paravirt.h"
 #include "dev-i440fx.h" // piix4_fadt_init
+#include "post.h"
 
 /****************************************************/
 /* ACPI tables init */
@@ -522,6 +523,66 @@ build_srat(void)
     return srat;
 }
 
+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 acpi_mcfg acpi_mcfg = {
+        .nr = 0,
+        .mcfg = NULL,
+        .e820 = NULL,
+    };
+    int bdf = pci_find_init_device(mcfg_find_tbl, &acpi_mcfg);
+    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, bdf, &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),
@@ -568,6 +629,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 e01315a..798fb19 100644
--- a/src/acpi.h
+++ b/src/acpi.h
@@ -98,4 +98,21 @@ struct fadt_descriptor_rev1
 #endif
 } 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
diff --git a/src/post.h b/src/post.h
new file mode 100644
index 0000000..04e506d
--- /dev/null
+++ b/src/post.h
@@ -0,0 +1,14 @@
+#ifndef __POST_H
+#define __POST_H
+
+#include "memmap.h"     // struct e820entry
+#include "acpi.h"       // struct acpi_table_mcfg
+
+struct acpi_mcfg
+{
+    u32 nr;
+    struct acpi_table_mcfg *mcfg;
+    struct e820entry *e820;
+};
+
+#endif /* __POST_H */
-- 
1.7.1.1




More information about the SeaBIOS mailing list