xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/cpu/cpulib.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpigen.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <cpu/cpu.h>
7 #include <cpu/intel/common/common.h>
8 #include <cpu/intel/turbo.h>
9 #include <cpu/x86/msr.h>
10 #include <cpu/x86/mtrr.h>
11 #include <intelblocks/cpulib.h>
12 #include <intelblocks/fast_spi.h>
13 #include <intelblocks/msr.h>
14 #include <smp/node.h>
15 #include <soc/soc_chip.h>
16 #include <types.h>
17 
18 #define CPUID_PROCESSOR_FREQUENCY		0X16
19 #define CPUID_HYBRID_INFORMATION		0x1a
20 
21 /* Structured Extended Feature Flags */
22 #define HYBRID_FEATURE				BIT(15)
23 
24 /*
25  * Set PERF_CTL MSR (0x199) P_Req with
26  * Turbo Ratio which is the Maximum Ratio.
27  */
cpu_set_max_ratio(void)28 void cpu_set_max_ratio(void)
29 {
30 	/* Check for configurable TDP option */
31 	if (get_turbo_state() == TURBO_ENABLED)
32 		cpu_set_p_state_to_turbo_ratio();
33 }
34 
35 /*
36  * Get the TDP Nominal Ratio from MSR 0x648 Bits 7:0.
37  */
cpu_get_tdp_nominal_ratio(void)38 u8 cpu_get_tdp_nominal_ratio(void)
39 {
40 	u8 nominal_ratio;
41 	msr_t msr;
42 
43 	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
44 	nominal_ratio = msr.lo & 0xff;
45 	return nominal_ratio;
46 }
47 
48 /*
49  * Read PLATFORM_INFO MSR (0xCE).
50  * Return Value of Bit 34:33 (CONFIG_TDP_LEVELS).
51  *
52  * Possible values of Bit 34:33 are -
53  * 00 : Config TDP not supported
54  * 01 : One Additional TDP level supported
55  * 10 : Two Additional TDP level supported
56  * 11 : Reserved
57  */
cpu_config_tdp_levels(void)58 int cpu_config_tdp_levels(void)
59 {
60 	msr_t platform_info;
61 
62 	/* Bits 34:33 indicate how many levels supported */
63 	platform_info = rdmsr(MSR_PLATFORM_INFO);
64 	return (platform_info.hi >> 1) & 3;
65 }
66 
set_perf_control_msr(msr_t msr)67 static void set_perf_control_msr(msr_t msr)
68 {
69 	wrmsr(IA32_PERF_CTL, msr);
70 	printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n",
71 	       ((msr.lo >> 8) & 0xff) * CONFIG_CPU_BCLK_MHZ);
72 }
73 
74 /*
75  * TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the
76  * factory configured values for of 1-core, 2-core, 3-core
77  * and 4-core turbo ratio limits for all processors.
78  *
79  * 7:0 -	MAX_TURBO_1_CORE
80  * 15:8 -	MAX_TURBO_2_CORES
81  * 23:16 -	MAX_TURBO_3_CORES
82  * 31:24 -	MAX_TURBO_4_CORES
83  *
84  * Set PERF_CTL MSR (0x199) P_Req with that value.
85  */
cpu_set_p_state_to_turbo_ratio(void)86 void cpu_set_p_state_to_turbo_ratio(void)
87 {
88 	msr_t msr, perf_ctl;
89 
90 	msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
91 	perf_ctl.lo = (msr.lo & 0xff) << 8;
92 	perf_ctl.hi = 0;
93 
94 	set_perf_control_msr(perf_ctl);
95 }
96 
97 /*
98  * CONFIG_TDP_NOMINAL MSR (0x648) Bits 7:0 tells Nominal
99  * TDP level ratio to be used for specific processor (in units
100  * of 100MHz).
101  *
102  * Set PERF_CTL MSR (0x199) P_Req with that value.
103  */
cpu_set_p_state_to_nominal_tdp_ratio(void)104 void cpu_set_p_state_to_nominal_tdp_ratio(void)
105 {
106 	msr_t msr, perf_ctl;
107 
108 	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
109 	perf_ctl.lo = (msr.lo & 0xff) << 8;
110 	perf_ctl.hi = 0;
111 
112 	set_perf_control_msr(perf_ctl);
113 }
114 
115 /*
116  * PLATFORM_INFO MSR (0xCE) Bits 15:8 tells
117  * MAX_NON_TURBO_LIM_RATIO.
118  *
119  * Set PERF_CTL MSR (0x199) P_Req with that value.
120  */
cpu_set_p_state_to_max_non_turbo_ratio(void)121 void cpu_set_p_state_to_max_non_turbo_ratio(void)
122 {
123 	msr_t perf_ctl;
124 
125 	/* Platform Info bits 15:8 give max ratio */
126 	perf_ctl.lo = (cpu_get_max_non_turbo_ratio() << 8) & 0xff00;
127 	perf_ctl.hi = 0;
128 
129 	set_perf_control_msr(perf_ctl);
130 }
131 
132 /*
133  * Set PERF_CTL MSR (0x199) P_Req with the value
134  * for maximum efficiency. This value is reported in PLATFORM_INFO MSR (0xCE)
135  * in Bits 47:40 and is extracted with cpu_get_min_ratio().
136  */
cpu_set_p_state_to_min_clock_ratio(void)137 void cpu_set_p_state_to_min_clock_ratio(void)
138 {
139 	uint32_t min_ratio;
140 	msr_t perf_ctl;
141 
142 	/* Read the minimum ratio for the best efficiency. */
143 	min_ratio = cpu_get_min_ratio();
144 	perf_ctl.lo = (min_ratio << 8) & 0xff00;
145 	perf_ctl.hi = 0;
146 
147 	set_perf_control_msr(perf_ctl);
148 }
149 
150 /*
151  * Get the Burst/Turbo Mode State from MSR IA32_MISC_ENABLE 0x1A0
152  * Bit 38 - TURBO_MODE_DISABLE Bit to get state ENABLED / DISABLED.
153  * Also check for the cpuid 0x6 to check whether Burst mode unsupported.
154  */
cpu_get_burst_mode_state(void)155 int cpu_get_burst_mode_state(void)
156 {
157 	msr_t msr;
158 	unsigned int eax;
159 	int burst_en, burst_cap, burst_state = BURST_MODE_UNKNOWN;
160 
161 	eax = cpuid_eax(0x6);
162 	burst_cap = eax & 0x2;
163 	msr = rdmsr(IA32_MISC_ENABLE);
164 	burst_en = !(msr.hi & BURST_MODE_DISABLE);
165 
166 	if (!burst_cap && burst_en) {
167 		burst_state = BURST_MODE_UNAVAILABLE;
168 	} else if (burst_cap && !burst_en) {
169 		burst_state = BURST_MODE_DISABLED;
170 	} else if (burst_cap && burst_en) {
171 		burst_state = BURST_MODE_ENABLED;
172 	}
173 	return burst_state;
174 }
175 
cpu_is_hybrid_supported(void)176 bool cpu_is_hybrid_supported(void)
177 {
178 	struct cpuid_result cpuid_regs;
179 
180 	/* CPUID.(EAX=07H, ECX=00H):EDX[15] indicates CPU is hybrid CPU or not*/
181 	cpuid_regs = cpuid_ext(CPUID_STRUCT_EXTENDED_FEATURE_FLAGS, 0);
182 	return !!(cpuid_regs.edx & HYBRID_FEATURE);
183 }
184 
185 /*
186  * The function must be called if CPU is hybrid. If CPU is hybrid, the CPU type
187  * information is available in the Hybrid Information Enumeration Leaf(EAX=0x1A, ECX=0).
188  */
cpu_get_cpu_type(void)189 uint8_t cpu_get_cpu_type(void)
190 {
191 	union cpuid_nat_model_id_and_core_type {
192 		struct {
193 			u32 native_mode_id:24;
194 			u32 core_type:8;
195 		} bits;
196 		u32 hybrid_info;
197 	};
198 	union cpuid_nat_model_id_and_core_type eax;
199 
200 	eax.hybrid_info = cpuid_eax(CPUID_HYBRID_INFORMATION);
201 	return (u8)eax.bits.core_type;
202 }
203 
204 /* It gets CPU bus frequency in MHz */
cpu_get_bus_frequency(void)205 uint32_t cpu_get_bus_frequency(void)
206 {
207 	return cpuid_ecx(CPUID_PROCESSOR_FREQUENCY);
208 }
209 
210 /*
211  * Program CPU Burst mode
212  * true = Enable Burst mode.
213  * false = Disable Burst mode.
214  */
cpu_burst_mode(bool burst_mode_status)215 void cpu_burst_mode(bool burst_mode_status)
216 {
217 	msr_t msr;
218 
219 	msr = rdmsr(IA32_MISC_ENABLE);
220 	if (burst_mode_status)
221 		msr.hi &= ~BURST_MODE_DISABLE;
222 	else
223 		msr.hi |= BURST_MODE_DISABLE;
224 	wrmsr(IA32_MISC_ENABLE, msr);
225 }
226 
227 /*
228  * Program Enhanced Intel Speed Step Technology
229  * true = Enable EIST.
230  * false = Disable EIST.
231  */
cpu_set_eist(bool eist_status)232 void cpu_set_eist(bool eist_status)
233 {
234 	msr_t msr;
235 
236 	msr = rdmsr(IA32_MISC_ENABLE);
237 	if (eist_status)
238 		msr.lo |= (1 << 16);
239 	else
240 		msr.lo &= ~(1 << 16);
241 	wrmsr(IA32_MISC_ENABLE, msr);
242 }
243 
244 /*
245  * This function fills in the number of Cores(physical) and Threads(virtual)
246  * of the CPU in the function arguments. It also returns if the number of cores
247  * and number of threads are equal.
248  */
cpu_read_topology(unsigned int * num_phys,unsigned int * num_virt)249 int cpu_read_topology(unsigned int *num_phys, unsigned int *num_virt)
250 {
251 	msr_t msr;
252 	msr = rdmsr(MSR_CORE_THREAD_COUNT);
253 	*num_virt = (msr.lo >> 0) & 0xffff;
254 	*num_phys = (msr.lo >> 16) & 0xffff;
255 	return (*num_virt == *num_phys);
256 }
257 
cpu_get_coord_type(void)258 int cpu_get_coord_type(void)
259 {
260 	return HW_ALL;
261 }
262 
cpu_get_min_ratio(void)263 uint32_t cpu_get_min_ratio(void)
264 {
265 	msr_t msr;
266 	/* Get bus ratio limits and calculate clock speeds */
267 	msr = rdmsr(MSR_PLATFORM_INFO);
268 	return ((msr.hi >> 8) & 0xff);	/* Max Efficiency Ratio */
269 }
270 
cpu_get_max_ratio(void)271 uint32_t cpu_get_max_ratio(void)
272 {
273 	msr_t msr;
274 	uint32_t ratio_max;
275 	if (cpu_config_tdp_levels()) {
276 		/* Set max ratio to nominal TDP ratio */
277 		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
278 		ratio_max = msr.lo & 0xff;
279 	} else {
280 		msr = rdmsr(MSR_PLATFORM_INFO);
281 		/* Max Non-Turbo Ratio */
282 		ratio_max = (msr.lo >> 8) & 0xff;
283 	}
284 	return ratio_max;
285 }
286 
cpu_get_max_non_turbo_ratio(void)287 uint8_t cpu_get_max_non_turbo_ratio(void)
288 {
289 	msr_t msr;
290 
291 	/*
292 	 * PLATFORM_INFO(0xCE) MSR Bits[15:8] tells
293 	 * MAX_NON_TURBO_LIM_RATIO
294 	 */
295 	msr = rdmsr(MSR_PLATFORM_INFO);
296 	return ((msr.lo >> 8) & 0xff);
297 }
298 
configure_tcc_thermal_target(void)299 void configure_tcc_thermal_target(void)
300 {
301 	const config_t *conf = config_of_soc();
302 	msr_t msr;
303 
304 	if (!conf->tcc_offset)
305 		return;
306 
307 	/* Set TCC activation offset */
308 	msr = rdmsr(MSR_PLATFORM_INFO);
309 	if ((msr.lo & BIT(30))) {
310 		msr = rdmsr(MSR_TEMPERATURE_TARGET);
311 		msr.lo &= ~(0xf << 24);
312 		msr.lo |= (conf->tcc_offset & 0xf) << 24;
313 		wrmsr(MSR_TEMPERATURE_TARGET, msr);
314 	}
315 
316 	/*
317 	 * SoCs prior to Comet Lake/Cannon Lake do not support the time window
318 	 * bits, so return early.
319 	 */
320 	if (CONFIG(SOC_INTEL_APOLLOLAKE) || CONFIG(SOC_INTEL_SKYLAKE) ||
321 	    CONFIG(SOC_INTEL_KABYLAKE) || CONFIG(SOC_INTEL_BRASWELL) ||
322 	    CONFIG(SOC_INTEL_BROADWELL))
323 		return;
324 
325 	/* Time Window Tau Bits [6:0] */
326 	msr = rdmsr(MSR_TEMPERATURE_TARGET);
327 	msr.lo &= ~0x7f;
328 	msr.lo |= 0xe6; /* setting 100ms thermal time window */
329 	wrmsr(MSR_TEMPERATURE_TARGET, msr);
330 }
331 
cpu_get_bus_clock(void)332 uint32_t cpu_get_bus_clock(void)
333 {
334 	/* CPU bus clock is set by default here to 100MHz.
335 	 * This function returns the bus clock in KHz.
336 	 */
337 	return CONFIG_CPU_BCLK_MHZ * KHz;
338 }
339 
cpu_get_power_max(void)340 uint32_t cpu_get_power_max(void)
341 {
342 	msr_t msr;
343 	int power_unit;
344 
345 	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
346 	power_unit = 2 << ((msr.lo & 0xf) - 1);
347 	msr = rdmsr(MSR_PKG_POWER_SKU);
348 	return (msr.lo & 0x7fff) * 1000 / power_unit;
349 }
350 
cpu_get_max_turbo_ratio(void)351 uint32_t cpu_get_max_turbo_ratio(void)
352 {
353 	msr_t msr;
354 	msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
355 	return msr.lo & 0xff;
356 }
357 
mca_configure(void)358 void mca_configure(void)
359 {
360 	int i;
361 	const unsigned int num_banks = mca_get_bank_count();
362 
363 	printk(BIOS_DEBUG, "Clearing out pending MCEs\n");
364 
365 	mca_clear_status();
366 
367 	for (i = 0; i < num_banks; i++) {
368 		/* Initialize machine checks */
369 		wrmsr(IA32_MC_CTL(i),
370 			(msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
371 	}
372 }
373 
cpu_lt_lock_memory(void)374 void cpu_lt_lock_memory(void)
375 {
376 	msr_set(MSR_LT_CONTROL, LT_CONTROL_LOCK);
377 }
378 
is_sgx_supported(void)379 bool is_sgx_supported(void)
380 {
381 	struct cpuid_result cpuid_regs;
382 	msr_t msr;
383 
384 	/* EBX[2] is feature capability */
385 	cpuid_regs = cpuid_ext(CPUID_STRUCT_EXTENDED_FEATURE_FLAGS, 0x0);
386 	msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */
387 	return ((cpuid_regs.ebx & SGX_SUPPORTED) && (msr.lo & MTRR_CAP_PRMRR));
388 }
389 
is_sgx_configured_and_supported(void)390 static bool is_sgx_configured_and_supported(void)
391 {
392 	return CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE) && is_sgx_supported();
393 }
394 
is_keylocker_supported(void)395 bool is_keylocker_supported(void)
396 {
397 	struct cpuid_result cpuid_regs;
398 	msr_t msr;
399 
400 	/* ECX[23] is feature capability */
401 	cpuid_regs = cpuid_ext(CPUID_STRUCT_EXTENDED_FEATURE_FLAGS, 0x0);
402 	msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */
403 	return ((cpuid_regs.ecx & KEYLOCKER_SUPPORTED) && (msr.lo & MTRR_CAP_PRMRR));
404 }
405 
is_keylocker_configured_and_supported(void)406 static bool is_keylocker_configured_and_supported(void)
407 {
408 	return CONFIG(INTEL_KEYLOCKER) && is_keylocker_supported();
409 }
410 
check_prm_features_enabled(void)411 static bool check_prm_features_enabled(void)
412 {
413 	/*
414 	 * Key Locker and SGX are the features that need PRM.
415 	 * If either of them are enabled return true, otherwise false
416 	 * */
417 	return is_sgx_configured_and_supported() ||
418 		is_keylocker_configured_and_supported();
419 }
420 
get_valid_prmrr_size(void)421 int get_valid_prmrr_size(void)
422 {
423 	msr_t msr;
424 	int i;
425 	int valid_size;
426 
427 	/* If none of the features that need PRM are enabled then return 0 */
428 	if (!check_prm_features_enabled())
429 		return 0;
430 
431 	if (!CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE)
432 		return 0;
433 
434 	msr = rdmsr(MSR_PRMRR_VALID_CONFIG);
435 	if (!msr.lo) {
436 		printk(BIOS_WARNING, "PRMRR not supported.\n");
437 		return 0;
438 	}
439 
440 	printk(BIOS_DEBUG, "MSR_PRMRR_VALID_CONFIG = 0x%08x\n", msr.lo);
441 
442 	/* find the first (greatest) value that is lower than or equal to the selected size */
443 	for (i = 8; i >= 0; i--) {
444 		valid_size = msr.lo & (1 << i);
445 
446 		if (valid_size && valid_size <= CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE)
447 			break;
448 		else if (i == 0)
449 			valid_size = 0;
450 	}
451 
452 	if (!valid_size) {
453 		printk(BIOS_WARNING, "Unsupported PRMRR size of %i MiB, check your config!\n",
454 			CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE);
455 		return 0;
456 	}
457 
458 	printk(BIOS_DEBUG, "PRMRR size set to %i MiB\n", valid_size);
459 
460 	valid_size *= MiB;
461 
462 	return valid_size;
463 }
464 
sync_core_prmrr(void)465 static void sync_core_prmrr(void)
466 {
467 	static msr_t msr_base, msr_mask;
468 
469 	if (boot_cpu()) {
470 		msr_base = rdmsr(MSR_PRMRR_BASE_0);
471 		msr_mask = rdmsr(MSR_PRMRR_PHYS_MASK);
472 	} else if (!intel_ht_sibling()) {
473 		wrmsr(MSR_PRMRR_BASE_0, msr_base);
474 		wrmsr(MSR_PRMRR_PHYS_MASK, msr_mask);
475 	}
476 }
477 
init_core_prmrr(void)478 void init_core_prmrr(void)
479 {
480 	msr_t msr = rdmsr(MTRR_CAP_MSR);
481 
482 	if (msr.lo & MTRR_CAP_PRMRR)
483 		sync_core_prmrr();
484 }
485 
set_tme_core_activate(void)486 void set_tme_core_activate(void)
487 {
488 	msr_t msr = { .lo = 0, .hi = 0 };
489 
490 	wrmsr(MSR_CORE_MKTME_ACTIVATION, msr);
491 }
492 
493 /* Provide the max turbo frequency of the CPU */
smbios_cpu_get_max_speed_mhz(void)494 unsigned int smbios_cpu_get_max_speed_mhz(void)
495 {
496 	return cpu_get_max_turbo_ratio() * CONFIG_CPU_BCLK_MHZ;
497 }
498 
disable_three_strike_error(void)499 void disable_three_strike_error(void)
500 {
501 	msr_t msr;
502 
503 	msr = rdmsr(MSR_PREFETCH_CTL);
504 	msr.lo = msr.lo | DISABLE_CPU_ERROR;
505 	wrmsr(MSR_PREFETCH_CTL, msr);
506 }
507 
disable_signaling_three_strike_event(void)508 void disable_signaling_three_strike_event(void)
509 {
510 	msr_t msr;
511 
512 	msr = rdmsr(MSR_DISABLE_SIGNALING_THREE_STRIKE_EVENT);
513 	msr.lo = msr.lo | THREE_STRIKE_COUNT;
514 	wrmsr(MSR_DISABLE_SIGNALING_THREE_STRIKE_EVENT, msr);
515 }
516