diff options
Diffstat (limited to 'src/soc/intel/common/block/acpi')
-rw-r--r-- | src/soc/intel/common/block/acpi/Kconfig | 5 | ||||
-rw-r--r-- | src/soc/intel/common/block/acpi/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/acpi/cpu_hybrid.c | 59 |
3 files changed, 65 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/acpi/Kconfig b/src/soc/intel/common/block/acpi/Kconfig index 07e9bea8d3..e21584c073 100644 --- a/src/soc/intel/common/block/acpi/Kconfig +++ b/src/soc/intel/common/block/acpi/Kconfig @@ -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 diff --git a/src/soc/intel/common/block/acpi/Makefile.inc b/src/soc/intel/common/block/acpi/Makefile.inc index a6eb80db36..0286d942dc 100644 --- a/src/soc/intel/common/block/acpi/Makefile.inc +++ b/src/soc/intel/common/block/acpi/Makefile.inc @@ -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 diff --git a/src/soc/intel/common/block/acpi/cpu_hybrid.c b/src/soc/intel/common/block/acpi/cpu_hybrid.c new file mode 100644 index 0000000000..cbfaed8fd3 --- /dev/null +++ b/src/soc/intel/common/block/acpi/cpu_hybrid.c @@ -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); |