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:
parent
8ccc8fdf26
commit
8ae391d199
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue