Morgan Jang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/46068 )
Change subject: arch/x86/smbios: Update SMBIOS type 7 ......................................................................
arch/x86/smbios: Update SMBIOS type 7
Combine L1 Data cache size and L1 Instruction cache size, and multiply the cache size of L1 and L2 by the number of cores.
TEST=Execute "dmidecode -t 7" to check if the cache information is correct for Deltalake platform
Change-Id: Ieeb5d3346454ffb2291613dc2aa24b31d10c2e04 Signed-off-by: Morgan Jang Morgan_Jang@wiwynn.com --- M src/arch/x86/smbios.c M src/include/smbios.h 2 files changed, 82 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/46068/1
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index e33b70f..026849f 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -476,6 +476,52 @@ return (res.eax > 0) ? 0x0c : 0x6; }
+unsigned int __weak smbios_cache_error_correction_type(void) +{ + return SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN; /* Unknown */ +} +unsigned int __weak smbios_cache_sram_type(void) +{ + return SMBIOS_CACHE_SRAM_TYPE_UNKNOWN; /* Unknown */ +} + +unsigned int __weak smbios_cache_conf_operation_mode(u8 level) +{ + return 3; /* Unknown */ +} + +static size_t get_number_of_caches(u32 leaf, u8 level) +{ + size_t max_logical_cpus_sharing_cache = 0; + size_t number_of_logical_cpus = 0; + size_t max_logical_cpus_per_package = 0; + struct cpuid_result res; + + /* Provide sane defaults even for CPU without CPUID */ + res.eax = res.edx = 0; + res.ebx = 0x10000; + + if (cpu_have_cpuid()) + res = cpuid(1); + + max_logical_cpus_per_package = (res.ebx >> 16) & 0xff; + + if (cpu_have_cpuid() && cpuid_get_max_func() >= 0xb) { + res = cpuid_ext(0xb, 1); + number_of_logical_cpus = res.ebx; + } else { + number_of_logical_cpus = max_logical_cpus_per_package; + } + + res = cpuid_ext(leaf, level); + max_logical_cpus_sharing_cache = ((res.eax >> 14) & 0xfff) + 1; + + if (max_logical_cpus_sharing_cache != max_logical_cpus_per_package) + return number_of_logical_cpus / max_logical_cpus_sharing_cache; + + return 1; +} + static int smbios_write_type1(unsigned long *current, int handle) { struct smbios_type1 *t = (struct smbios_type1 *)*current; @@ -650,11 +696,11 @@ const enum smbios_cache_associativity associativity, const enum smbios_cache_type type, const size_t max_cache_size, - const size_t cache_size) + const size_t cache_size, + const u32 leaf) { struct smbios_type7 *t = (struct smbios_type7 *)*current; int len = sizeof(struct smbios_type7); - static unsigned int cnt = 0; char buf[8];
memset(t, 0, sizeof(struct smbios_type7)); @@ -662,13 +708,13 @@ t->handle = handle; t->length = len - 2;
- snprintf(buf, sizeof(buf), "CACHE%x", cnt++); + snprintf(buf, sizeof(buf), "CACHE%x", level); t->socket_designation = smbios_add_string(t->eos, buf);
t->cache_configuration = SMBIOS_CACHE_CONF_LEVEL(level) | SMBIOS_CACHE_CONF_LOCATION(0) | /* Internal */ SMBIOS_CACHE_CONF_ENABLED(1) | /* Enabled */ - SMBIOS_CACHE_CONF_OPERATION_MODE(3); /* Unknown */ + SMBIOS_CACHE_CONF_OPERATION_MODE(smbios_cache_conf_operation_mode(level));
if (max_cache_size < (SMBIOS_CACHE_SIZE_MASK * KiB)) { t->max_cache_size = max_cache_size / KiB; @@ -704,11 +750,16 @@ t->installed_size2 |= SMBIOS_CACHE_SIZE2_UNIT_64KB; }
+ t->max_cache_size *= get_number_of_caches(leaf, level); + t->installed_size *= get_number_of_caches(leaf, level); + t->max_cache_size2 *= get_number_of_caches(leaf, level); + t->installed_size2 *= get_number_of_caches(leaf, level); + t->associativity = associativity; t->supported_sram_type = sram_type; t->current_sram_type = sram_type; t->cache_speed = 0; /* Unknown */ - t->error_correction_type = SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN; + t->error_correction_type = smbios_cache_error_correction_type(); t->system_cache_type = type;
len = t->length + smbios_string_table_len(t->eos); @@ -767,6 +818,7 @@ unsigned int cnt = 0; int len = 0; u32 leaf; + size_t cache0_size = 0;
if (!cpu_have_cpuid()) return len; @@ -803,7 +855,8 @@ const size_t partitions = CPUID_CACHE_PHYS_LINE(res) + 1; const size_t cache_line_size = CPUID_CACHE_COHER_LINE(res) + 1; const size_t number_of_sets = CPUID_CACHE_NO_OF_SETS(res) + 1; - const size_t cache_size = assoc * partitions * cache_line_size * number_of_sets; + size_t cache_size = assoc * partitions * cache_line_size * + number_of_sets;
if (!cache_type) /* No more caches in the system */ @@ -829,11 +882,21 @@ else associativity = smbios_cache_associativity(assoc);
+ if (level == 1 && type == SMBIOS_CACHE_TYPE_DATA) { + cache0_size = cache_size; + continue; + } + + if (level == 1 && type == SMBIOS_CACHE_TYPE_INSTRUCTION) { + cache_size += cache0_size; + type = SMBIOS_CACHE_TYPE_UNIFIED; + } + const int h = (*handle)++;
update_max(len, *max_struct_size, smbios_write_type7(current, h, - level, SMBIOS_CACHE_SRAM_TYPE_UNKNOWN, associativity, - type, cache_size, cache_size)); + level, smbios_cache_sram_type(), associativity, + type, cache_size, cache_size, leaf));
if (type4) { switch (level) { diff --git a/src/include/smbios.h b/src/include/smbios.h index 521339e..216c8f6 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -59,6 +59,10 @@ struct cpuid_result; unsigned int smbios_processor_family(struct cpuid_result res);
+unsigned int smbios_cache_error_correction_type(void); +unsigned int smbios_cache_sram_type(void); +unsigned int smbios_cache_conf_operation_mode(u8 level); + /* Used by mainboard to add port information of type 8 */ struct port_information; int smbios_write_type8(unsigned long *current, int *handle, @@ -499,6 +503,13 @@ #define SMBIOS_CACHE_SIZE2_UNIT_64KB (1UL << 31) #define SMBIOS_CACHE_SIZE2_MASK 0x7fffffff
+/* define for cache operation mode */ + +#define SMBIOS_CACHE_OP_MODE_WRITE_THROUGH 0 +#define SMBIOS_CACHE_OP_MODE_WRITE_BACK 1 +#define SMBIOS_CACHE_OP_MODE_VARIES_WITH_MEMORY_ADDRESS 2 +#define SMBIOS_CACHE_OP_MODE_UNKNOWN 3 + struct smbios_type7 { u8 type; u8 length;