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/pci.h>
5 #include <cpu/x86/mp.h>
6 #include <cpu/x86/msr.h>
7 #include <cpu/intel/smm_reloc.h>
8 #include <cpu/intel/turbo.h>
9 #include <intelblocks/cpulib.h>
10 #include <intelblocks/mp_init.h>
11 #include <soc/cpu.h>
12 #include <soc/msr.h>
13 #include <soc/pci_devs.h>
14 #include <soc/systemagent.h>
15 #include <cpu/x86/mtrr.h>
16 #include <cpu/intel/microcode.h>
18 #include <types.h>
19 
20 #include "chip.h"
21 
23 {
24  msr_t msr;
25 
26  msr = rdmsr(MSR_BIOS_DONE);
27  return !!(msr.lo & ENABLE_IA_UNTRUSTED);
28 }
29 
30 static void soc_fsp_load(void)
31 {
32  fsps_load();
33 }
34 
35 static void configure_misc(void)
36 {
37  msr_t msr;
38 
39  config_t *conf = config_of_soc();
40 
41  msr = rdmsr(IA32_MISC_ENABLE);
42  msr.lo |= (1 << 0); /* Fast String enable */
43  msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
44  wrmsr(IA32_MISC_ENABLE, msr);
45 
46  /* Set EIST status */
47  cpu_set_eist(conf->eist_enable);
48 
49  /* Disable Thermal interrupts */
50  msr.lo = 0;
51  msr.hi = 0;
53 
54  /* Enable package critical interrupt only */
55  msr.lo = 1 << 4;
56  msr.hi = 0;
58 
59  /* Enable PROCHOT */
60  msr = rdmsr(MSR_POWER_CTL);
61  msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input */
62  msr.lo |= (1 << 18); /* Enable Energy/Performance Bias control */
63  msr.lo |= (1 << 23); /* Lock it */
64  wrmsr(MSR_POWER_CTL, msr);
65 }
66 
67 static void configure_c_states(const config_t *const cfg)
68 {
69  msr_t msr;
70 
72  if (cfg->max_package_c_state && (msr.lo & 0xf) >= cfg->max_package_c_state) {
73  msr.lo = (msr.lo & ~0xf) | ((cfg->max_package_c_state - 1) & 0xf);
74  }
75  msr.lo |= CST_CFG_LOCK_MASK;
77 
78  /* C-state Interrupt Response Latency Control 0 - package C3 latency */
79  msr.hi = 0;
82 
83  /* C-state Interrupt Response Latency Control 1 - package C6/C7 short */
84  msr.hi = 0;
87 
88  /* C-state Interrupt Response Latency Control 2 - package C6/C7 long */
89  msr.hi = 0;
92 
93  /* C-state Interrupt Response Latency Control 3 - package C8 */
94  msr.hi = 0;
97 
98  /* C-state Interrupt Response Latency Control 4 - package C9 */
99  msr.hi = 0;
102 
103  /* C-state Interrupt Response Latency Control 5 - package C10 */
104  msr.hi = 0;
107 }
108 
109 /* All CPUs including BSP will run the following function. */
110 void soc_core_init(struct device *cpu)
111 {
112  config_t *cfg = config_of_soc();
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 */
123  configure_c_states(cfg);
124 
125  /* Configure Enhanced SpeedStep and Thermal Sensors */
126  configure_misc();
127 
128  set_aesni_lock();
129 
131 
132  /* Enable Direct Cache Access */
134 
135  /* Set energy policy */
137 
138  if (cfg->cpu_turbo_disable)
139  disable_turbo();
140  else
141  enable_turbo();
142 
143  /* Enable Vmx */
144  set_feature_ctrl_vmx_arg(CONFIG(ENABLE_VMX) && !cfg->disable_vmx);
146 }
147 
148 static void per_cpu_smm_trigger(void)
149 {
150  /* Relocate the SMM handler. */
151  smm_relocate();
152 }
153 
154 void smm_lock(void)
155 {
156  struct device *sa_dev = pcidev_path_on_root(SA_DEVFN_ROOT);
157  /*
158  * LOCK the SMM memory window and enable normal SMM.
159  * After running this function, only a full reset can
160  * make the SMM registers writable again.
161  */
162  printk(BIOS_DEBUG, "Locking SMM.\n");
164 }
165 
166 static void post_mp_init(void)
167 {
168  /* Set Max Ratio */
170 
171  /*
172  * Now that all APs have been relocated as well as the BSP let SMIs
173  * start flowing.
174  */
176 
177  /* Lock down the SMRAM space. */
178  smm_lock();
179 }
180 
181 static const struct mp_ops mp_ops = {
182  /*
183  * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP,
184  * that are set prior to ramstage.
185  * Real MTRRs programming are being done after resource allocation.
186  */
188  .get_cpu_count = get_cpu_count,
189  .get_smm_info = smm_info,
190  .get_microcode_info = get_microcode_info,
191  .pre_mp_smm_init = smm_initialize,
192  .per_cpu_smm_trigger = per_cpu_smm_trigger,
193  .relocation_handler = smm_relocation_handler,
194  .post_mp_init = post_mp_init,
195 };
196 
197 void soc_init_cpus(struct bus *cpu_bus)
198 {
199  /* TODO: Handle mp_init_with_smm failure? */
200  mp_init_with_smm(cpu_bus, &mp_ops);
201 
202  /* Thermal throttle activation offset */
204 }
205 
206 int soc_skip_ucode_update(u32 current_patch_id, u32 new_patch_id)
207 {
208  msr_t msr1;
209  msr_t msr2;
210 
211  /*
212  * If PRMRR/SGX is supported the FIT microcode load will set the msr
213  * 0x08b with the Patch revision id one less than the id in the
214  * microcode binary. The PRMRR support is indicated in the MSR
215  * MTRRCAP[12]. If SGX is not enabled, check and avoid reloading the
216  * same microcode during CPU initialization. If SGX is enabled, as
217  * part of SGX BIOS initialization steps, the same microcode needs to
218  * be reloaded after the core PRMRR MSRs are programmed.
219  */
220  msr1 = rdmsr(MTRR_CAP_MSR);
221  msr2 = rdmsr(MSR_PRMRR_PHYS_BASE);
222  if (msr2.lo && (current_patch_id == new_patch_id - 1))
223  return 0;
224 
225  return (msr1.lo & MTRR_CAP_PRMRR) &&
226  (current_patch_id == new_patch_id - 1);
227 }
#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_lock(void)
Definition: common_init.c:72
void set_feature_ctrl_vmx_arg(bool enable)
Definition: common_init.c:21
#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_PKG_CST_CONFIG_CONTROL
Definition: haswell.h:41
#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
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
void enable_pm_timer_emulation(void)
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
static void configure_misc(void)
Definition: cpu.c:35
static void soc_fsp_load(void)
Definition: cpu.c:30
static void per_cpu_smm_trigger(void)
Definition: cpu.c:148
static void configure_c_states(const config_t *const cfg)
Definition: cpu.c:67
static void post_mp_init(void)
Definition: cpu.c:166
#define CST_CFG_LOCK_MASK
Definition: msr.h:16
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 disable_turbo(void)
Definition: turbo.c:108
void enable_turbo(void)
Definition: turbo.c:89
#define MTRR_CAP_PRMRR
Definition: mtrr.h:19
#define MTRR_CAP_MSR
Definition: mtrr.h:17