blob: 534feb11559a0aeb9d4749c8681c612c94549071 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Barnali Sarkar19b546f2017-05-03 18:00:48 +05302
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpigen.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +01004#include <assert.h>
Barnali Sarkar19b546f2017-05-03 18:00:48 +05305#include <console/console.h>
Elyes Haouasdef74aa2022-10-31 13:44:40 +01006#include <cpu/cpu.h>
Subrata Banik13fd3c82022-06-05 18:57:36 +05307#include <cpu/intel/common/common.h>
Barnali Sarkar19b546f2017-05-03 18:00:48 +05308#include <cpu/intel/turbo.h>
9#include <cpu/x86/msr.h>
Subrata Banik13fd3c82022-06-05 18:57:36 +053010#include <cpu/x86/mtrr.h>
Barnali Sarkar19b546f2017-05-03 18:00:48 +053011#include <intelblocks/cpulib.h>
12#include <intelblocks/fast_spi.h>
Michael Niewöhner5ce66da2019-09-22 21:56:17 +020013#include <intelblocks/msr.h>
Subrata Banik13fd3c82022-06-05 18:57:36 +053014#include <smp/node.h>
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +053015#include <soc/soc_chip.h>
Elyes HAOUAS23a60fa2020-07-22 11:44:29 +020016#include <types.h>
Barnali Sarkar19b546f2017-05-03 18:00:48 +053017
Aamir Bohrad1925902021-02-19 16:18:07 +053018#define CPUID_EXTENDED_CPU_TOPOLOGY 0x0b
Aamir Bohrad1925902021-02-19 16:18:07 +053019#define LEVEL_TYPE_CORE 2
20#define LEVEL_TYPE_SMT 1
21
22#define CPUID_CPU_TOPOLOGY(x, val) \
23 (((val) >> CPUID_CPU_TOPOLOGY_##x##_SHIFT) & CPUID_CPU_TOPOLOGY_##x##_MASK)
24
25#define CPUID_CPU_TOPOLOGY_LEVEL_TYPE_SHIFT 0x8
26#define CPUID_CPU_TOPOLOGY_LEVEL_TYPE_MASK 0xff
27#define CPUID_CPU_TOPOLOGY_LEVEL(res) CPUID_CPU_TOPOLOGY(LEVEL_TYPE, (res).ecx)
28
29#define CPUID_CPU_TOPOLOGY_LEVEL_BITS_SHIFT 0x0
30#define CPUID_CPU_TOPOLOGY_LEVEL_BITS_MASK 0x1f
31#define CPUID_CPU_TOPOLOGY_THREAD_BITS(res) CPUID_CPU_TOPOLOGY(LEVEL_BITS, (res).eax)
32#define CPUID_CPU_TOPOLOGY_CORE_BITS(res, threadbits) \
33 ((CPUID_CPU_TOPOLOGY(LEVEL_BITS, (res).eax)) - threadbits)
34
Sridahr Siricilla74245762021-11-11 01:42:30 +053035#define CPUID_PROCESSOR_FREQUENCY 0X16
36#define CPUID_HYBRID_INFORMATION 0x1a
37
38/* Structured Extended Feature Flags */
39#define CPUID_STRUCT_EXTENDED_FEATURE_FLAGS 0x7
40#define HYBRID_FEATURE BIT(15)
41
Barnali Sarkar19b546f2017-05-03 18:00:48 +053042/*
Werner Zeh6b522c32018-11-22 15:10:18 +010043 * Set PERF_CTL MSR (0x199) P_Req with
Barnali Sarkar19b546f2017-05-03 18:00:48 +053044 * Turbo Ratio which is the Maximum Ratio.
45 */
46void cpu_set_max_ratio(void)
47{
48 /* Check for configurable TDP option */
49 if (get_turbo_state() == TURBO_ENABLED)
50 cpu_set_p_state_to_turbo_ratio();
51}
52
53/*
54 * Get the TDP Nominal Ratio from MSR 0x648 Bits 7:0.
55 */
56u8 cpu_get_tdp_nominal_ratio(void)
57{
58 u8 nominal_ratio;
59 msr_t msr;
60
61 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
62 nominal_ratio = msr.lo & 0xff;
63 return nominal_ratio;
64}
65
66/*
67 * Read PLATFORM_INFO MSR (0xCE).
68 * Return Value of Bit 34:33 (CONFIG_TDP_LEVELS).
69 *
70 * Possible values of Bit 34:33 are -
71 * 00 : Config TDP not supported
72 * 01 : One Additional TDP level supported
73 * 10 : Two Additional TDP level supported
74 * 11 : Reserved
75 */
76int cpu_config_tdp_levels(void)
77{
78 msr_t platform_info;
79
80 /* Bits 34:33 indicate how many levels supported */
81 platform_info = rdmsr(MSR_PLATFORM_INFO);
82 return (platform_info.hi >> 1) & 3;
83}
84
Subrata Banik459df662019-04-10 11:36:58 +053085static void set_perf_control_msr(msr_t msr)
86{
87 wrmsr(IA32_PERF_CTL, msr);
88 printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n",
89 ((msr.lo >> 8) & 0xff) * CONFIG_CPU_BCLK_MHZ);
90}
91
Barnali Sarkar19b546f2017-05-03 18:00:48 +053092/*
93 * TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the
94 * factory configured values for of 1-core, 2-core, 3-core
95 * and 4-core turbo ratio limits for all processors.
96 *
97 * 7:0 - MAX_TURBO_1_CORE
98 * 15:8 - MAX_TURBO_2_CORES
99 * 23:16 - MAX_TURBO_3_CORES
100 * 31:24 - MAX_TURBO_4_CORES
101 *
Werner Zeh6b522c32018-11-22 15:10:18 +0100102 * Set PERF_CTL MSR (0x199) P_Req with that value.
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530103 */
104void cpu_set_p_state_to_turbo_ratio(void)
105{
106 msr_t msr, perf_ctl;
107
108 msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
109 perf_ctl.lo = (msr.lo & 0xff) << 8;
110 perf_ctl.hi = 0;
111
Subrata Banik459df662019-04-10 11:36:58 +0530112 set_perf_control_msr(perf_ctl);
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530113}
114
115/*
116 * CONFIG_TDP_NOMINAL MSR (0x648) Bits 7:0 tells Nominal
117 * TDP level ratio to be used for specific processor (in units
118 * of 100MHz).
119 *
Werner Zeh6b522c32018-11-22 15:10:18 +0100120 * Set PERF_CTL MSR (0x199) P_Req with that value.
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530121 */
122void cpu_set_p_state_to_nominal_tdp_ratio(void)
123{
124 msr_t msr, perf_ctl;
125
126 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
127 perf_ctl.lo = (msr.lo & 0xff) << 8;
128 perf_ctl.hi = 0;
129
Subrata Banik459df662019-04-10 11:36:58 +0530130 set_perf_control_msr(perf_ctl);
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530131}
132
133/*
134 * PLATFORM_INFO MSR (0xCE) Bits 15:8 tells
135 * MAX_NON_TURBO_LIM_RATIO.
136 *
Werner Zeh6b522c32018-11-22 15:10:18 +0100137 * Set PERF_CTL MSR (0x199) P_Req with that value.
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530138 */
139void cpu_set_p_state_to_max_non_turbo_ratio(void)
140{
Sridhar Siricilla57ff3022021-12-02 09:48:44 +0530141 msr_t perf_ctl;
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530142
143 /* Platform Info bits 15:8 give max ratio */
Sridhar Siricilla57ff3022021-12-02 09:48:44 +0530144 perf_ctl.lo = (cpu_get_max_non_turbo_ratio() << 8) & 0xff00;
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530145 perf_ctl.hi = 0;
146
Subrata Banik459df662019-04-10 11:36:58 +0530147 set_perf_control_msr(perf_ctl);
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530148}
149
150/*
Werner Zeh6b522c32018-11-22 15:10:18 +0100151 * Set PERF_CTL MSR (0x199) P_Req with the value
Werner Zeh52c58922018-11-21 10:38:12 +0100152 * for maximum efficiency. This value is reported in PLATFORM_INFO MSR (0xCE)
153 * in Bits 47:40 and is extracted with cpu_get_min_ratio().
154 */
155void cpu_set_p_state_to_min_clock_ratio(void)
156{
157 uint32_t min_ratio;
158 msr_t perf_ctl;
159
160 /* Read the minimum ratio for the best efficiency. */
161 min_ratio = cpu_get_min_ratio();
162 perf_ctl.lo = (min_ratio << 8) & 0xff00;
163 perf_ctl.hi = 0;
Subrata Banik459df662019-04-10 11:36:58 +0530164
165 set_perf_control_msr(perf_ctl);
Werner Zeh52c58922018-11-21 10:38:12 +0100166}
167
168/*
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530169 * Get the Burst/Turbo Mode State from MSR IA32_MISC_ENABLE 0x1A0
170 * Bit 38 - TURBO_MODE_DISABLE Bit to get state ENABLED / DISABLED.
171 * Also check for the cpuid 0x6 to check whether Burst mode unsupported.
172 */
173int cpu_get_burst_mode_state(void)
174{
175
176 msr_t msr;
177 unsigned int eax;
178 int burst_en, burst_cap, burst_state = BURST_MODE_UNKNOWN;
179
180 eax = cpuid_eax(0x6);
181 burst_cap = eax & 0x2;
182 msr = rdmsr(IA32_MISC_ENABLE);
183 burst_en = !(msr.hi & BURST_MODE_DISABLE);
184
185 if (!burst_cap && burst_en) {
186 burst_state = BURST_MODE_UNAVAILABLE;
187 } else if (burst_cap && !burst_en) {
188 burst_state = BURST_MODE_DISABLED;
189 } else if (burst_cap && burst_en) {
190 burst_state = BURST_MODE_ENABLED;
191 }
192 return burst_state;
193}
194
Sridahr Siricilla74245762021-11-11 01:42:30 +0530195bool cpu_is_hybrid_supported(void)
196{
197 struct cpuid_result cpuid_regs;
198
199 /* CPUID.(EAX=07H, ECX=00H):EDX[15] indicates CPU is hybrid CPU or not*/
200 cpuid_regs = cpuid_ext(CPUID_STRUCT_EXTENDED_FEATURE_FLAGS, 0);
201 return !!(cpuid_regs.edx & HYBRID_FEATURE);
202}
203
204/*
205 * The function must be called if CPU is hybrid. If CPU is hybrid, the CPU type
206 * information is available in the Hybrid Information Enumeration Leaf(EAX=0x1A, ECX=0).
207 */
208uint8_t cpu_get_cpu_type(void)
209{
210 union cpuid_nat_model_id_and_core_type {
211 struct {
212 u32 native_mode_id:24;
213 u32 core_type:8;
214 } bits;
215 u32 hybrid_info;
216 };
217 union cpuid_nat_model_id_and_core_type eax;
218
219 eax.hybrid_info = cpuid_eax(CPUID_HYBRID_INFORMATION);
220 return (u8)eax.bits.core_type;
221}
222
223/* It gets CPU bus frequency in MHz */
224uint32_t cpu_get_bus_frequency(void)
225{
226 return cpuid_ecx(CPUID_PROCESSOR_FREQUENCY);
227}
228
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530229/*
Subrata Banik6d569162019-04-10 12:19:27 +0530230 * Program CPU Burst mode
231 * true = Enable Burst mode.
232 * false = Disable Burst mode.
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530233 */
Subrata Banik6d569162019-04-10 12:19:27 +0530234void cpu_burst_mode(bool burst_mode_status)
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530235{
236 msr_t msr;
237
238 msr = rdmsr(IA32_MISC_ENABLE);
Subrata Banik6d569162019-04-10 12:19:27 +0530239 if (burst_mode_status)
240 msr.hi &= ~BURST_MODE_DISABLE;
241 else
242 msr.hi |= BURST_MODE_DISABLE;
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530243 wrmsr(IA32_MISC_ENABLE, msr);
244}
245
246/*
Subrata Banik6d569162019-04-10 12:19:27 +0530247 * Program Enhanced Intel Speed Step Technology
248 * true = Enable EIST.
249 * false = Disable EIST.
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530250 */
Subrata Banik6d569162019-04-10 12:19:27 +0530251void cpu_set_eist(bool eist_status)
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530252{
253 msr_t msr;
254
255 msr = rdmsr(IA32_MISC_ENABLE);
Subrata Banik6d569162019-04-10 12:19:27 +0530256 if (eist_status)
257 msr.lo |= (1 << 16);
258 else
259 msr.lo &= ~(1 << 16);
Barnali Sarkar19b546f2017-05-03 18:00:48 +0530260 wrmsr(IA32_MISC_ENABLE, msr);
261}
262
263/*
Barnali Sarkar91d38a5b2017-06-13 19:17:35 +0530264 * This function fills in the number of Cores(physical) and Threads(virtual)
265 * of the CPU in the function arguments. It also returns if the number of cores
266 * and number of threads are equal.
267 */
268int cpu_read_topology(unsigned int *num_phys, unsigned int *num_virt)
269{
270 msr_t msr;
271 msr = rdmsr(MSR_CORE_THREAD_COUNT);
272 *num_virt = (msr.lo >> 0) & 0xffff;
273 *num_phys = (msr.lo >> 16) & 0xffff;
Shaunak Saha5f843102017-08-16 09:54:00 -0700274 return (*num_virt == *num_phys);
275}
276
277int cpu_get_coord_type(void)
278{
279 return HW_ALL;
280}
281
282uint32_t cpu_get_min_ratio(void)
283{
284 msr_t msr;
285 /* Get bus ratio limits and calculate clock speeds */
286 msr = rdmsr(MSR_PLATFORM_INFO);
287 return ((msr.hi >> 8) & 0xff); /* Max Efficiency Ratio */
288}
289
290uint32_t cpu_get_max_ratio(void)
291{
292 msr_t msr;
293 uint32_t ratio_max;
294 if (cpu_config_tdp_levels()) {
295 /* Set max ratio to nominal TDP ratio */
296 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
297 ratio_max = msr.lo & 0xff;
298 } else {
299 msr = rdmsr(MSR_PLATFORM_INFO);
300 /* Max Non-Turbo Ratio */
301 ratio_max = (msr.lo >> 8) & 0xff;
302 }
303 return ratio_max;
304}
305
Sridahr Siricilla74245762021-11-11 01:42:30 +0530306uint8_t cpu_get_max_non_turbo_ratio(void)
307{
308 msr_t msr;
309
310 /*
311 * PLATFORM_INFO(0xCE) MSR Bits[15:8] tells
312 * MAX_NON_TURBO_LIM_RATIO
313 */
314 msr = rdmsr(MSR_PLATFORM_INFO);
315 return ((msr.lo >> 8) & 0xff);
316}
317
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +0530318void configure_tcc_thermal_target(void)
319{
320 const config_t *conf = config_of_soc();
321 msr_t msr;
322
Tim Wawrzynczakabd3cae2020-06-29 13:06:46 -0600323 if (!conf->tcc_offset)
324 return;
325
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +0530326 /* Set TCC activation offset */
327 msr = rdmsr(MSR_PLATFORM_INFO);
Tim Wawrzynczakabd3cae2020-06-29 13:06:46 -0600328 if ((msr.lo & BIT(30))) {
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +0530329 msr = rdmsr(MSR_TEMPERATURE_TARGET);
330 msr.lo &= ~(0xf << 24);
331 msr.lo |= (conf->tcc_offset & 0xf) << 24;
332 wrmsr(MSR_TEMPERATURE_TARGET, msr);
333 }
Tim Wawrzynczakabd3cae2020-06-29 13:06:46 -0600334
Tim Wawrzynczaka1061632020-07-01 09:32:18 -0600335 /*
336 * SoCs prior to Comet Lake/Cannon Lake do not support the time window
337 * bits, so return early.
338 */
339 if (CONFIG(SOC_INTEL_APOLLOLAKE) || CONFIG(SOC_INTEL_SKYLAKE) ||
340 CONFIG(SOC_INTEL_KABYLAKE) || CONFIG(SOC_INTEL_BRASWELL) ||
341 CONFIG(SOC_INTEL_BROADWELL))
342 return;
Tim Wawrzynczakabd3cae2020-06-29 13:06:46 -0600343
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +0530344 /* Time Window Tau Bits [6:0] */
Tim Wawrzynczaka1061632020-07-01 09:32:18 -0600345 msr = rdmsr(MSR_TEMPERATURE_TARGET);
Sumeet R Pawnikar360684b2020-06-18 15:56:11 +0530346 msr.lo &= ~0x7f;
347 msr.lo |= 0xe6; /* setting 100ms thermal time window */
348 wrmsr(MSR_TEMPERATURE_TARGET, msr);
349}
350
Shaunak Saha5f843102017-08-16 09:54:00 -0700351uint32_t cpu_get_bus_clock(void)
352{
353 /* CPU bus clock is set by default here to 100MHz.
354 * This function returns the bus clock in KHz.
355 */
356 return CONFIG_CPU_BCLK_MHZ * KHz;
357}
358
359uint32_t cpu_get_power_max(void)
360{
361 msr_t msr;
362 int power_unit;
363
364 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
365 power_unit = 2 << ((msr.lo & 0xf) - 1);
366 msr = rdmsr(MSR_PKG_POWER_SKU);
Mario Scheithauerba91cd32018-04-10 12:32:07 +0200367 return (msr.lo & 0x7fff) * 1000 / power_unit;
Shaunak Saha5f843102017-08-16 09:54:00 -0700368}
369
370uint32_t cpu_get_max_turbo_ratio(void)
371{
372 msr_t msr;
373 msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
374 return msr.lo & 0xff;
Barnali Sarkar91d38a5b2017-06-13 19:17:35 +0530375}
Pratik Prajapati4e203072017-08-28 12:16:23 -0700376
Subrata Banikf91344c2019-05-06 19:23:26 +0530377void mca_configure(void)
Pratik Prajapati4e203072017-08-28 12:16:23 -0700378{
Pratik Prajapati4e203072017-08-28 12:16:23 -0700379 int i;
Felix Heldc75c8c12021-07-13 02:00:55 +0200380 const unsigned int num_banks = mca_get_bank_count();
Pratik Prajapati4e203072017-08-28 12:16:23 -0700381
Nico Huber53229422019-02-01 14:20:01 +0100382 printk(BIOS_DEBUG, "Clearing out pending MCEs\n");
383
Felix Heldacbf1542021-07-13 16:44:18 +0200384 mca_clear_status();
Pratik Prajapati35cb7852018-05-18 18:05:18 -0700385
Pratik Prajapati4e203072017-08-28 12:16:23 -0700386 for (i = 0; i < num_banks; i++) {
Pratik Prajapati4e203072017-08-28 12:16:23 -0700387 /* Initialize machine checks */
Felix Held1b46e762021-07-13 00:54:32 +0200388 wrmsr(IA32_MC_CTL(i),
Pratik Prajapati4e203072017-08-28 12:16:23 -0700389 (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
390 }
391}
Michael Niewöhner5ce66da2019-09-22 21:56:17 +0200392
Michael Niewöhner6e64c1a2020-08-05 21:36:11 +0200393void cpu_lt_lock_memory(void)
Michael Niewöhner5ce66da2019-09-22 21:56:17 +0200394{
Michael Niewöhner90df9162020-10-13 22:58:28 +0200395 msr_set(MSR_LT_CONTROL, LT_CONTROL_LOCK);
Michael Niewöhner5ce66da2019-09-22 21:56:17 +0200396}
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200397
Michael Niewöhner490546f2020-09-15 12:20:08 +0200398int get_valid_prmrr_size(void)
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200399{
400 msr_t msr;
401 int i;
402 int valid_size;
403
Michael Niewöhner028c0b62020-09-15 12:11:15 +0200404 if (!CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE))
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200405 return 0;
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200406
407 msr = rdmsr(MSR_PRMRR_VALID_CONFIG);
408 if (!msr.lo) {
409 printk(BIOS_WARNING, "PRMRR not supported.\n");
410 return 0;
411 }
412
413 printk(BIOS_DEBUG, "MSR_PRMRR_VALID_CONFIG = 0x%08x\n", msr.lo);
414
415 /* find the first (greatest) value that is lower than or equal to the selected size */
416 for (i = 8; i >= 0; i--) {
417 valid_size = msr.lo & (1 << i);
418
419 if (valid_size && valid_size <= CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_PRMRR_SIZE)
420 break;
421 else if (i == 0)
422 valid_size = 0;
423 }
424
Angel Pons2ce386a2020-09-14 21:52:42 +0200425 if (!valid_size) {
426 printk(BIOS_WARNING, "Unsupported PRMRR size of %i MiB, check your config!\n",
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200427 CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_PRMRR_SIZE);
Angel Pons2ce386a2020-09-14 21:52:42 +0200428 return 0;
429 }
Michael Niewöhner7736bfc2019-10-22 23:05:06 +0200430
431 printk(BIOS_DEBUG, "PRMRR size set to %i MiB\n", valid_size);
432
433 valid_size *= MiB;
434
435 return valid_size;
436}
Aamir Bohrad1925902021-02-19 16:18:07 +0530437
438/* Get number of bits for core ID and SMT ID */
439static void get_cpu_core_thread_bits(uint32_t *core_bits, uint32_t *thread_bits)
440{
441 struct cpuid_result cpuid_regs;
442 int level_num, cpu_id_op = 0;
443 const uint32_t cpuid_max_func = cpuid_get_max_func();
444
445 /* Assert if extended CPU topology not supported */
446 assert(cpuid_max_func >= CPUID_EXTENDED_CPU_TOPOLOGY);
447
Ronak Kanabar68305aa2022-02-24 10:09:29 +0530448 cpu_id_op = CPUID_EXTENDED_CPU_TOPOLOGY;
Aamir Bohrad1925902021-02-19 16:18:07 +0530449
450 *core_bits = level_num = 0;
451 cpuid_regs = cpuid_ext(cpu_id_op, level_num);
452
453 /* Sub-leaf index 0 enumerates SMT level, if not assert */
454 assert(CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs) == LEVEL_TYPE_SMT);
455
456 *thread_bits = CPUID_CPU_TOPOLOGY_THREAD_BITS(cpuid_regs);
457 do {
458 level_num++;
459 cpuid_regs = cpuid_ext(cpu_id_op, level_num);
460 if (CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs) == LEVEL_TYPE_CORE) {
461 *core_bits = CPUID_CPU_TOPOLOGY_CORE_BITS(cpuid_regs, *thread_bits);
462 break;
463 }
464 /* Stop when level type is invalid i.e 0 */
465 } while (CPUID_CPU_TOPOLOGY_LEVEL(cpuid_regs));
466}
467
468void get_cpu_topology_from_apicid(uint32_t apicid, uint8_t *package,
469 uint8_t *core, uint8_t *thread)
470{
471
472 uint32_t core_bits, thread_bits;
473
474 get_cpu_core_thread_bits(&core_bits, &thread_bits);
475
476 if (package)
477 *package = apicid >> (thread_bits + core_bits);
478 if (core)
479 *core = (apicid >> thread_bits) & ((1 << core_bits) - 1);
480 if (thread)
481 *thread = apicid & ((1 << thread_bits) - 1);
482}
Subrata Banik13fd3c82022-06-05 18:57:36 +0530483
484static void sync_core_prmrr(void)
485{
486 static msr_t msr_base, msr_mask;
487
488 if (boot_cpu()) {
489 msr_base = rdmsr(MSR_PRMRR_BASE_0);
490 msr_mask = rdmsr(MSR_PRMRR_PHYS_MASK);
491 } else if (!intel_ht_sibling()) {
492 wrmsr(MSR_PRMRR_BASE_0, msr_base);
493 wrmsr(MSR_PRMRR_PHYS_MASK, msr_mask);
494 }
495}
496
497void init_core_prmrr(void)
498{
499 msr_t msr = rdmsr(MTRR_CAP_MSR);
500
501 if (msr.lo & MTRR_CAP_PRMRR)
502 sync_core_prmrr();
503}
Subrata Banik29a92e82022-08-15 15:16:43 +0530504
505bool is_tme_supported(void)
506{
507 struct cpuid_result cpuid_regs;
508
509 cpuid_regs = cpuid_ext(0x7, 0x0); /* ECX[13] is feature capability */
510
511 return (cpuid_regs.ecx & TME_SUPPORTED);
512}
Subrata Banik66cd1842022-08-15 16:29:31 +0530513
514void set_tme_core_activate(void)
515{
516 msr_t msr = { .lo = 0, .hi = 0 };
517
518 wrmsr(MSR_CORE_MKTME_ACTIVATION, msr);
519}
Dinesh Gehlotd4f2d142022-12-16 09:21:18 +0000520
521/* Provide the max turbo frequency of the CPU */
522unsigned int smbios_cpu_get_max_speed_mhz(void)
523{
524 return cpu_get_max_turbo_ratio() * CONFIG_CPU_BCLK_MHZ;
525}
Pratikkumar Prajapatie51978f2022-12-19 10:13:09 -0800526
527bool is_sgx_supported(void)
528{
529 struct cpuid_result cpuid_regs;
530 msr_t msr;
531
532 cpuid_regs = cpuid_ext(0x7, 0x0); /* EBX[2] is feature capability */
533 msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */
534 return ((cpuid_regs.ebx & SGX_SUPPORTED) && (msr.lo & MTRR_CAP_PRMRR));
535}
Pratikkumar Prajapati08e80672022-12-19 11:21:56 -0800536
537bool is_keylocker_supported(void)
538{
539 struct cpuid_result cpuid_regs;
540 msr_t msr;
541
542 cpuid_regs = cpuid_ext(0x7, 0x0); /* ECX[23] is feature capability */
543 msr = rdmsr(MTRR_CAP_MSR); /* Bit 12 is PRMRR enablement */
544 return ((cpuid_regs.ecx & KEYLOCKER_SUPPORTED) && (msr.lo & MTRR_CAP_PRMRR));
545}