diff options
-rw-r--r-- | src/mainboard/emulation/qemu-i440fx/fw_cfg.c | 84 | ||||
-rw-r--r-- | src/mainboard/emulation/qemu-i440fx/fw_cfg_if.h | 17 |
2 files changed, 101 insertions, 0 deletions
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c index 615aa2be3b..085f2a9ad4 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 80e628032b..2d272450b0 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; |