soc/amd/common/cpu/noncar: Compute core info boost freq & L3 cache
On SoCs like Glinda, CPU cores may exhibit slight variations in maximum boost frequency, and the L3 cache can be composed of multiple blocks with different sizes and unique IDs. Add helper functions, 1. get_max_boost_frequency() to compute max boost frequenncy. 2. ap_stash_core_info() to update core_info struct with max boost frequency & all L3 cache block uniq ID & its size. To accurately determine the total L3 cache size: 1. Retrieve L3 cache information for each CPU core. 2. Identify the unique cache ID associated with each core. 3. Aggregate cache sizes for all unique cache IDs to compute the total L3 cache size, ensuring correct summation when L3 cache blocks have different sizes. TEST=Build for Glinda SoC, with L3 cache = 16MB + 8MB. Ran command 'dmidecode -t 7' & verified L3 cache is 24MB(Previously it was wrongly reported as 32MB). Change-Id: I46947e8ac62c903036a81642e03201e353c3dac6 Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/85640 Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
051fdff0e8
commit
fb2d62dbd0
1 changed files with 39 additions and 0 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include <cpu/amd/microcode.h>
|
||||
#include <cpu/amd/msr.h>
|
||||
#include <cpu/amd/mtrr.h>
|
||||
#include <lib.h>
|
||||
#include <smbios.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/msr.h>
|
||||
|
|
@ -18,6 +19,17 @@
|
|||
|
||||
#define UNINITIALIZED ((uint64_t)-1)
|
||||
|
||||
struct core_info {
|
||||
/* Core max boost frequency */
|
||||
uint32_t max_frequency;
|
||||
|
||||
/* L3 Cache block unique ID & size (in bytes) */
|
||||
uint16_t l3_cache_uid;
|
||||
size_t l3_cache_size;
|
||||
};
|
||||
|
||||
static struct core_info core_info_list[CONFIG_MAX_CPUS];
|
||||
|
||||
static union pstate_msr get_pstate0_msr(void)
|
||||
{
|
||||
static union pstate_msr pstate_reg = { .raw = UNINITIALIZED };
|
||||
|
|
@ -103,6 +115,30 @@ unsigned int get_reserved_phys_addr_bits(void)
|
|||
CPUID_EBX_MEM_ENCRYPT_ADDR_BITS_SHIFT;
|
||||
}
|
||||
|
||||
static uint32_t get_max_boost_frequency(void)
|
||||
{
|
||||
msr_t msr = rdmsr(MSR_CPPC_CAPABILITY_1);
|
||||
uint16_t nominal_perf = (msr.lo >> SHIFT_CPPC_CAPABILITY_1_NOMINAL_PERF) & 0xff;
|
||||
uint16_t max_perf = (msr.lo >> SHIFT_CPPC_CAPABILITY_1_HIGHEST_PERF) & 0xff;
|
||||
|
||||
return (smbios_cpu_get_current_speed_mhz() * max_perf)/nominal_perf;
|
||||
}
|
||||
|
||||
static void ap_stash_core_info(void)
|
||||
{
|
||||
unsigned int cpuid_cpu_id = cpuid_ebx(CPUID_EBX_CORE_ID) & 0xff;
|
||||
|
||||
const uint8_t level = CACHE_L3;
|
||||
struct cpu_cache_info info;
|
||||
x86_get_cpu_cache_info(level, &info);
|
||||
|
||||
struct core_info *core_info = &core_info_list[cpu_index()];
|
||||
core_info->l3_cache_uid = cpuid_cpu_id >> log2(info.num_cores_shared);
|
||||
core_info->l3_cache_size = info.size;
|
||||
|
||||
core_info->max_frequency = get_max_boost_frequency();
|
||||
}
|
||||
|
||||
void amd_cpu_init(struct device *dev)
|
||||
{
|
||||
if (CONFIG(SOC_AMD_COMMON_BLOCK_MCA_COMMON))
|
||||
|
|
@ -112,4 +148,7 @@ void amd_cpu_init(struct device *dev)
|
|||
|
||||
if (CONFIG(SOC_AMD_COMMON_BLOCK_UCODE))
|
||||
amd_apply_microcode_patch();
|
||||
|
||||
if (CONFIG(SOC_FILL_CPU_CACHE_INFO))
|
||||
ap_stash_core_info();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue