[SeaBIOS] [PATCH v3 2/8] seabios: acpi: add mcfg table.
Jason Baron
jbaron at redhat.com
Fri Oct 19 22:40:59 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]
Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
Signed-off-by: Jason Baron <jbaron at redhat.com>
---
src/acpi.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/acpi.h | 17 ++++++++++++++
2 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c
index 6d239fa..eff191d 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,76 @@ 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 +845,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