soc/intel/alderlake: Add method to determine the cpu type

set_cpu_type(): It determines the CPU type (big or small) that
is executing the function, and marks the global_cpu_type's array slot
which is corresponds to the executing CPU's index if the CPU type is
big core.

get_cpu_index(): It determines the index from LAPIC Ids. This is
required to expose CPPC3 package in ascending order of CPUs' LAPIC ids.
So, the function returns CPU's position from the ascending order list
of LAPIC ids.

TEST=Tested CPU index calculation, core type determination on Brya

Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Change-Id: If4ceb24d9bb1e808750bf618c29b2b9ea6d4191b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59360
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
Sridahr Siricilla 2021-11-11 01:29:40 +05:30 committed by Felix Held
parent cdd0252028
commit cd1cd8d117
4 changed files with 82 additions and 0 deletions

View File

@ -44,4 +44,9 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_CPPC
help
Generate CPPC entries for Intel SpeedShift
config SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID
bool
help
Defines hybrid CPU specific ACPI helper functions.
endif

View File

@ -5,3 +5,4 @@ ramstage-$(CONFIG_ACPI_BERT) += acpi_bert.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE) += acpi_wake_source.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_PEP) += pep.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_ENABLE) += sgx.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID) += cpu_hybrid.c

View File

@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <acpi/acpigen.h>
#include <intelblocks/acpi.h>
#include <soc/cpu.h>
#include <smp/spinlock.h>
#include <device/device.h>
#include <device/path.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/mp.h>
DECLARE_SPIN_LOCK(cpu_lock);
static u8 global_cpu_type[CONFIG_MAX_CPUS];
static bool is_big_core(void)
{
return get_soc_cpu_type() == CPUID_CORE_TYPE_INTEL_CORE;
}
static u32 get_cpu_index(void)
{
u32 cpu_index = 0;
struct device *dev;
u32 my_apic_id = lapicid();
for (dev = dev_find_lapic(0); dev; dev = dev->next) {
if (my_apic_id > dev->path.apic.apic_id)
cpu_index++;
}
return cpu_index;
}
/*
* This function determines the type (big or small) of the CPU that is executing
* it and stores the information (in a thread-safe manner) in an global_cpu_type
* array.
* It requires the SoC to implement a function `get_soc_cpu_type()` which will be
* called in a critical section to determine the type of the executing CPU.
*/
static void set_cpu_type(void *unused)
{
spin_lock(&cpu_lock);
u8 cpu_index = get_cpu_index();
if (is_big_core())
global_cpu_type[cpu_index] = 1;
spin_unlock(&cpu_lock);
}
static void run_set_cpu_type(void *unused)
{
if (mp_run_on_all_cpus(set_cpu_type, NULL) != CB_SUCCESS) {
printk(BIOS_ERR, "cpu_hybrid: Failed to set global_cpu_type with CPU type info\n");
return;
}
}
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, run_set_cpu_type, NULL);

View File

@ -9,6 +9,15 @@
#include <soc/pm.h>
#include <stdint.h>
/* CPU Types */
enum core_type {
CPUID_RESERVED_1 = 0x10,
CPUID_CORE_TYPE_INTEL_ATOM = 0x20,
CPUID_RESERVED_2 = 0x30,
CPUID_CORE_TYPE_INTEL_CORE = 0x40,
CPUID_UNKNOWN = 0xff,
};
/* Forward declare the power state struct here */
struct chipset_power_state;
@ -108,4 +117,12 @@ void generate_acpi_power_engine_with_lpm(const struct soc_pmc_lpm *lpm);
/* Fill SSDT for SGX status, EPC base and length */
void sgx_fill_ssdt(void);
/*
* This function returns the CPU type (big or small) of the CPU that it is executing
* on. It is designed to be called after MP initialization. If the SoC selects
* SOC_INTEL_COMMON_BLOCK_ACPI_CPU_HYBRID, then this function must be implemented,
* and will be called from set_cpu_type().
*/
enum core_type get_soc_cpu_type(void);
#endif /* _SOC_INTEL_COMMON_BLOCK_ACPI_H_ */