diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2020-07-21 14:53:37 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2020-07-26 21:15:03 +0000 |
commit | 604295e508208dc7ea11a4ded1b7e66954b25594 (patch) | |
tree | 3882f62d76cf39dc13a018a7306098fe36841997 /src/arch/x86/smbios.c | |
parent | f04b2627105cb01bc480325498b265a3208df6f4 (diff) |
smbios: Add Type19
Implement type 19 by accumulating the DRAM dimm size found in cbmem's
CBMEM_ID_MEMINFO structure. This seems common on x86 where the
address space always starts at 0.
At least EDK2 uses this table in the UI and shows 0 MB DRAM if not
present.
Change-Id: Idee8b8cd0b155e14d62d4c12893ff01878ef3f1c
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/43672
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Christian Walter <christian.walter@9elements.com>
Diffstat (limited to 'src/arch/x86/smbios.c')
-rw-r--r-- | src/arch/x86/smbios.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 1c7f2ac4f2..c38c3692dc 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -1079,6 +1079,56 @@ static int smbios_write_type17(unsigned long *current, int *handle) return totallen; } +static int smbios_write_type19(unsigned long *current, int *handle) +{ + struct smbios_type19 *t = (struct smbios_type19 *)*current; + int len = sizeof(struct smbios_type19); + int i; + + struct memory_info *meminfo; + meminfo = cbmem_find(CBMEM_ID_MEMINFO); + if (meminfo == NULL) + return 0; /* can't find mem info in cbmem */ + + memset(t, 0, sizeof(struct smbios_type19)); + + t->type = SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS; + t->length = len - 2; + t->handle = *handle; + + for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) { + if (meminfo->dimm[i].dimm_size > 0) { + t->extended_ending_address += meminfo->dimm[i].dimm_size; + t->partition_width++; + } + } + t->extended_ending_address *= MiB; + + /* Check if it fits into regular address */ + if (t->extended_ending_address >= KiB && + t->extended_ending_address < 0x40000000000ULL) { + /* + * FIXME: The starting address is SoC specific, but SMBIOS tables are only + * exported on x86 where it's always 0. + */ + + t->starting_address = 0; + t->ending_address = t->extended_ending_address / KiB - 1; + t->extended_starting_address = ~0; + t->extended_ending_address = ~0; + } else { + t->starting_address = ~0; + t->ending_address = ~0; + t->extended_starting_address = 0; + t->extended_ending_address--; + } + + len = t->length + smbios_string_table_len(t->eos); + *current += len; + *handle += 1; + return len; +} + static int smbios_write_type32(unsigned long *current, int handle) { struct smbios_type32 *t = (struct smbios_type32 *)*current; @@ -1296,6 +1346,8 @@ unsigned long smbios_write_tables(unsigned long current) elog_smbios_write_type15(¤t,handle++)); update_max(len, max_struct_size, smbios_write_type17(¤t, &handle)); + update_max(len, max_struct_size, smbios_write_type19(¤t, + &handle)); update_max(len, max_struct_size, smbios_write_type32(¤t, handle++)); |