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:
Naresh Solanki 2025-03-24 17:45:07 +05:30 committed by Matt DeVillier
commit fb2d62dbd0

View file

@ -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();
}