From: Arbel Moshe arbel.moshe@oracle.com
Add support for obsolete SMBIOS Type 6 which describes the speed, type, size and error status of each system memory module.
This is required by some guests to boot successfully.
Such an example is Cisco NGFW appliance which has a script which runs every boot that parses this SMBIOS Type 6 information and if it doesn't exists, it just fails to boot with an error of "Unable to parse dmidecode. Restarting now!".
Reviewed-by: Liran Alon liran.alon@oracle.com Reviewed-by: Ross Philipson ross.philipson@oracle.com Signed-off-by: Arbel Moshe arbel.moshe@oracle.com --- src/fw/smbios.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/std/smbios.h | 12 ++++++++++++ 2 files changed, 58 insertions(+)
diff --git a/src/fw/smbios.c b/src/fw/smbios.c index f3b5ad9dd9a0..751ae98f0fc4 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -348,6 +348,51 @@ smbios_init_type_4(void *start, unsigned int cpu_number) return end; }
+/* Type 6 -- Memory Module Information */ +static void * +smbios_init_type_6(void *start, u32 size_mb, int instance) +{ + struct smbios_type_6 *p = (struct smbios_type_6 *)start; + char *end = (char *)start + sizeof(struct smbios_type_6); + u8 size_mem = 0; + char name[1024]; + int str_index = 0; + + p->header.type = 6; + p->header.length = sizeof(struct smbios_type_6); + p->header.handle = 0x600 + instance; + + snprintf(name, sizeof(name), "RAM socket #%2x", instance); + + memcpy(end, name, strlen(name) + 1); + end += strlen(name) + 1; + p->socket_designation_str = ++str_index; + + set_field_with_default(6, bank_connection, 0xff); /* No connection */ + set_field_with_default(6, current_speed, 0); /* Unknown Speed */ + set_field_with_default(6, memory_type, 0x400); /* SDRAM */ + + /* size_mem = n, where 2**n = size_mb */ + size_mb = size_mb >> 1; + while (size_mb) { + ++size_mem; + size_mb = size_mb >> 1; + } + + p->installed_size = size_mem; + p->enabled_size = size_mem; + set_field_with_default(6, error_status, 0); + + *end = 0; + end++; + if (!str_index) { + *end = 0; + end++; + } + + return end; +} + /* Type 16 -- Physical Memory Array */ static void * smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs) @@ -550,6 +595,7 @@ smbios_legacy_setup(void) u32 dev_mb = ((i == (nr_mem_devs - 1)) ? (((ram_mb - 1) & 0x3fff) + 1) : 16384); + add_struct(6, p, dev_mb, i); add_struct(17, p, dev_mb, i); }
diff --git a/src/std/smbios.h b/src/std/smbios.h index 4ccf2ea348ee..765ac51667ed 100644 --- a/src/std/smbios.h +++ b/src/std/smbios.h @@ -100,6 +100,18 @@ struct smbios_type_4 { u16 l3_cache_handle; } PACKED;
+/* SMBIOS type 6 - Memory Module Information */ +struct smbios_type_6 { + struct smbios_structure_header header; + u8 socket_designation_str; + u8 bank_connection; + u8 current_speed; + u16 memory_type; + u8 installed_size; + u8 enabled_size; + u8 error_status; +} PACKED; + /* SMBIOS type 16 - Physical Memory Array * Associated with one type 17 (Memory Device). */