arch/x86/smbios: Populate SMBIOS type 7 with cache information

SMBIOS has a field to display the cache size, which is currently
set to UNKNOWN unconditionally, 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>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46068
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Jonathan Zhang <jonzhang@fb.com>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Morgan Jang 2020-10-06 16:26:17 +08:00 committed by Patrick Georgi
parent 8ccc8fdf26
commit 8ae391d199
2 changed files with 62 additions and 6 deletions

View File

@ -478,6 +478,51 @@ unsigned int __weak smbios_processor_family(struct cpuid_result res)
return (res.eax > 0) ? 0x0c : 0x6; return (res.eax > 0) ? 0x0c : 0x6;
} }
unsigned int __weak smbios_cache_error_correction_type(u8 level)
{
return SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN;
}
unsigned int __weak smbios_cache_sram_type(void)
{
return SMBIOS_CACHE_SRAM_TYPE_UNKNOWN;
}
unsigned int __weak smbios_cache_conf_operation_mode(u8 level)
{
return SMBIOS_CACHE_OP_MODE_UNKNOWN; /* Unknown */
}
static size_t get_number_of_caches(struct cpuid_result res_deterministic_cache)
{
size_t max_logical_cpus_sharing_cache = 0;
size_t number_of_cpus_per_package = 0;
size_t max_logical_cpus_per_package = 0;
struct cpuid_result res;
if (!cpu_have_cpuid())
return 1;
res = cpuid(1);
max_logical_cpus_per_package = (res.ebx >> 16) & 0xff;
max_logical_cpus_sharing_cache = ((res_deterministic_cache.eax >> 14) & 0xfff) + 1;
/* Check if it's last level cache */
if (max_logical_cpus_sharing_cache == max_logical_cpus_per_package)
return 1;
if (cpuid_get_max_func() >= 0xb) {
res = cpuid_ext(0xb, 1);
number_of_cpus_per_package = res.ebx & 0xff;
} else {
number_of_cpus_per_package = max_logical_cpus_per_package;
}
return number_of_cpus_per_package / max_logical_cpus_sharing_cache;
}
static int smbios_write_type1(unsigned long *current, int handle) static int smbios_write_type1(unsigned long *current, int handle)
{ {
struct smbios_type1 *t = (struct smbios_type1 *)*current; struct smbios_type1 *t = (struct smbios_type1 *)*current;
@ -662,7 +707,6 @@ static int smbios_write_type7(unsigned long *current,
{ {
struct smbios_type7 *t = (struct smbios_type7 *)*current; struct smbios_type7 *t = (struct smbios_type7 *)*current;
int len = sizeof(struct smbios_type7); int len = sizeof(struct smbios_type7);
static unsigned int cnt = 0;
char buf[8]; char buf[8];
memset(t, 0, sizeof(struct smbios_type7)); memset(t, 0, sizeof(struct smbios_type7));
@ -670,13 +714,13 @@ static int smbios_write_type7(unsigned long *current,
t->handle = handle; t->handle = handle;
t->length = len - 2; 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->socket_designation = smbios_add_string(t->eos, buf);
t->cache_configuration = SMBIOS_CACHE_CONF_LEVEL(level) | t->cache_configuration = SMBIOS_CACHE_CONF_LEVEL(level) |
SMBIOS_CACHE_CONF_LOCATION(0) | /* Internal */ SMBIOS_CACHE_CONF_LOCATION(0) | /* Internal */
SMBIOS_CACHE_CONF_ENABLED(1) | /* Enabled */ 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)) { if (max_cache_size < (SMBIOS_CACHE_SIZE_MASK * KiB)) {
t->max_cache_size = max_cache_size / KiB; t->max_cache_size = max_cache_size / KiB;
@ -716,7 +760,7 @@ static int smbios_write_type7(unsigned long *current,
t->supported_sram_type = sram_type; t->supported_sram_type = sram_type;
t->current_sram_type = sram_type; t->current_sram_type = sram_type;
t->cache_speed = 0; /* Unknown */ t->cache_speed = 0; /* Unknown */
t->error_correction_type = SMBIOS_CACHE_ERROR_CORRECTION_UNKNOWN; t->error_correction_type = smbios_cache_error_correction_type(level);
t->system_cache_type = type; t->system_cache_type = type;
len = t->length + smbios_string_table_len(t->eos); len = t->length + smbios_string_table_len(t->eos);
@ -811,7 +855,8 @@ static int smbios_write_type7_cache_parameters(unsigned long *current,
const size_t partitions = CPUID_CACHE_PHYS_LINE(res) + 1; 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 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 number_of_sets = CPUID_CACHE_NO_OF_SETS(res) + 1;
const size_t cache_size = assoc * partitions * cache_line_size * number_of_sets; const size_t cache_size = assoc * partitions * cache_line_size * number_of_sets
* get_number_of_caches(res);
if (!cache_type) if (!cache_type)
/* No more caches in the system */ /* No more caches in the system */
@ -840,7 +885,7 @@ static int smbios_write_type7_cache_parameters(unsigned long *current,
const int h = (*handle)++; const int h = (*handle)++;
update_max(len, *max_struct_size, smbios_write_type7(current, h, 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)); type, cache_size, cache_size));
if (type4) { if (type4) {

View File

@ -61,6 +61,10 @@ unsigned int smbios_processor_characteristics(void);
struct cpuid_result; struct cpuid_result;
unsigned int smbios_processor_family(struct cpuid_result res); unsigned int smbios_processor_family(struct cpuid_result res);
unsigned int smbios_cache_error_correction_type(u8 level);
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 */ /* Used by mainboard to add port information of type 8 */
struct port_information; struct port_information;
int smbios_write_type8(unsigned long *current, int *handle, int smbios_write_type8(unsigned long *current, int *handle,
@ -501,6 +505,13 @@ enum smbios_cache_associativity {
#define SMBIOS_CACHE_SIZE2_UNIT_64KB (1UL << 31) #define SMBIOS_CACHE_SIZE2_UNIT_64KB (1UL << 31)
#define SMBIOS_CACHE_SIZE2_MASK 0x7fffffff #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 { struct smbios_type7 {
u8 type; u8 type;
u8 length; u8 length;