diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/apollolake/Kconfig | 21 | ||||
-rw-r--r-- | src/soc/intel/apollolake/cpu.c | 71 |
2 files changed, 73 insertions, 19 deletions
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 49e56aa6d7..5ff328b522 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -315,6 +315,27 @@ config USE_APOLLOLAKE_FSP_CAR endchoice +choice + prompt "MPINIT code implementation" + default NO_COMMON_MPINIT if SOC_INTEL_APOLLOLAKE + default COMMON_MPINIT + help + This option allows you to select MP Init Code path either + from Intel Common Code implementation, or from SOC files. + +config NO_COMMON_MPINIT + bool "Not using Common MP Init code" + help + Common code MP Init path is not used. + +config COMMON_MPINIT + bool "Using Common MP Init code" + select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT + help + Common code MP Init path is used. + +endchoice + # # Each bit in QOS mask controls this many bytes. This is calculated as: # (CACHE_WAYS / CACHE_BITS_PER_MASK) * CACHE_LINE_SIZE * CACHE_SETS diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 22e3c80305..f81c2eef8d 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -21,20 +21,23 @@ #include <cpu/x86/cache.h> #include <cpu/x86/mp.h> #include <cpu/intel/microcode.h> +#include <cpu/intel/turbo.h> #include <cpu/x86/msr.h> #include <cpu/x86/mtrr.h> #include <device/device.h> #include <device/pci.h> +#include <fsp/api.h> #include <fsp/memmap.h> #include <intelblocks/cpulib.h> #include <intelblocks/fast_spi.h> +#include <intelblocks/mp_init.h> #include <intelblocks/msr.h> #include <intelblocks/smm.h> #include <reg_script.h> +#include <romstage_handoff.h> #include <soc/cpu.h> #include <soc/iomap.h> #include <soc/pm.h> -#include <cpu/intel/turbo.h> static const struct reg_script core_msr_script[] = { /* Enable C-state and IO/MWAIT redirect */ @@ -57,7 +60,7 @@ static const struct reg_script core_msr_script[] = { REG_SCRIPT_END }; -static void soc_core_init(device_t cpu) +void soc_core_init(device_t cpu, const void *microcode) { /* Set core MSRs */ reg_script_run(core_msr_script); @@ -69,8 +72,14 @@ static void soc_core_init(device_t cpu) enable_pm_timer_emulation(); } +#if !IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) +static void soc_init_core(device_t cpu) +{ + soc_core_init(cpu, NULL); +} + static struct device_operations cpu_dev_ops = { - .init = soc_core_init, + .init = soc_init_core, }; static struct cpu_device_id cpu_table[] = { @@ -85,6 +94,7 @@ static const struct cpu_driver driver __cpu_driver = { .ops = &cpu_dev_ops, .id_table = cpu_table, }; +#endif /* * MP and SMM loading initialization. @@ -97,29 +107,44 @@ struct smm_relocation_attrs { static struct smm_relocation_attrs relo_attrs; -static void read_cpu_topology(unsigned int *num_phys, unsigned int *num_virt) -{ - msr_t msr; - msr = rdmsr(MSR_CORE_THREAD_COUNT); - *num_virt = (msr.lo >> 0) & 0xffff; - *num_phys = (msr.lo >> 16) & 0xffff; -} - /* - * Do essential initialization tasks before APs can be fired up - + * Do essential initialization tasks before APs can be fired up. + * + * IF (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT)) - + * Skip Pre MP init MTRR programming, as MTRRs are mirrored from BSP, + * that are set prior to ramstage. + * Real MTRRs are programmed after resource allocation. * - * 1. Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This - * creates the MTRR solution that the APs will use. Otherwise APs will try to - * apply the incomplete solution as the BSP is calculating it. + * Do FSP loading before MP Init to ensure that the FSP component stored in + * external stage cache in TSEG does not flush off due to SMM relocation + * during MP Init stage. + * + * ELSE - + * Enable MTRRs on the BSP. This creates the MTRR solution that the + * APs will use. Otherwise APs will try to apply the incomplete solution + * as the BSP is calculating it. */ static void pre_mp_init(void) { + if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT)) { + fsps_load(romstage_handoff_is_resume()); + return; + } x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } +#if !IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) +static void read_cpu_topology(unsigned int *num_phys, unsigned int *num_virt) +{ + msr_t msr; + msr = rdmsr(MSR_CORE_THREAD_COUNT); + *num_virt = (msr.lo >> 0) & 0xffff; + *num_phys = (msr.lo >> 16) & 0xffff; +} + /* Find CPU topology */ -static int get_cpu_count(void) +int get_cpu_count(void) { unsigned int num_virt_cores, num_phys_cores; @@ -131,7 +156,7 @@ static int get_cpu_count(void) return num_virt_cores; } -static void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, int *parallel) { *microcode = intel_microcode_find(); *parallel = 1; @@ -139,6 +164,7 @@ static void get_microcode_info(const void **microcode, int *parallel) /* Make sure BSP is using the microcode from cbfs */ intel_microcode_load_unlocked(*microcode); } +#endif static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size) @@ -197,11 +223,18 @@ static const struct mp_ops mp_ops = { .post_mp_init = smm_southbridge_enable, }; -void apollolake_init_cpus(struct device *dev) +void soc_init_cpus(struct bus *cpu_bus, const void *microcode) { /* Clear for take-off */ - if (mp_init_with_smm(dev->link_list, &mp_ops) < 0) + if (mp_init_with_smm(cpu_bus, &mp_ops)) printk(BIOS_ERR, "MP initialization failure.\n"); +} + +void apollolake_init_cpus(struct device *dev) +{ + if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT)) + return; + soc_init_cpus(dev->link_list, NULL); /* Temporarily cache the memory-mapped boot media. */ if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED) && |