/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool cpu_soc_is_in_untrusted_mode(void) { msr_t msr; msr = rdmsr(MSR_BIOS_DONE); return !!(msr.lo & ENABLE_IA_UNTRUSTED); } void cpu_soc_bios_done(void) { msr_t msr; msr = rdmsr(MSR_BIOS_DONE); msr.lo |= ENABLE_IA_UNTRUSTED; wrmsr(MSR_BIOS_DONE, msr); } uint8_t get_supported_lpm_mask(void) { return LPM_S0i2_0 | LPM_S0i2_1 | LPM_S0i2_2; } static void soc_fsp_load(void) { fsps_load(); } static void configure_misc(void) { msr_t msr; config_t *conf = (config_t *)config_of_soc(); msr = rdmsr(IA32_MISC_ENABLE); msr.lo |= (1 << 0); /* Fast String enable */ msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ wrmsr(IA32_MISC_ENABLE, msr); /* Set EIST status */ cpu_set_eist(conf->eist_enable); /* Disable Thermal interrupts */ msr.lo = 0; msr.hi = 0; wrmsr(IA32_THERM_INTERRUPT, msr); /* Enable package critical interrupt only */ msr.lo = 1 << 4; msr.hi = 0; wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr); /* Enable PROCHOT and Power Performance Platform Override */ msr = rdmsr(MSR_POWER_CTL); msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input*/ msr.lo |= (1 << 23); /* Lock it */ msr.lo |= (1 << 18); /* Power Performance Platform Override */ wrmsr(MSR_POWER_CTL, msr); } enum core_type get_soc_cpu_type(void) { if (cpu_is_hybrid_supported()) return cpu_get_cpu_type(); else return CPUID_CORE_TYPE_INTEL_CORE; } bool soc_is_nominal_freq_supported(void) { return true; } static void enable_x2apic(void) { if (!CONFIG(X2APIC_LATE_WORKAROUND)) return; enable_lapic_mode(true); } /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { /* Clear out pending MCEs */ /* TODO(adurbin): This should only be done on a cold boot. Also, some * of these banks are core vs package scope. For now every CPU clears * every bank. */ mca_configure(); enable_x2apic(); enable_lapic_tpr(); /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); enable_pm_timer_emulation(); /* Enable Direct Cache Access */ configure_dca_cap(); /* Set energy policy */ set_energy_perf_bias(ENERGY_POLICY_NORMAL); const config_t *conf = config_of_soc(); /* Set energy-performance preference */ if (conf->enable_energy_perf_pref) if (check_energy_perf_cap()) set_energy_perf_pref(conf->energy_perf_pref_value); /* Enable Turbo */ enable_turbo(); /* Set core type in struct cpu_info */ set_dev_core_type(); if (CONFIG(INTEL_TME) && is_tme_supported()) set_tme_core_activate(); if (CONFIG(DROP_CPU_FEATURE_PROGRAM_IN_FSP)) { /* Disable 3-strike error */ if (CONFIG(SOC_INTEL_METEORLAKE_PRE_PRODUCTION_SILICON)) disable_three_strike_error(); else disable_signaling_three_strike_event(); set_aesni_lock(); /* Enable VMX */ set_feature_ctrl_vmx_arg(CONFIG(ENABLE_VMX) && !conf->disable_vmx); /* Feature control lock configure */ set_feature_ctrl_lock(); } } static void per_cpu_smm_trigger(void) { /* Relocate the SMM handler. */ smm_relocate(); } static void pre_mp_init(void) { soc_fsp_load(); const config_t *conf = config_of_soc(); if (conf->enable_energy_perf_pref) { if (check_energy_perf_cap()) enable_energy_perf_pref(); else printk(BIOS_WARNING, "Energy Performance Preference not supported!\n"); } } static void post_mp_init(void) { /* Set Max Ratio */ cpu_set_max_ratio(); /* * 1. Now that all APs have been relocated as well as the BSP let SMIs * start flowing. * 2. Skip enabling power button SMI and enable it after BS_CHIPS_INIT * to avoid shutdown hang due to lack of init on certain IP in FSP-S. */ global_smi_enable_no_pwrbtn(); } static const struct mp_ops mp_ops = { /* * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP, * that are set prior to ramstage. * Real MTRRs programming are being done after resource allocation. */ .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, .get_smm_info = smm_info, .get_microcode_info = get_microcode_info, .pre_mp_smm_init = smm_initialize, .per_cpu_smm_trigger = per_cpu_smm_trigger, .relocation_handler = smm_relocation_handler, .post_mp_init = post_mp_init, }; void mp_init_cpus(struct bus *cpu_bus) { if (mp_init_with_smm(cpu_bus, &mp_ops)) printk(BIOS_ERR, "MP initialization failure.\n"); /* Thermal throttle activation offset */ configure_tcc_thermal_target(); } int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id) { if (!CONFIG(CHROMEOS)) return 0; /* * Locked RO Descriptor Implications: * * - A locked descriptor signals the RO binary is fixed; the FIT will load the * RO's microcode during system reset. * - Attempts to load newer microcode from the RW CBFS will cause a boot-time * delay (~60ms, core-dependent), as the microcode must be reloaded on BSP+APs. * - The kernel can load microcode updates without impacting AP FW boot time. * - Skipping RW CBFS microcode loading is low-risk when the RO is locked, * prioritizing fast boot times. */ if (CONFIG(LOCK_MANAGEMENT_ENGINE) && current_patch_id) return 1; return 0; }