Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/58271 )
Change subject: arch/x86/smbios: add generation of type 20 table ......................................................................
arch/x86/smbios: add generation of type 20 table
If available, use data from MEMINFO CBMEM table and saved handles from type 17/19 tables to generate type 20 SMBIOS table
Change-Id: I2574d6209d973a8e7f112eb3ef61f5d26986e47b Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/arch/x86/smbios.c M src/include/smbios.h 2 files changed, 69 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/58271/1
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index e9c8f47..f3ddc59 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -1031,6 +1031,54 @@ return len; }
+static int smbios_write_type20_table(unsigned long *current, int *handle, u32 addr_start, + u32 addr_end, int type17_handle, int type19_handle) +{ + struct smbios_type20 *t = (struct smbios_type20 *)*current; + memset(t, 0, sizeof(struct smbios_type20)); + int len = sizeof(struct smbios_type20); + + t->type = SMBIOS_MEMORY_DEVICE_MAPPED_ADDRESS; + t->memory_device_handle = type17_handle++; + t->memory_array_mapped_address_handle = type19_handle; + t->addr_start = addr_start; + t->addr_end = addr_end; + t->partition_row_pos = 0xFF; + t->interleave_pos = 0xFF; + t->interleave_depth = 0xFF; + t->handle = *handle; + *handle += 1; + t->length = len - 2; + return len; +} + +static int smbios_write_type20(unsigned long *current, int *handle, + int type17_handle, int type19_handle) +{ + u32 start_addr = 0; + int len; + int totallen = 0; + int i; + + struct memory_info *meminfo; + meminfo = cbmem_find(CBMEM_ID_MEMINFO); + if (meminfo == NULL) + return 0; /* can't find mem info in cbmem */ + + printk(BIOS_INFO, "Create SMBIOS type 20\n"); + for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) { + struct dimm_info *dimm; + dimm = &meminfo->dimm[i]; + u32 end_addr = start_addr + (dimm->dimm_size << 10) - 1; + len = smbios_write_type20_table(current, handle, start_addr, end_addr, + type17_handle, type19_handle); + start_addr += (end_addr + 1); + *current += len; + totallen += len; + } + return totallen; +} + static int smbios_write_type32(unsigned long *current, int handle) { struct smbios_type32 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_BOOT_INFORMATION, @@ -1281,8 +1329,12 @@
const int type16 = handle; update_max(len, max_struct_size, smbios_write_type16(¤t, &handle)); + const int type17 = handle; update_max(len, max_struct_size, smbios_write_type17(¤t, &handle, type16)); + const int type19 = handle; update_max(len, max_struct_size, smbios_write_type19(¤t, &handle, type16)); + update_max(len, max_struct_size, + smbios_write_type20(¤t, &handle, type17, type19)); update_max(len, max_struct_size, smbios_write_type32(¤t, handle++));
update_max(len, max_struct_size, smbios_walk_device_tree(all_devices, diff --git a/src/include/smbios.h b/src/include/smbios.h index 0b24c15..ab8f10b 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -247,6 +247,7 @@ SMBIOS_PHYS_MEMORY_ARRAY = 16, SMBIOS_MEMORY_DEVICE = 17, SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS = 19, + SMBIOS_MEMORY_DEVICE_MAPPED_ADDRESS = 20, SMBIOS_SYSTEM_BOOT_INFORMATION = 32, SMBIOS_IPMI_DEVICE_INFORMATION = 38, SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION = 41, @@ -880,6 +881,22 @@ u8 eos[2]; } __packed;
+struct smbios_type20 { + u8 type; + u8 length; + u16 handle; + u32 addr_start; + u32 addr_end; + u16 memory_device_handle; + u16 memory_array_mapped_address_handle; + u8 partition_row_pos; + u8 interleave_pos; + u8 interleave_depth; + u64 ext_addr_start; + u64 ext_addr_end; + char eos [2]; +} __packed; + struct smbios_type32 { struct smbios_header header; u8 reserved[6];