[coreboot-gerrit] New patch to review for coreboot: cb5bdd1 qemu: set smbios entries from fw_cfg

Gerd Hoffmann (kraxel@redhat.com) gerrit at coreboot.org
Fri Nov 15 15:06:03 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/4086

-gerrit

commit cb5bdd144d1d86fbdfe1d33a9bda64c4b266ec73
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Nov 13 12:56:30 2013 +0100

    qemu: set smbios entries from fw_cfg
    
    Qemu makes the guest uuid (qemu -uuid $uuid) available
    to the guest via fw_cfg.  Other smbios fields can be
    configured in qemu using the -smbios command line
    switch (check the qemu manpage for details).
    
    This patch adds coreboot support for this, so the
    values provided by qemu will actually show up in the
    smbios table.
    
    Change-Id: Ifd9ae0d02749af4e7070a65eadbd1a9585a8a8e6
    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_if.h | 17 +++++
 2 files changed, 101 insertions(+)

diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
index 615aa2b..085f2a9 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
@@ -17,6 +17,7 @@
 
 #include <string.h>
 #include <swab.h>
+#include <smbios.h>
 #include <console/console.h>
 #include <arch/io.h>
 #include <arch/acpigen.h>
@@ -307,3 +308,86 @@ err:
 	free(addrs);
 	return 0;
 }
+
+/* ---------------------------------------------------------------------- */
+/* pick up smbios information from fw_cfg                                 */
+
+static const char *type1_manufacturer;
+static const char *type1_product_name;
+static const char *type1_version;
+static const char *type1_serial_number;
+static const char *type1_family;
+static u8 type1_uuid[16];
+
+static void fw_cfg_smbios_init(void)
+{
+	static int done = 0;
+	uint16_t i, count = 0;
+	FwCfgSmbios entry;
+	char *buf;
+
+	if (done)
+		return;
+	done = 1;
+
+	fw_cfg_get(FW_CFG_SMBIOS_ENTRIES, &count, sizeof(count));
+	for (i = 0; i < count; i++) {
+		insb(FW_CFG_PORT_DATA, &entry, sizeof(entry));
+		buf = malloc(entry.length - sizeof(entry));
+		insb(FW_CFG_PORT_DATA, buf, entry.length - sizeof(entry));
+		if (entry.headertype == SMBIOS_FIELD_ENTRY &&
+		    entry.tabletype == 1) {
+			switch (entry.fieldoffset) {
+			case offsetof(struct smbios_type1, manufacturer):
+				type1_manufacturer = strdup(buf);
+				break;
+			case offsetof(struct smbios_type1, product_name):
+				type1_product_name = strdup(buf);
+				break;
+			case offsetof(struct smbios_type1, version):
+				type1_version = strdup(buf);
+				break;
+			case offsetof(struct smbios_type1, serial_number):
+				type1_serial_number = strdup(buf);
+				break;
+			case offsetof(struct smbios_type1, family):
+				type1_family = strdup(buf);
+				break;
+			case offsetof(struct smbios_type1, uuid):
+				memcpy(type1_uuid, buf, 16);
+				break;
+			}
+		}
+		free(buf);
+	}
+}
+
+const char *smbios_mainboard_manufacturer(void)
+{
+	fw_cfg_smbios_init();
+	return type1_manufacturer ?: CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
+}
+
+const char *smbios_mainboard_product_name(void)
+{
+	fw_cfg_smbios_init();
+	return type1_product_name ?: CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME;
+}
+
+const char *smbios_mainboard_version(void)
+{
+	fw_cfg_smbios_init();
+	return type1_version ?: CONFIG_MAINBOARD_VERSION;
+}
+
+const char *smbios_mainboard_serial_number(void)
+{
+	fw_cfg_smbios_init();
+	return type1_serial_number ?: CONFIG_MAINBOARD_SERIAL_NUMBER;
+}
+
+void smbios_mainboard_set_uuid(u8 *uuid)
+{
+	fw_cfg_smbios_init();
+	memcpy(uuid, type1_uuid, 16);
+}
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h b/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
index 80e6280..2d27245 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h
@@ -38,6 +38,12 @@
 #define FW_CFG_ARCH_LOCAL       0x8000
 #define FW_CFG_ENTRY_MASK       ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
 
+#define FW_CFG_ACPI_TABLES      (FW_CFG_ARCH_LOCAL + 0)
+#define FW_CFG_SMBIOS_ENTRIES   (FW_CFG_ARCH_LOCAL + 1)
+#define FW_CFG_IRQ0_OVERRIDE    (FW_CFG_ARCH_LOCAL + 2)
+#define FW_CFG_E820_TABLE       (FW_CFG_ARCH_LOCAL + 3)
+#define FW_CFG_HPET             (FW_CFG_ARCH_LOCAL + 4)
+
 #define FW_CFG_INVALID          0xffff
 
 typedef struct FWCfgFile {
@@ -57,3 +63,14 @@ typedef struct FwCfgE820Entry {
     uint64_t length;
     uint32_t type;
 } FwCfgE820Entry __attribute((__aligned__(4)));
+
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+typedef struct FwCfgSmbios {
+	uint16_t length;
+	uint8_t  headertype;
+	uint8_t  tabletype;
+	uint16_t fieldoffset;
+} FwCfgSmbios;



More information about the coreboot-gerrit mailing list