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>
This commit is contained in:
parent
291294d137
commit
d1c1afdf57
|
@ -1031,6 +1031,50 @@ static int smbios_write_type19(unsigned long *current, int *handle, int type16)
|
||||||
return len;
|
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)
|
static int smbios_write_type32(unsigned long *current, int handle)
|
||||||
{
|
{
|
||||||
struct smbios_type32 *t = smbios_carve_table(*current, SMBIOS_SYSTEM_BOOT_INFORMATION,
|
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;
|
const int type16 = handle;
|
||||||
update_max(len, max_struct_size, smbios_write_type16(¤t, &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));
|
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_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_write_type32(¤t, handle++));
|
||||||
|
|
||||||
update_max(len, max_struct_size, smbios_walk_device_tree(all_devices,
|
update_max(len, max_struct_size, smbios_walk_device_tree(all_devices,
|
||||||
|
|
|
@ -247,6 +247,7 @@ typedef enum {
|
||||||
SMBIOS_PHYS_MEMORY_ARRAY = 16,
|
SMBIOS_PHYS_MEMORY_ARRAY = 16,
|
||||||
SMBIOS_MEMORY_DEVICE = 17,
|
SMBIOS_MEMORY_DEVICE = 17,
|
||||||
SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS = 19,
|
SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS = 19,
|
||||||
|
SMBIOS_MEMORY_DEVICE_MAPPED_ADDRESS = 20,
|
||||||
SMBIOS_SYSTEM_BOOT_INFORMATION = 32,
|
SMBIOS_SYSTEM_BOOT_INFORMATION = 32,
|
||||||
SMBIOS_IPMI_DEVICE_INFORMATION = 38,
|
SMBIOS_IPMI_DEVICE_INFORMATION = 38,
|
||||||
SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION = 41,
|
SMBIOS_ONBOARD_DEVICES_EXTENDED_INFORMATION = 41,
|
||||||
|
@ -880,6 +881,20 @@ struct smbios_type19 {
|
||||||
u8 eos[2];
|
u8 eos[2];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct smbios_type20 {
|
||||||
|
struct smbios_header header;
|
||||||
|
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;
|
||||||
|
u8 eos[2];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct smbios_type32 {
|
struct smbios_type32 {
|
||||||
struct smbios_header header;
|
struct smbios_header header;
|
||||||
u8 reserved[6];
|
u8 reserved[6];
|
||||||
|
|
Loading…
Reference in New Issue