[coreboot-gerrit] New patch to review for coreboot: 07bc2d2 qemu: 2.1+ smbios tables support

Gerd Hoffmann (kraxel@redhat.com) gerrit at coreboot.org
Thu Mar 5 12:33:24 CET 2015


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

-gerrit

commit 07bc2d274380f3943b1bf2a4f876a52c32e3a1f2
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 27 11:25:13 2014 +0200

    qemu: 2.1+ smbios tables support
    
    Change-Id: Id034f0c214e8890194145a92f06354201dee7963
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 src/mainboard/emulation/qemu-i440fx/fw_cfg.c      | 84 +++++++++++++++++++++++
 src/mainboard/emulation/qemu-i440fx/fw_cfg.h      |  1 +
 src/mainboard/emulation/qemu-i440fx/northbridge.c |  5 ++
 3 files changed, 90 insertions(+)

diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
index 44256be..d117b2e 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
@@ -362,6 +362,90 @@ static void fw_cfg_smbios_init(void)
 	}
 }
 
+static unsigned long smbios_next(unsigned long current)
+{
+	struct smbios_type0 *t0;
+	int l, count = 0;
+	char *s;
+
+	t0 = (void*)current;
+	current += t0->length;
+	for (;;) {
+		s = (void*)current;
+		l = strlen(s);
+		if (!l) {
+			return current + (count ? 1 : 2);
+		}
+		current += l+1;
+		count++;
+	}
+}
+
+/*
+ * Starting with version 2.1 qemu provides a full set of smbios tables
+ * for the virtual hardware emulated, except type 0 (bios information).
+ *
+ * What we are doing here is going find the type0 table, keep it, and
+ * override everything else generated by coreboot with the qemu smbios
+ * tables.
+ *
+ * It's a bit hackish, but qemu is a special case (compared to real
+ * hardware) and this way we don't need special qemu support in the
+ * generic smbios code.
+ */
+unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
+{
+	struct smbios_type0 *t0;
+	unsigned long start, end;
+	int len, ret, i, count = 1;
+	char *str;
+
+	len = fw_cfg_check_file("etc/smbios/smbios-tables");
+	if (len < 0)
+		return 0;
+	printk(BIOS_DEBUG, "QEMU: found smbios tables in fw_cfg (len %d).\n", len);
+
+	/*
+	 * Search backwards for "coreboot" (first string in type0 table,
+	 * see src/arch/x86/boot/smbios.c), then find type0 table.
+	 */
+	for (i = 0; i < 16384; i++) {
+		str = (char*)(*current - i);
+		if (strcmp(str, "coreboot") == 0)
+			break;
+	}
+	if (i == 16384)
+		return 0;
+	i += sizeof(struct smbios_type0) - 2;
+	t0 = (struct smbios_type0*)(*current - i);
+	if (t0->type != SMBIOS_BIOS_INFORMATION || t0->handle != 0)
+		return 0;
+	printk(BIOS_DEBUG, "QEMU: coreboot type0 table found at 0x%lx.\n",
+	       *current - i);
+	start = smbios_next(*current - i);
+
+	/*
+	 * Fetch smbios tables from qemu, go find the end marker.
+	 * We'll exclude the end marker as coreboot will add one.
+	 */
+	printk(BIOS_DEBUG, "QEMU: loading smbios tables to 0x%lx\n", start);
+	fw_cfg_load_file("etc/smbios/smbios-tables", (void*)start);
+	end = start;
+	do {
+		t0 = (struct smbios_type0*)end;
+		if (t0->type == SMBIOS_END_OF_TABLE)
+			break;
+		end = smbios_next(end);
+		count++;
+	} while (end < start + len);
+
+	/* final fixups. */
+	ret = end - *current;
+	*current = end;
+	*handle = count;
+	return ret;
+}
+
 const char *smbios_mainboard_manufacturer(void)
 {
 	fw_cfg_smbios_init();
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.h b/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
index 2a10d8b..51ecaa8 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
@@ -19,3 +19,4 @@ void fw_cfg_get(int entry, void *dst, int dstlen);
 int fw_cfg_check_file(const char *name);
 void fw_cfg_load_file(const char *name, void *dst);
 int fw_cfg_max_cpus(void);
+unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current);
diff --git a/src/mainboard/emulation/qemu-i440fx/northbridge.c b/src/mainboard/emulation/qemu-i440fx/northbridge.c
index 08d563f..f12a272 100644
--- a/src/mainboard/emulation/qemu-i440fx/northbridge.c
+++ b/src/mainboard/emulation/qemu-i440fx/northbridge.c
@@ -213,6 +213,11 @@ static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *
 static int qemu_get_smbios_data(device_t dev, int *handle, unsigned long *current)
 {
 	int len;
+
+	len = fw_cfg_smbios_tables(handle, current);
+	if (len != 0)
+		return len;
+
 	len = qemu_get_smbios_data16(*handle, current);
 	len += qemu_get_smbios_data17(*handle+1, *handle, current);
 	*handle += 2;



More information about the coreboot-gerrit mailing list