[coreboot-gerrit] New patch to review for coreboot: 6430821 qemu: load e820 from fw_cfg

Gerd Hoffmann (kraxel@redhat.com) gerrit at coreboot.org
Wed Nov 6 14:56:36 CET 2013


Gerd Hoffmann (kraxel at redhat.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4030

-gerrit

commit 6430821feff312d7dab381bda2ebfc3bc52047b2
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Nov 6 14:36:17 2013 +0100

    qemu: load e820 from fw_cfg
    
    qemu 1.7+ provides a fw_cfg file named "etc/e820" with e820-like entries
    for reservations and ram regions.  Use it for ram detection if present,
    otherwise fallback to the traditional cmos method.
    
    Change-Id: Icac6c99d2a053e59dfdd28e48d1ceb3d56a61bdc
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h   |  6 +++
 src/mainboard/emulation/qemu-i440fx/northbridge.c | 65 +++++++++++++++++++----
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h b/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
index d159f12..80e6280 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
@@ -51,3 +51,9 @@ typedef struct FWCfgFiles {
     uint32_t  count;
     FWCfgFile f[];
 } FWCfgFiles;
+
+typedef struct FwCfgE820Entry {
+    uint64_t address;
+    uint64_t length;
+    uint32_t type;
+} FwCfgE820Entry __attribute((__aligned__(4)));
diff --git a/src/mainboard/emulation/qemu-i440fx/northbridge.c b/src/mainboard/emulation/qemu-i440fx/northbridge.c
index c878689..0f8c0c2 100644
--- a/src/mainboard/emulation/qemu-i440fx/northbridge.c
+++ b/src/mainboard/emulation/qemu-i440fx/northbridge.c
@@ -13,6 +13,7 @@
 #include <cbmem.h>
 
 #include "fw_cfg.h"
+#include "fw_cfg_if.h"
 
 #include "memory.c"
 
@@ -58,20 +59,62 @@ static void cpu_pci_domain_read_resources(struct device *dev)
 	struct resource *res;
 	unsigned long tomk = 0, high;
 	int idx = 10;
+	int size;
 
 	pci_domain_read_resources(dev);
 
-	tomk = qemu_get_memory_size();
-	high = qemu_get_high_memory_size();
-	printk(BIOS_DEBUG, "Detected %lu MiB RAM below 4G.\n", tomk / 1024);
-	printk(BIOS_DEBUG, "Detected %lu MiB RAM above 4G.\n", high / 1024);
-
-	/* Report the memory regions. */
-	idx = 10;
-	ram_resource(dev, idx++, 0, 640);
-	ram_resource(dev, idx++, 768, tomk - 768);
-	if (high)
-		ram_resource(dev, idx++, 4 * 1024 * 1024, high);
+	size = fw_cfg_check_file("etc/e820");
+	if (size > 0) {
+		/* supported by qemu 1.7+ */
+		FwCfgE820Entry *list = malloc(size);
+		int i;
+		fw_cfg_load_file("etc/e820", list);
+		for (i = 0; i < size/sizeof(*list); i++) {
+			switch (list[i].type) {
+			case 1: /* ram */
+				printk(BIOS_DEBUG, "QEMU: e820/ram: 0x%08llx +0x%08llx\n",
+				       list[i].address, list[i].length);
+				if (list[i].address == 0) {
+					tomk = list[i].length / 1024;
+					ram_resource(dev, idx++, 0, 640);
+					ram_resource(dev, idx++, 768, tomk - 768);
+				} else {
+					ram_resource(dev, idx++,
+						     list[i].address / 1024,
+						     list[i].length / 1024);
+				}
+				break;
+			case 2: /* reserved */
+				printk(BIOS_DEBUG, "QEMU: e820/res: 0x%08llx +0x%08llx\n",
+				       list[i].address, list[i].length);
+				res = new_resource(dev, idx++);
+				res->base = list[i].address;
+				res->size = list[i].length;
+				res->limit = 0xffffffff;
+				res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+					IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+				break;
+			default:
+				/* skip unknown */
+				break;
+			}
+		}
+		free(list);
+	}
+
+	if (!tomk) {
+		/* qemu older than 1.7, or reading etc/e820 failed. Fallback to cmos. */
+		tomk = qemu_get_memory_size();
+		high = qemu_get_high_memory_size();
+		printk(BIOS_DEBUG, "QEMU: cmos: %lu MiB RAM below 4G.\n", tomk / 1024);
+		printk(BIOS_DEBUG, "QEMU: cmos: %lu MiB RAM above 4G.\n", high / 1024);
+
+		/* Report the memory regions. */
+		ram_resource(dev, idx++, 0, 640);
+		ram_resource(dev, idx++, 768, tomk - 768);
+		if (high)
+			ram_resource(dev, idx++, 4 * 1024 * 1024, high);
+	}
 
 	/* Reserve I/O ports used by QEMU */
 	qemu_reserve_ports(dev, idx++, 0x0510, 0x02, "firmware-config");



More information about the coreboot-gerrit mailing list