diff options
author | Jonathan Zhang <jonzhang@fb.com> | 2020-04-02 20:03:48 -0700 |
---|---|---|
committer | Philipp Deppenwiese <zaolin.daisuki@gmail.com> | 2020-06-06 07:44:07 +0000 |
commit | b7cf7d36d7cf97b0cce437b9f1577ca39eeb312d (patch) | |
tree | d1df2f10fbaf6a582db3c9a8cbd2da5f14f7e09e /src/soc/intel/xeon_sp/cpx/cpu.c | |
parent | eaa219b5bba95cfdc03b9b20d1c06d84bd33c702 (diff) |
soc/intel/xeon_sp/cpx: set up cpus
Set up cpus:
* setup apic IDs.
* setup MSR to enable fast string, speed step, etc.
* Enable turbo
Signed-off-by: Jonathan Zhang <jonzhang@fb.com>
Signed-off-by: Reddy Chagam <anjaneya.chagam@intel.com>
Change-Id: I5765e98151f6ceebaabccc06db63d5911caf7ce8
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40112
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'src/soc/intel/xeon_sp/cpx/cpu.c')
-rw-r--r-- | src/soc/intel/xeon_sp/cpx/cpu.c | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index 1c33218d76..e2724cef90 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -2,18 +2,49 @@ #include <acpi/acpigen.h> #include <acpi/acpi.h> +#include <assert.h> #include <console/console.h> #include <cpu/cpu.h> #include <cpu/intel/microcode.h> +#include <cpu/intel/turbo.h> #include <cpu/x86/lapic.h> #include <cpu/x86/mp.h> #include <cpu/x86/mtrr.h> #include <intelblocks/cpulib.h> #include <intelblocks/mp_init.h> #include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/soc_util.h> +#include "chip.h" static const void *microcode_patch; +static const config_t *chip_config = NULL; + +static void xeon_configure_mca(void) +{ + msr_t msr; + struct cpuid_result cpuid_regs; + + /* + * Check feature flag in CPUID.(EAX=1):EDX[7]==1 MCE + * and CPUID.(EAX=1):EDX[14]==1 MCA + */ + cpuid_regs = cpuid(1); + if ((cpuid_regs.edx & (1 << 7 | 1 << 14)) != (1 << 7 | 1 << 14)) + return; + + msr = rdmsr(IA32_MCG_CAP); + if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) { + /* Enable all error logging */ + msr.lo = msr.hi = 0xffffffff; + wrmsr(IA32_MCG_CTL, msr); + } + + mca_configure(); +} + + void get_microcode_info(const void **microcode, int *parallel) { *microcode = intel_mp_current_microcode(); @@ -27,10 +58,28 @@ const void *intel_mp_current_microcode(void) static void each_cpu_init(struct device *cpu) { + msr_t msr; + printk(BIOS_SPEW, "%s dev: %s, cpu: %d, apic_id: 0x%x\n", __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id); - setup_lapic(); + + /* Enable Fast Strings */ + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= FAST_STRINGS_ENABLE_BIT; + wrmsr(IA32_MISC_ENABLE, msr); + /* Enable Turbo */ + enable_turbo(); + + /* Enable speed step. */ + if (get_turbo_state() == TURBO_ENABLED) { + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= SPEED_STEP_ENABLE_BIT; + wrmsr(IA32_MISC_ENABLE, msr); + } + + /* Clear out pending MCEs */ + xeon_configure_mca(); } static struct device_operations cpu_dev_ops = { @@ -47,6 +96,33 @@ static const struct cpu_driver driver __cpu_driver = { .id_table = cpu_table, }; +static void set_max_turbo_freq(void) +{ + msr_t msr, perf_ctl; + + FUNC_ENTER(); + perf_ctl.hi = 0; + + /* Check for configurable TDP option */ + if (get_turbo_state() == TURBO_ENABLED) { + msr = rdmsr(MSR_TURBO_RATIO_LIMIT); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else if (cpu_config_tdp_levels()) { + /* Set to nominal TDP ratio */ + msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = rdmsr(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + wrmsr(IA32_PERF_CTL, perf_ctl); + + printk(BIOS_DEBUG, "cpu: frequency set to %d\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); + FUNC_EXIT(); +} + /* * Do essential initialization tasks before APs can be fired up */ @@ -72,10 +148,17 @@ static int get_thread_count(void) return num_virts * CONFIG_MAX_SOCKET; } +static void post_mp_init(void) +{ + /* Set Max Ratio */ + set_max_turbo_freq(); +} + static const struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_thread_count, - .get_microcode_info = get_microcode_info + .get_microcode_info = get_microcode_info, + .post_mp_init = post_mp_init, }; void cpx_init_cpus(struct device *dev) @@ -89,4 +172,13 @@ void cpx_init_cpus(struct device *dev) if (mp_init_with_smm(dev->link_list, &mp_ops) < 0) printk(BIOS_ERR, "MP initialization failure.\n"); + + /* + * chip_config is used in cpu device callback. Other than cpu 0, + * rest of the CPU devices do not have chip_info updated. + */ + chip_config = dev->chip_info; + + /* update numa domain for all cpu devices */ + xeonsp_init_cpu_config(); } |