From 2b48258865fc0819c92e3fbc15f6c7ea9f00966d Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Tue, 3 May 2022 18:12:18 +0200 Subject: [PATCH] arch/x86/smbios.c: Allow creating entries for empty DIMM slots Properly handle meminfo DIMMs with `dimm_size` of 0, which represent empty slots. This allows platform code to create dummy meminfo DIMMs so that SMBIOS tables have type 17 entries for empty DIMM slots. Change-Id: I17ae83edf94483bd2eeef5524ff82721c196b8ba Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/64035 Reviewed-by: Jonathan Zhang Tested-by: build bot (Jenkins) --- src/arch/x86/smbios.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 5b8df5bc64..8d9de7c728 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -277,6 +277,26 @@ static int create_smbios_type17_for_dimm(struct dimm_info *dimm, return smbios_full_table_len(&t->header, t->eos); } +static int create_smbios_type17_for_empty_slot(struct dimm_info *dimm, + unsigned long *current, int *handle, + int type16_handle) +{ + struct smbios_type17 *t = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE, + sizeof(*t), *handle); + t->phys_memory_array_handle = type16_handle; + /* no handle for error information */ + t->memory_error_information_handle = 0xfffe; + t->total_width = 0xffff; /* Unknown */ + t->data_width = 0xffff; /* Unknown */ + t->form_factor = 0x2; /* Unknown */ + smbios_fill_dimm_locator(dimm, t); /* Device and Bank */ + t->memory_type = 0x2; /* Unknown */ + t->type_detail = 0x2; /* Unknown */ + + *handle += 1; + return smbios_full_table_len(&t->header, t->eos); +} + #define VERSION_VPD "firmware_version" static const char *vpd_get_bios_version(void) { @@ -947,15 +967,19 @@ static int smbios_write_type17(unsigned long *current, int *handle, int type16) printk(BIOS_INFO, "Create SMBIOS type 17\n"); for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) { - struct dimm_info *dimm; - dimm = &meminfo->dimm[i]; + struct dimm_info *d = &meminfo->dimm[i]; /* * Windows 10 GetPhysicallyInstalledSystemMemory functions reads SMBIOS tables * type 16 and type 17. The type 17 tables need to point to a type 16 table. * Otherwise, the physical installed memory size is guessed from the system * memory map, which results in a slightly smaller value than the actual size. */ - const int len = create_smbios_type17_for_dimm(dimm, current, handle, type16); + int len; + if (d->dimm_size > 0) + len = create_smbios_type17_for_dimm(d, current, handle, type16); + else + len = create_smbios_type17_for_empty_slot(d, current, handle, type16); + *current += len; totallen += len; } @@ -1046,6 +1070,9 @@ static int smbios_write_type20(unsigned long *current, int *handle, for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) { struct dimm_info *dimm; dimm = &meminfo->dimm[i]; + if (dimm->dimm_size == 0) + continue; + u32 end_addr = start_addr + (dimm->dimm_size << 10) - 1; totallen += smbios_write_type20_table(current, handle, start_addr, end_addr, type17_handle, type19_handle);