intel/common/block/cpu: Add APIs to get CPU info from lapic ID

Add support to get core, package and thread ID from lapic ID.
Implementation uses CPUID extended topology instruction to derive
bit offsets for core, package and thread info in apic ID.

BUG=b:179113790

Change-Id: If26d34d4250f5a88bdafacdd5d56b8882b69409e
Signed-off-by: Aamir Bohra <aamir.bohra@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50913
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: EricR Lai <ericr_lai@compal.corp-partner.google.com>
This commit is contained in:
Aamir Bohra 2021-02-19 16:18:07 +05:30 committed by Furquan Shaikh
parent c92c5e5450
commit d192590e29
2 changed files with 73 additions and 0 deletions

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <acpi/acpigen.h> #include <acpi/acpigen.h>
#include <console/console.h> #include <console/console.h>
#include <cpu/intel/turbo.h> #include <cpu/intel/turbo.h>
@ -12,6 +13,24 @@
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
#include <types.h> #include <types.h>
#define CPUID_EXTENDED_CPU_TOPOLOGY 0x0b
#define CPUID_EXTENDED_CPU_TOPOLOGY_V2 0x1f
#define LEVEL_TYPE_CORE 2
#define LEVEL_TYPE_SMT 1
#define CPUID_CPU_TOPOLOGY(x, val) \
(((val) >> CPUID_CPU_TOPOLOGY_##x##_SHIFT) & CPUID_CPU_TOPOLOGY_##x##_MASK)
#define CPUID_CPU_TOPOLOGY_LEVEL_TYPE_SHIFT 0x8
#define CPUID_CPU_TOPOLOGY_LEVEL_TYPE_MASK 0xff
#define CPUID_CPU_TOPOLOGY_LEVEL(res) CPUID_CPU_TOPOLOGY(LEVEL_TYPE, (res).ecx)
#define CPUID_CPU_TOPOLOGY_LEVEL_BITS_SHIFT 0x0
#define CPUID_CPU_TOPOLOGY_LEVEL_BITS_MASK 0x1f
#define CPUID_CPU_TOPOLOGY_THREAD_BITS(res) CPUID_CPU_TOPOLOGY(LEVEL_BITS, (res).eax)
#define CPUID_CPU_TOPOLOGY_CORE_BITS(res, threadbits) \
((CPUID_CPU_TOPOLOGY(LEVEL_BITS, (res).eax)) - threadbits)
/* /*
* Set PERF_CTL MSR (0x199) P_Req with * Set PERF_CTL MSR (0x199) P_Req with
* Turbo Ratio which is the Maximum Ratio. * Turbo Ratio which is the Maximum Ratio.
@ -380,3 +399,53 @@ int get_valid_prmrr_size(void)
return valid_size; return valid_size;
} }
/* Get number of bits for core ID and SMT ID */
static void get_cpu_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits)
{
struct cpuid_result cpuid_regs;
int level_num, cpu_id_op = 0;
const uint32_t cpuid_max_func = cpuid_get_max_func();
/* Assert if extended CPU topology not supported */
assert(cpuid_max_func >= CPUID_EXTENDED_CPU_TOPOLOGY);
/* Check for extended CPU topology CPUID support */
if (cpuid_max_func >= CPUID_EXTENDED_CPU_TOPOLOGY_V2)
cpu_id_op = CPUID_EXTENDED_CPU_TOPOLOGY_V2;
else if (cpuid_max_func >= CPUID_EXTENDED_CPU_TOPOLOGY)
cpu_id_op = CPUID_EXTENDED_CPU_TOPOLOGY;
*core_bits = level_num = 0;
cpuid_regs = cpuid_ext(cpu_id_op, level_num);
/* Sub-leaf index 0 enumerates SMT level, if not assert */
assert(CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs) == LEVEL_TYPE_SMT);
*thread_bits = CPUID_CPU_TOPOLOGY_THREAD_BITS(cpuid_regs);
do {
level_num++;
cpuid_regs = cpuid_ext(cpu_id_op, level_num);
if (CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs) == LEVEL_TYPE_CORE) {
*core_bits = CPUID_CPU_TOPOLOGY_CORE_BITS(cpuid_regs, *thread_bits);
break;
}
/* Stop when level type is invalid i.e 0 */
} while (CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs));
}
void get_cpu_topology_from_apicid(uint32_t apicid, uint8_t *package,
uint8_t *core, uint8_t *thread)
{
uint32_t core_bits, thread_bits;
get_cpu_core_thread_bits(&core_bits, &thread_bits);
if (package)
*package = apicid >> (thread_bits + core_bits);
if (core)
*core = (apicid >> thread_bits) & ((1 << core_bits) - 1);
if (thread)
*thread = apicid & ((1 << thread_bits) - 1);
}

View File

@ -162,4 +162,8 @@ int get_valid_prmrr_size(void);
*/ */
void enable_pm_timer_emulation(void); void enable_pm_timer_emulation(void);
/* Derive core, package and thread information from lapic ID */
void get_cpu_topology_from_apicid(uint32_t apicid, uint8_t *package,
uint8_t *core, uint8_t *thread);
#endif /* SOC_INTEL_COMMON_BLOCK_CPULIB_H */ #endif /* SOC_INTEL_COMMON_BLOCK_CPULIB_H */