summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2020-07-21 14:53:37 +0200
committerPatrick Georgi <pgeorgi@google.com>2020-07-26 21:15:03 +0000
commit604295e508208dc7ea11a4ded1b7e66954b25594 (patch)
tree3882f62d76cf39dc13a018a7306098fe36841997
parentf04b2627105cb01bc480325498b265a3208df6f4 (diff)
downloadcoreboot-604295e508208dc7ea11a4ded1b7e66954b25594.tar.xz
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>
-rw-r--r--src/arch/x86/smbios.c52
-rw-r--r--src/include/smbios.h13
2 files changed, 65 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(&current,handle++));
update_max(len, max_struct_size, smbios_write_type17(&current,
&handle));
+ update_max(len, max_struct_size, smbios_write_type19(&current,
+ &handle));
update_max(len, max_struct_size, smbios_write_type32(&current,
handle++));
diff --git a/src/include/smbios.h b/src/include/smbios.h
index ed09d642b9..8cdd58a828 100644
--- a/src/include/smbios.h
+++ b/src/include/smbios.h
@@ -828,6 +828,19 @@ struct smbios_type17 {
u8 eos[2];
} __packed;
+struct smbios_type19 {
+ u8 type;
+ u8 length;
+ u16 handle;
+ u32 starting_address;
+ u32 ending_address;
+ u16 memory_array_handle;
+ u8 partition_width;
+ u64 extended_starting_address;
+ u64 extended_ending_address;
+ u8 eos[2];
+} __packed;
+
struct smbios_type32 {
u8 type;
u8 length;