Build full tables for types 0 (bios information) and 1 (system information). Type 0 is optional, and a table will only be built if requested via the command line; the default is to leave type 0 tables up to the bios itself.
Signed-off-by: Gabriel Somlo somlo@cmu.edu --- hw/i386/smbios.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index 06f572d..b00a367 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -352,6 +352,62 @@ static void smbios_build_type_1_fields(void) } }
+static void smbios_build_type_0_table(void) +{ + SMBIOS_BUILD_TABLE_PRE(0, 0x000, false); /* optional, leave up to BIOS */ + + SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor); + SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version); + + t->bios_starting_address_segment = 0xE800; /* hardcoded in SeaBIOS */ + + SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date); + + t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */ + + /* BIOS characteristics not supported */ + memset(t->bios_characteristics, 0, 8); + t->bios_characteristics[0] = 0x08; + + /* Enable targeted content distribution (needed for SVVP, per SeaBIOS) */ + t->bios_characteristics_extension_bytes[0] = 0; + t->bios_characteristics_extension_bytes[1] = 4; + + if (type0.have_major_minor) { + t->system_bios_major_release = type0.major; + t->system_bios_minor_release = type0.minor; + } else { + t->system_bios_major_release = 0; + t->system_bios_minor_release = 0; + } + + /* hardcoded in SeaBIOS */ + t->embedded_controller_major_release = 0xFF; + t->embedded_controller_minor_release = 0xFF; + + SMBIOS_BUILD_TABLE_POST; +} + +static void smbios_build_type_1_table(void) +{ + SMBIOS_BUILD_TABLE_PRE(1, 0x100, true); /* required */ + + SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer); + SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product); + SMBIOS_TABLE_SET_STR(1, version_str, type1.version); + SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial); + if (qemu_uuid_set) { + memcpy(t->uuid, qemu_uuid, 16); + } else { + memset(t->uuid, 0, 16); + } + t->wake_up_type = 0x06; /* power switch */ + SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku); + SMBIOS_TABLE_SET_STR(1, family_str, type1.family); + + SMBIOS_BUILD_TABLE_POST; +} + static void smbios_build_type_2_table(void) { SMBIOS_BUILD_TABLE_PRE(2, 0x200, false); /* optional */ @@ -379,6 +435,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product, const char *version) { smbios_have_defaults = true; + SMBIOS_SET_DEFAULT(type0.vendor, manufacturer); + SMBIOS_SET_DEFAULT(type0.version, version); + SMBIOS_SET_DEFAULT(type0.date, "01/01/2014"); SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); SMBIOS_SET_DEFAULT(type1.product, product); SMBIOS_SET_DEFAULT(type1.version, version); @@ -390,9 +449,13 @@ void smbios_set_defaults(const char *manufacturer, uint8_t *smbios_get_table(size_t *length) { if (!smbios_immutable) { + smbios_build_type_0_table(); + smbios_build_type_1_table(); smbios_build_type_2_table(); +if (false) { /* shut up gcc until we remove deprecated code */ smbios_build_type_0_fields(); smbios_build_type_1_fields(); +} smbios_validate_table(); smbios_immutable = true; }