diff options
author | Matt DeVillier <matt.devillier@gmail.com> | 2016-09-02 21:41:26 -0500 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-10-15 00:18:40 +0000 |
commit | d1c1afdf574931eb15c7dec1094c6a9bc3ee60a7 (patch) | |
tree | 3279acfa885e238b1f2186d0219f6e2480d6ca93 /src/arch/x86 | |
parent | 291294d137393bb1f4d59b388f287134943f2a95 (diff) |
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 (Memory Device Mapped
Address) SMBIOS table.
Windows 10/11 and some other OSes use this table to report the total
memory available on a given device.
Change-Id: I2574d6209d973a8e7f112eb3ef61f5d26986e47b
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/58271
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/smbios.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index e9c8f47a44..04f8717e72 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -1031,6 +1031,50 @@ static int smbios_write_type19(unsigned long *current, int *handle, int type16) 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 = smbios_carve_table(*current, SMBIOS_MEMORY_DEVICE_MAPPED_ADDRESS, + sizeof(*t), *handle); + + 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; + + const int len = smbios_full_table_len(&t->header, t->eos); + *current += len; + *handle += 1; + return len; +} + +static int smbios_write_type20(unsigned long *current, int *handle, + int type17_handle, int type19_handle) +{ + u32 start_addr = 0; + 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; + totallen += smbios_write_type20_table(current, handle, start_addr, end_addr, + type17_handle, type19_handle); + start_addr = end_addr + 1; + } + 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 +1325,12 @@ unsigned long smbios_write_tables(unsigned long current) 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, |