blob: 2ed8e2290ab3223da455a399527111aed80351f3 [file] [log] [blame]
Jonathan Zhang3ed903f2023-01-25 11:37:27 -08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpigen.h>
4#include <acpi/acpi.h>
5#include <console/console.h>
6#include <console/debug.h>
7#include <cpu/cpu.h>
8#include <cpu/intel/cpu_ids.h>
9#include <cpu/intel/common/common.h>
10#include <cpu/intel/em64t101_save_state.h>
11#include <cpu/intel/microcode.h>
12#include <cpu/intel/smm_reloc.h>
13#include <cpu/intel/turbo.h>
14#include <cpu/x86/lapic.h>
15#include <cpu/x86/mp.h>
16#include <cpu/x86/mtrr.h>
17#include <device/pci_mmio_cfg.h>
18#include <intelblocks/cpulib.h>
19#include <intelblocks/mp_init.h>
20#include <intelpch/lockdown.h>
21#include <soc/msr.h>
22#include <soc/pci_devs.h>
23#include <soc/pm.h>
24#include <soc/soc_util.h>
25#include <soc/smmrelocate.h>
26#include <soc/util.h>
27
28#include "chip.h"
29
30static const void *microcode_patch;
31
32static const config_t *chip_config = NULL;
33
34bool cpu_soc_is_in_untrusted_mode(void)
35{
36 return false;
37}
38
39void cpu_soc_bios_done(void)
40{
41}
42
43static void xeon_configure_mca(void)
44{
45 msr_t msr;
46 struct cpuid_result cpuid_regs;
47
48 /*
49 * Check feature flag in CPUID.(EAX=1):EDX[7]==1 MCE
50 * and CPUID.(EAX=1):EDX[14]==1 MCA
51 */
52 cpuid_regs = cpuid(1);
53 if ((cpuid_regs.edx & (1 << 7 | 1 << 14)) != (1 << 7 | 1 << 14))
54 return;
55
56 msr = rdmsr(IA32_MCG_CAP);
57 if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) {
58 /* Enable all error logging */
59 msr.lo = msr.hi = 0xffffffff;
60 wrmsr(IA32_MCG_CTL, msr);
61 }
62
63 mca_configure();
64}
65
66/*
67 * On server platforms the FIT mechanism only updates the microcode on
68 * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases
69 * so do it serialized.
70 */
71void get_microcode_info(const void **microcode, int *parallel)
72{
73 *microcode = intel_microcode_find();
74 *parallel = 0;
75}
76
77static void each_cpu_init(struct device *cpu)
78{
79 msr_t msr;
80
Lean Sheng Tand33cbf12023-04-14 14:19:19 +020081 printk(BIOS_SPEW, "%s dev: %s, cpu: %lu, apic_id: 0x%x, package_id: 0x%x\n",
82 __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id,
83 cpu->path.apic.package_id);
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080084
85 /*
86 * Enable PWR_PERF_PLTFRM_OVR and PROCHOT_LOCK.
87 * The value set by FSP is 20_005f, we set it to 1a_00a4_005b.
88 */
89 msr = rdmsr(MSR_POWER_CTL);
90 msr.lo |= (0x16 << RESERVED1_SHIFT) | PWR_PERF_PLTFRM_OVR | PROCHOT_LOCK;
91 msr.hi = 0x1a;
92 wrmsr(MSR_POWER_CTL, msr);
93
94 /* Set static, idle, dynamic load line impedance */
95 msr = rdmsr(MSR_VR_MISC_CONFIG);
96 msr.lo = 0x1a1a1a;
97 wrmsr(MSR_VR_MISC_CONFIG, msr);
98
99 /* Set current limitation */
100 msr = rdmsr(MSR_VR_CURRENT_CONFIG);
101 msr.lo = 0x1130;
102 msr.lo |= CURRENT_LIMIT_LOCK;
103 wrmsr(MSR_VR_CURRENT_CONFIG, msr);
104
105 /* Set Turbo Ratio Limits */
106 msr.lo = chip_config->turbo_ratio_limit & 0xffffffff;
107 msr.hi = (chip_config->turbo_ratio_limit >> 32) & 0xffffffff;
108 wrmsr(MSR_TURBO_RATIO_LIMIT, msr);
109
110 /* Set Turbo Ratio Limit Cores */
111 msr.lo = chip_config->turbo_ratio_limit_cores & 0xffffffff;
112 msr.hi = (chip_config->turbo_ratio_limit_cores >> 32) & 0xffffffff;
113 wrmsr(MSR_TURBO_RATIO_LIMIT_CORES, msr);
114
115 /* Set energy policy */
116 msr = rdmsr(MSR_ENERGY_PERF_BIAS_CONFIG);
117 msr.lo = 0x178fa038;
118 wrmsr(MSR_ENERGY_PERF_BIAS_CONFIG, msr);
119
120 msr.hi = 0x158d20;
121 msr.lo = 0x00158af0;
122 wrmsr(PACKAGE_RAPL_LIMIT, msr);
123
124 /*
125 * Set HWP base feature, EPP reg enumeration, lock thermal and msr
126 * This is package level MSR. Need to check if it updates correctly on
127 * multi-socket platform.
128 */
129 msr = rdmsr(MSR_MISC_PWR_MGMT);
130 if (!(msr.lo & LOCK_MISC_PWR_MGMT_MSR)) { /* if already locked skip update */
131 msr.lo = (HWP_ENUM_ENABLE | HWP_EPP_ENUM_ENABLE | LOCK_MISC_PWR_MGMT_MSR
132 | LOCK_THERM_INT);
133 wrmsr(MSR_MISC_PWR_MGMT, msr);
134 }
135
136 /* Enable Fast Strings */
137 msr = rdmsr(IA32_MISC_ENABLE);
138 msr.lo |= FAST_STRINGS_ENABLE_BIT;
139 wrmsr(IA32_MISC_ENABLE, msr);
140 /* Enable Turbo */
141 enable_turbo();
142
143 /* Enable speed step. */
144 if (get_turbo_state() == TURBO_ENABLED) {
145 msr = rdmsr(IA32_MISC_ENABLE);
146 msr.lo |= SPEED_STEP_ENABLE_BIT;
147 wrmsr(IA32_MISC_ENABLE, msr);
148 }
149
150 /* Lock the supported Cstates */
151 msr = rdmsr(MSR_PKG_CST_CONFIG_CONTROL);
152 msr.lo |= CST_CFG_LOCK_MASK;
153 wrmsr(MSR_PKG_CST_CONFIG_CONTROL, msr);
154
155 /* Disable all writes to overclocking limits MSR */
156 msr = rdmsr(MSR_FLEX_RATIO);
157 msr.lo |= MSR_FLEX_RATIO_OC_LOCK;
158 wrmsr(MSR_FLEX_RATIO, msr);
159
160 /* Lock Power Plane Limit MSR */
161 msr = rdmsr(MSR_DRAM_PLANE_POWER_LIMIT);
162 msr.hi |= MSR_HI_PP_PWR_LIM_LOCK;
163 wrmsr(MSR_DRAM_PLANE_POWER_LIMIT, msr);
164
165 /* Clear out pending MCEs */
166 xeon_configure_mca();
167
168 /* Enable Vmx */
169 // set_vmx_and_lock();
170 /* only lock. let vmx enable by FSP */
171 set_feature_ctrl_lock();
172}
173
174static struct device_operations cpu_dev_ops = {
175 .init = each_cpu_init,
176};
177
178static const struct cpu_device_id cpu_table[] = {
Felix Held75613602023-03-20 22:22:54 +0100179 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_D, CPUID_EXACT_MATCH_MASK},
180 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E0, CPUID_EXACT_MATCH_MASK},
181 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E2, CPUID_EXACT_MATCH_MASK},
182 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E3, CPUID_EXACT_MATCH_MASK},
183 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E4, CPUID_EXACT_MATCH_MASK},
184 {X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_Ex, CPUID_EXACT_MATCH_MASK},
185 CPU_TABLE_END
Jonathan Zhang3ed903f2023-01-25 11:37:27 -0800186};
187
188static const struct cpu_driver driver __cpu_driver = {
189 .ops = &cpu_dev_ops,
190 .id_table = cpu_table,
191};
192
193static void set_max_turbo_freq(void)
194{
195 msr_t msr, perf_ctl;
196
197 FUNC_ENTER();
198 perf_ctl.hi = 0;
199
200 /* Check for configurable TDP option */
201 if (get_turbo_state() == TURBO_ENABLED) {
202 msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
203 perf_ctl.lo = (msr.lo & 0xff) << 8;
204 } else if (cpu_config_tdp_levels()) {
205 /* Set to nominal TDP ratio */
206 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
207 perf_ctl.lo = (msr.lo & 0xff) << 8;
208 } else {
209 /* Platform Info bits 15:8 give max ratio */
210 msr = rdmsr(MSR_PLATFORM_INFO);
211 perf_ctl.lo = msr.lo & 0xff00;
212 }
213 wrmsr(IA32_PERF_CTL, perf_ctl);
214
215 printk(BIOS_DEBUG, "cpu: frequency set to %d\n",
216 ((perf_ctl.lo >> 8) & 0xff) * CONFIG_CPU_BCLK_MHZ);
217 FUNC_EXIT();
218}
219
220/*
221 * Do essential initialization tasks before APs can be fired up
222 */
223static void pre_mp_init(void)
224{
225 x86_setup_mtrrs_with_detect();
226 x86_mtrr_check();
227}
228
229static int get_thread_count(void)
230{
231 unsigned int num_phys = 0, num_virts = 0;
232
233 cpu_read_topology(&num_phys, &num_virts);
234 printk(BIOS_SPEW, "Detected %u cores and %u threads\n", num_phys, num_virts);
235 return num_virts * soc_get_num_cpus();
236}
237
238static void post_mp_init(void)
239{
240 /* Set Max Ratio */
241 set_max_turbo_freq();
242
243 if (CONFIG(HAVE_SMI_HANDLER)) {
244 global_smi_enable();
245 if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT)
246 pmc_lock_smi();
247 }
248}
249
250static const struct mp_ops mp_ops = {
251 .pre_mp_init = pre_mp_init,
252 .get_cpu_count = get_thread_count,
253#if CONFIG(HAVE_SMI_HANDLER)
254 .get_smm_info = get_smm_info,
255 .pre_mp_smm_init = smm_southbridge_clear_state,
256 .relocation_handler = smm_relocation_handler,
257#endif
258 .get_microcode_info = get_microcode_info,
259 .post_mp_init = post_mp_init,
260};
261
262void mp_init_cpus(struct bus *bus)
263{
264 /*
265 * chip_config is used in cpu device callback. Other than cpu 0,
266 * rest of the CPU devices do not have chip_info updated.
267 */
268 chip_config = bus->dev->chip_info;
269
270 microcode_patch = intel_microcode_find();
271
272 if (!microcode_patch)
273 printk(BIOS_ERR, "microcode not found in CBFS!\n");
274
275 intel_microcode_load_unlocked(microcode_patch);
276
277 if (mp_init_with_smm(bus, &mp_ops) < 0)
278 printk(BIOS_ERR, "MP initialization failure.\n");
Jonathan Zhang3ed903f2023-01-25 11:37:27 -0800279}