Morgan Jang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/44059 )
Change subject: mb/ocp/deltalake: Update SMBIOS type 7 -- Cache Information ......................................................................
mb/ocp/deltalake: Update SMBIOS type 7 -- Cache Information
According to BIOS writer`s guide, L1 Data cache size and L1 Instruction cache size should be combined, and multiply the cache size of L1 and L2 by the number of cores
TEST=Execute "dmidecode -t 4" to check if the cache information is correct for Deltalake platform
Change-Id: Ibfb7d048046ff69fd3f0d18359193f80b8f39911 Signed-off-by: Morgan Jang Morgan_Jang@wiwynn.com --- M src/arch/x86/smbios.c M src/include/smbios.h M src/mainboard/ocp/deltalake/ramstage.c 3 files changed, 79 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/44059/1
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 070c7ea..ead956e 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -607,6 +607,20 @@ return 0x02; /* Unknown */ }
+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 int smbios_write_type1(unsigned long *current, int handle) { struct smbios_type1 *t = (struct smbios_type1 *)*current; @@ -766,8 +780,10 @@ { struct smbios_type7 *t = (struct smbios_type7 *)*current; int len = sizeof(struct smbios_type7); - static unsigned int cnt = 0; + static unsigned int cnt = 1; char buf[8]; + u8 core_count; + struct cpuid_result res;
memset(t, 0, sizeof(struct smbios_type7)); t->type = SMBIOS_CACHE_INFORMATION; @@ -780,7 +796,7 @@ 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; @@ -816,11 +832,33 @@ t->installed_size2 |= SMBIOS_CACHE_SIZE2_UNIT_64KB; }
+ if (cpu_have_cpuid() && cpuid_get_max_func() >= 0xb) { + uint32_t leaf_b_cores = 0, leaf_b_threads = 0; + res = cpuid_ext(0xb, 1); + leaf_b_cores = res.ebx; + res = cpuid_ext(0xb, 0); + leaf_b_threads = res.ebx; + /* if hyperthreading is not available, pretend this is 1 */ + if (leaf_b_threads == 0) + leaf_b_threads = 1; + + core_count = leaf_b_cores / leaf_b_threads; + } else { + core_count = (res.ebx >> 16) & 0xff; + } + + if (level == 0 || level == 1 || level == 2) { + t->max_cache_size *= core_count; + t->installed_size *= core_count; + t->max_cache_size2 *= core_count; + t->installed_size2 *= core_count; + } + 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); @@ -880,6 +918,7 @@ unsigned int cnt = 0; int len = 0; u32 leaf; + size_t cache0_size = 0;
if (!cpu_have_cpuid()) return len; @@ -916,7 +955,7 @@ 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 * + size_t cache_size = assoc * partitions * cache_line_size * number_of_sets;
if (!cache_type) @@ -938,6 +977,16 @@ break; }
+ 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; + } + if (CPUID_CACHE_FULL_ASSOC(res)) associativity = SMBIOS_CACHE_ASSOCIATIVITY_FULL; else @@ -946,7 +995,7 @@ const int h = (*handle)++;
update_max(len, *max_struct_size, smbios_write_type7(current, h, - level, SMBIOS_CACHE_SRAM_TYPE_UNKNOWN, associativity, + level, smbios_cache_sram_type(), associativity, type, cache_size, cache_size));
if (type4) { diff --git a/src/include/smbios.h b/src/include/smbios.h index 45c550a..7cbf391 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -54,6 +54,10 @@ const char *smbios_chassis_serial_number(void); const char *smbios_processor_serial_number(void);
+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, diff --git a/src/mainboard/ocp/deltalake/ramstage.c b/src/mainboard/ocp/deltalake/ramstage.c index 4418ea4..2805f85 100644 --- a/src/mainboard/ocp/deltalake/ramstage.c +++ b/src/mainboard/ocp/deltalake/ramstage.c @@ -210,6 +210,27 @@ } #endif
+unsigned int smbios_cache_error_correction_type(void) +{ + return SMBIOS_CACHE_ERROR_CORRECTION_SINGLE_BIT; +} +unsigned int smbios_cache_sram_type(void) +{ + return SMBIOS_CACHE_SRAM_TYPE_SYNCHRONOUS; +} + +unsigned int smbios_cache_conf_operation_mode(u8 level) +{ + switch (level) { + case 1: + return 1; /* Writre Back */ + case 2: + case 3: + return 2; /* Varies with Memory Address*/ + default: + return 3; + } +}
static void mainboard_enable(struct device *dev) {