[coreboot-gerrit] Patch set updated for coreboot: b484762 qemu: 2.1+ smbios tables support
Gerd Hoffmann (kraxel@redhat.com)
gerrit at coreboot.org
Thu Mar 5 15:48:41 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 b4847626ce0fa6db7553e719ad2d8f75d9c7a623
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Aug 27 11:25:13 2014 +0200
qemu: 2.1+ smbios tables support
Starting with version 2.1 qemu provides a full set of smbios tables
for the virtual hardware emulated, except type 0 (bios information).
This patch adds support for loading those tables to coreboot.
The code is used by both i440fx and q35.
Change-Id: Id034f0c214e8890194145a92f06354201dee7963
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
src/mainboard/emulation/qemu-i440fx/fw_cfg.c | 83 +++++++++++++++++++++++
src/mainboard/emulation/qemu-i440fx/fw_cfg.h | 1 +
src/mainboard/emulation/qemu-i440fx/northbridge.c | 5 ++
3 files changed, 89 insertions(+)
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
index 44256be..242f218 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
@@ -362,6 +362,89 @@ 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 going to do here is 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