coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
cpu.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <cpu/x86/mtrr.h>
7 #include <cpu/x86/msr.h>
8 #include <cpu/x86/mp.h>
10 #include <cpu/intel/microcode.h>
11 #include <cpu/intel/speedstep.h>
12 #include <cpu/intel/turbo.h>
13 #include <cpu/x86/name.h>
14 #include <cpu/intel/smm_reloc.h>
15 #include <intelblocks/cpulib.h>
16 #include <intelblocks/fast_spi.h>
17 #include <intelblocks/mp_init.h>
18 #include <intelblocks/sgx.h>
19 #include <soc/cpu.h>
20 #include <soc/msr.h>
21 #include <soc/pci_devs.h>
22 #include <soc/ramstage.h>
23 #include <soc/systemagent.h>
24 #include <types.h>
25 
26 #include "chip.h"
27 
29 {
30  if (!CONFIG(MAINBOARD_SUPPORTS_COFFEELAKE_CPU))
31  return false;
32 
33  /* IA_UNTRUSTED_MODE is not supported in Sky Lake */
34  msr_t msr = rdmsr(MSR_BIOS_DONE);
35  return !!(msr.lo & ENABLE_IA_UNTRUSTED);
36 }
37 
38 static void configure_misc(void)
39 {
40  config_t *conf = config_of_soc();
41  msr_t msr;
42 
43  msr = rdmsr(IA32_MISC_ENABLE);
44  msr.lo |= (1 << 0); /* Fast String enable */
45  msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
46  wrmsr(IA32_MISC_ENABLE, msr);
47 
48  /* Set EIST status */
49  cpu_set_eist(conf->eist_enable);
50 
51  /* Disable Thermal interrupts */
52  msr.lo = 0;
53  msr.hi = 0;
55 
56  /* Enable package critical interrupt only */
57  msr.lo = 1 << 4;
58  msr.hi = 0;
60 
61  msr = rdmsr(MSR_POWER_CTL);
62  msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input */
63  msr.lo |= (1 << 18); /* Enable Energy/Performance Bias control */
64  msr.lo &= ~POWER_CTL_C1E_MASK; /* Disable C1E */
65  msr.lo |= (1 << 23); /* Lock it */
66  wrmsr(MSR_POWER_CTL, msr);
67 }
68 
69 static void configure_c_states(void)
70 {
71  msr_t msr;
72 
73  /* C-state Interrupt Response Latency Control 0 - package C3 latency */
74  msr.hi = 0;
77 
78  /* C-state Interrupt Response Latency Control 1 - package C6/C7 short */
79  msr.hi = 0;
82 
83  /* C-state Interrupt Response Latency Control 2 - package C6/C7 long */
84  msr.hi = 0;
87 
88  /* C-state Interrupt Response Latency Control 3 - package C8 */
89  msr.hi = 0;
90  msr.lo = IRTL_VALID | IRTL_1024_NS |
93 
94  /* C-state Interrupt Response Latency Control 4 - package C9 */
95  msr.hi = 0;
96  msr.lo = IRTL_VALID | IRTL_1024_NS |
99 
100  /* C-state Interrupt Response Latency Control 5 - package C10 */
101  msr.hi = 0;
102  msr.lo = IRTL_VALID | IRTL_1024_NS |
105 }
106 
107 /* All CPUs including BSP will run the following function. */
108 void soc_core_init(struct device *cpu)
109 {
110  /* Configure Core PRMRR for SGX. */
111  if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE))
113 
114  /* Clear out pending MCEs */
115  /* TODO(adurbin): This should only be done on a cold boot. Also, some
116  * of these banks are core vs package scope. For now every CPU clears
117  * every bank. */
118  mca_configure();
119 
121 
122  /* Configure c-state interrupt response time */
124 
125  /* Configure Enhanced SpeedStep and Thermal Sensors */
126  configure_misc();
127 
128  set_aesni_lock();
129 
130  /* Enable ACPI Timer Emulation via MSR 0x121 */
132 
133  /* Enable Direct Cache Access */
135 
136  /* Set energy policy */
138 
139  /* Enable Turbo */
140  enable_turbo();
141 }
142 
143 static void per_cpu_smm_trigger(void)
144 {
145  /* Relocate the SMM handler. */
146  smm_relocate();
147 }
148 
149 void smm_lock(void)
150 {
151  struct device *sa_dev = pcidev_path_on_root(SA_DEVFN_ROOT);
152  /*
153  * LOCK the SMM memory window and enable normal SMM.
154  * After running this function, only a full reset can
155  * make the SMM registers writable again.
156  */
157  printk(BIOS_DEBUG, "Locking SMM.\n");
159 }
160 
161 static void vmx_configure(void *unused)
162 {
164 }
165 
166 static void fc_lock_configure(void *unused)
167 {
169 }
170 
171 static void post_mp_init(void)
172 {
173  bool failure = false;
174 
175  /* Set Max Ratio */
177 
178  /*
179  * Now that all APs have been relocated as well as the BSP let SMIs
180  * start flowing.
181  */
183 
184  /* Lock down the SMRAM space. */
185  if (CONFIG(HAVE_SMI_HANDLER))
186  smm_lock();
187 
189  failure = true;
190 
191  if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX_ENABLE))
193  failure = true;
194 
196  failure = true;
197 
198  if (failure)
199  printk(BIOS_CRIT, "CRITICAL ERROR: MP post init failed\n");
200 }
201 
202 static void soc_fsp_load(void)
203 {
204  fsps_load();
205 }
206 
207 static const struct mp_ops mp_ops = {
208  /*
209  * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP,
210  * that are set prior to ramstage.
211  * Real MTRRs programming are being done after resource allocation.
212  */
214  .get_cpu_count = get_cpu_count,
215  .get_smm_info = smm_info,
216  .get_microcode_info = get_microcode_info,
217  .pre_mp_smm_init = smm_initialize,
218  .per_cpu_smm_trigger = per_cpu_smm_trigger,
219  .relocation_handler = smm_relocation_handler,
220  .post_mp_init = post_mp_init,
221 };
222 
223 void soc_init_cpus(struct bus *cpu_bus)
224 {
225  /* TODO: Handle mp_init_with_smm failure? */
226  mp_init_with_smm(cpu_bus, &mp_ops);
227 
228  /* Thermal throttle activation offset */
230 }
231 
232 int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
233 {
234  msr_t msr1;
235  msr_t msr2;
236 
237  /*
238  * If PRMRR/SGX is supported the FIT microcode load will set the msr
239  * 0x08b with the Patch revision id one less than the id in the
240  * microcode binary. The PRMRR support is indicated in the MSR
241  * MTRRCAP[12]. If SGX is not enabled, check and avoid reloading the
242  * same microcode during CPU initialization. If SGX is enabled, as
243  * part of SGX BIOS initialization steps, the same microcode needs to
244  * be reloaded after the core PRMRR MSRs are programmed.
245  */
246  msr1 = rdmsr(MTRR_CAP_MSR);
247  msr2 = rdmsr(MSR_PRMRR_PHYS_BASE);
248  if (msr2.lo && (current_patch_id == new_patch_id - 1))
249  return 0;
250  else
251  return (msr1.lo & MTRR_CAP_PRMRR) &&
252  (current_patch_id == new_patch_id - 1);
253 }
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
#define printk(level,...)
Definition: stdlib.h:16
void configure_dca_cap(void)
Definition: common_init.c:172
void set_aesni_lock(void)
Definition: common_init.c:146
void set_energy_perf_bias(u8 policy)
Definition: common_init.c:178
void enable_lapic_tpr(void)
Definition: common_init.c:167
void set_feature_ctrl_vmx(void)
Definition: common_init.c:67
void set_feature_ctrl_lock(void)
Definition: common_init.c:72
#define C_STATE_LATENCY_CONTROL_0_LIMIT
Definition: haswell.h:110
#define MSR_C_STATE_LATENCY_CONTROL_1
Definition: haswell.h:64
#define C_STATE_LATENCY_CONTROL_4_LIMIT
Definition: haswell.h:114
#define MSR_POWER_CTL
Definition: haswell.h:56
#define C_STATE_LATENCY_CONTROL_2_LIMIT
Definition: haswell.h:112
#define C_STATE_LATENCY_CONTROL_3_LIMIT
Definition: haswell.h:113
#define MSR_PRMRR_PHYS_BASE
Definition: haswell.h:54
#define IRTL_VALID
Definition: haswell.h:69
#define C_STATE_LATENCY_CONTROL_1_LIMIT
Definition: haswell.h:111
#define MSR_C_STATE_LATENCY_CONTROL_5
Definition: haswell.h:68
#define MSR_C_STATE_LATENCY_CONTROL_0
Definition: haswell.h:63
#define C_STATE_LATENCY_CONTROL_5_LIMIT
Definition: haswell.h:115
#define MSR_C_STATE_LATENCY_CONTROL_2
Definition: haswell.h:65
#define MSR_C_STATE_LATENCY_CONTROL_3
Definition: haswell.h:66
#define IRTL_1024_NS
Definition: haswell.h:72
#define MSR_C_STATE_LATENCY_CONTROL_4
Definition: haswell.h:67
void smm_relocate(void)
Definition: smmrelocate.c:247
void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase)
Definition: smmrelocate.c:90
void smm_initialize(void)
Definition: smmrelocate.c:227
void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size)
Definition: smmrelocate.c:213
#define G_SMRAME
Definition: smmrelocate.c:25
#define C_BASE_SEG
Definition: smmrelocate.c:26
#define D_LCK
Definition: smmrelocate.c:24
enum cb_err mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops)
Definition: mp_init.c:1145
enum cb_err mp_run_on_all_cpus(void(*func)(void *), void *arg)
Definition: mp_init.c:1002
void mca_configure(void)
Definition: cpulib.c:376
void cpu_set_eist(bool eist_status)
Definition: cpulib.c:250
void cpu_set_max_ratio(void)
Definition: cpulib.c:45
void configure_tcc_thermal_target(void)
Definition: cpulib.c:317
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
@ CONFIG
Definition: dsi_common.h:201
void fsps_load(void)
Definition: silicon_init.c:204
#define SMRAM
Definition: host_bridge.h:47
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define IA32_MISC_ENABLE
Definition: msr.h:45
#define IA32_PACKAGE_THERM_INTERRUPT
Definition: msr.h:53
#define ENERGY_POLICY_NORMAL
Definition: msr.h:50
static __always_inline void wrmsr(unsigned int index, msr_t msr)
Definition: msr.h:157
#define IA32_THERM_INTERRUPT
Definition: msr.h:44
void global_smi_enable_no_pwrbtn(void)
Definition: smm.c:69
#define config_of_soc()
Definition: device.h:394
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_CRIT
BIOS_CRIT - Recovery unlikely.
Definition: loglevel.h:56
void enable_pm_timer_emulation(void)
void prmrr_core_configure(void)
Definition: sgx.c:25
void sgx_configure(void *unused)
Definition: sgx.c:183
int get_cpu_count(void)
Definition: cpu.c:10
void soc_init_cpus(struct bus *cpu_bus)
Definition: cpu.c:183
bool cpu_soc_is_in_untrusted_mode(void)
Definition: cpu.c:33
void soc_core_init(struct device *cpu)
Definition: cpu.c:104
#define MSR_BIOS_DONE
Definition: msr.h:8
#define ENABLE_IA_UNTRUSTED
Definition: msr.h:9
#define SA_DEVFN_ROOT
Definition: pci_devs.h:23
void get_microcode_info(const void **microcode, int *parallel)
Definition: cpu.c:180
int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
Definition: cpu.c:206
void smm_lock(void)
Definition: cpu.c:154
#define POWER_CTL_C1E_MASK
Definition: msr.h:50
static void fc_lock_configure(void *unused)
Definition: cpu.c:166
static void vmx_configure(void *unused)
Definition: cpu.c:161
static void configure_c_states(void)
Definition: cpu.c:69
static void configure_misc(void)
Definition: cpu.c:38
static void soc_fsp_load(void)
Definition: cpu.c:202
static void per_cpu_smm_trigger(void)
Definition: cpu.c:143
static void post_mp_init(void)
Definition: cpu.c:171
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
Definition: device.h:76
Definition: device.h:107
Definition: mp.h:20
void(* pre_mp_init)(void)
Definition: mp.h:27
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
void enable_turbo(void)
Definition: turbo.c:89
#define MTRR_CAP_PRMRR
Definition: mtrr.h:19
#define MTRR_CAP_MSR
Definition: mtrr.h:17