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-or-later */
2 
3 #include <console/console.h>
4 #include <console/debug.h>
5 #include <intelblocks/cpulib.h>
6 #include <cpu/cpu.h>
7 #include <cpu/x86/mtrr.h>
8 #include <cpu/x86/mp.h>
9 #include <cpu/intel/turbo.h>
10 #include <soc/msr.h>
11 #include <soc/cpu.h>
12 #include <soc/soc_util.h>
13 #include <soc/smmrelocate.h>
14 #include <soc/util.h>
15 #include <assert.h>
16 #include "chip.h"
17 #include <cpu/intel/smm_reloc.h>
19 #include <types.h>
20 
21 static const config_t *chip_config = NULL;
22 
24 {
25  /* IA_UNTRUSTED_MODE is not supported in Skylake */
26  return false;
27 }
28 
29 static void xeon_configure_mca(void)
30 {
31  msr_t msr;
32  struct cpuid_result cpuid_regs;
33 
34  /* Check feature flag in CPUID.(EAX=1):EDX[7]==1 MCE
35  * and CPUID.(EAX=1):EDX[14]==1 MCA*/
36  cpuid_regs = cpuid(1);
37  if ((cpuid_regs.edx & (1<<7 | 1<<14)) != (1<<7 | 1<<14))
38  return;
39 
40  msr = rdmsr(IA32_MCG_CAP);
41  if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) {
42  /* Enable all error logging */
43  msr.lo = msr.hi = 0xffffffff;
44  wrmsr(IA32_MCG_CTL, msr);
45  }
46 
47  /* TODO(adurbin): This should only be done on a cold boot. Also, some
48  of these banks are core vs package scope. For now every CPU clears
49  every bank. */
50  mca_configure();
51 }
52 
53 static void xeon_sp_core_init(struct device *cpu)
54 {
55  msr_t msr;
56 
57  printk(BIOS_INFO, "%s dev: %s, cpu: %d, apic_id: 0x%x\n",
58  __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id);
60 
61  /* set MSR_PKG_CST_CONFIG_CONTROL - scope per core*/
62  msr.hi = 0;
65 
66  /* Enable Energy Perf Bias Access, Dynamic switching and lock MSR */
67  msr = rdmsr(MSR_POWER_CTL);
70  wrmsr(MSR_POWER_CTL, msr);
71 
72  /* Set P-State ratio */
74  msr.lo &= ~PSTATE_REQ_MASK;
75  msr.lo |= (chip_config->pstate_req_ratio << PSTATE_REQ_SHIFT);
77 
78  /*
79  * Set HWP base feature, EPP reg enumeration, lock thermal and msr
80  * TODO: Set LOCK_MISC_PWR_MGMT_MSR, Unexpected Exception if you
81  * lock & issue wrmsr on every thread
82  * This is package level MSR. Need to check if it updates correctly on
83  * multi-socket platform.
84  */
85  msr = rdmsr(MSR_MISC_PWR_MGMT);
86  if (!(msr.lo & LOCK_MISC_PWR_MGMT_MSR)) { /* if already locked skip update */
90  }
91 
92  /* TODO MSR_VR_MISC_CONFIG */
93 
94  /* Set current limit lock */
96  msr.lo |= CURRENT_LIMIT_LOCK;
98 
99  /* Set Turbo Ratio Limits */
100  msr.lo = chip_config->turbo_ratio_limit & 0xffffffff;
101  msr.hi = (chip_config->turbo_ratio_limit >> 32) & 0xffffffff;
103 
104  /* Set Turbo Ratio Limit Cores */
105  msr.lo = chip_config->turbo_ratio_limit_cores & 0xffffffff;
106  msr.hi = (chip_config->turbo_ratio_limit_cores >> 32) & 0xffffffff;
108 
109  /* set Turbo Activation ratio */
110  msr.hi = 0;
112  msr.lo |= MAX_NON_TURBO_RATIO;
114 
115  /* Enable Fast Strings */
116  msr = rdmsr(IA32_MISC_ENABLE);
118  wrmsr(IA32_MISC_ENABLE, msr);
119 
120  /* Set energy policy */
123  msr.hi = 0;
125 
126  /* Enable Turbo */
127  enable_turbo();
128 
129  /* Enable speed step. */
130  if (get_turbo_state() == TURBO_ENABLED) {
131  msr = rdmsr(IA32_MISC_ENABLE);
132  msr.lo |= SPEED_STEP_ENABLE_BIT;
133  wrmsr(IA32_MISC_ENABLE, msr);
134  }
135 
136  /* Clear out pending MCEs */
138 }
139 
140 static struct device_operations cpu_dev_ops = {
142 };
143 
144 static const struct cpu_device_id cpu_table[] = {
145  /* Skylake-SP A0/A1 CPUID 0x506f0*/
147  /* Skylake-SP B0 CPUID 0x506f1*/
149  /* Skylake-SP 4 CPUID 0x50654*/
151  {0, 0},
152 };
153 
154 static const struct cpu_driver driver __cpu_driver = {
155  .ops = &cpu_dev_ops,
156  .id_table = cpu_table,
157 };
158 
159 static void set_max_turbo_freq(void)
160 {
161  msr_t msr, perf_ctl;
162 
163  FUNC_ENTER();
164  perf_ctl.hi = 0;
165 
166  /* Check for configurable TDP option */
167  if (get_turbo_state() == TURBO_ENABLED) {
169  perf_ctl.lo = (msr.lo & 0xff) << 8;
170  } else if (cpu_config_tdp_levels()) {
171  /* Set to nominal TDP ratio */
173  perf_ctl.lo = (msr.lo & 0xff) << 8;
174  } else {
175  /* Platform Info bits 15:8 give max ratio */
176  msr = rdmsr(MSR_PLATFORM_INFO);
177  perf_ctl.lo = msr.lo & 0xff00;
178  }
179  wrmsr(IA32_PERF_CTL, perf_ctl);
180 
181  printk(BIOS_DEBUG, "cpu: frequency set to %d\n",
182  ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
183  FUNC_EXIT();
184 }
185 
186 /*
187  * Do essential initialization tasks before APs can be fired up
188  *
189  * Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This
190  * creates the MTRR solution that the APs will use. Otherwise APs will try to
191  * apply the incomplete solution as the BSP is calculating it.
192  */
193 static void pre_mp_init(void)
194 {
195  printk(BIOS_DEBUG, "%s: entry\n", __func__);
196 
198  x86_mtrr_check();
199 }
200 
201 static void post_mp_init(void)
202 {
203  /* Set Max Ratio */
205 
206  if (CONFIG(HAVE_SMI_HANDLER))
208 }
209 
210 /*
211  * CPU initialization recipe
212  *
213  * Note that no microcode update is passed to the init function. CSE updates
214  * the microcode on all cores before releasing them from reset. That means that
215  * the BSP and all APs will come up with the same microcode revision.
216  */
217 static const struct mp_ops mp_ops = {
219  .get_cpu_count = get_platform_thread_count,
220  .get_smm_info = get_smm_info,
221  .pre_mp_smm_init = smm_southbridge_clear_state,
222  .relocation_handler = smm_relocation_handler,
223  .post_mp_init = post_mp_init,
224 };
225 
226 void xeon_sp_init_cpus(struct device *dev)
227 {
228  FUNC_ENTER();
229 
230  /*
231  * This gets used in cpu device callback. Other than cpu 0,
232  * rest of the CPU devices do not have
233  * chip_info updated. Global chip_config is used as workaround
234  */
235  chip_config = dev->chip_info;
236 
238 
239  /* calls src/cpu/x86/mp_init.c */
240  /* TODO: Handle mp_init_with_smm failure? */
242 
243  /* update numa domain for all cpu devices */
245 
246  FUNC_EXIT();
247 }
int cpu_index(void)
Definition: cpu.c:332
#define X86_VENDOR_INTEL
Definition: cpu.h:138
#define assert(statement)
Definition: assert.h:74
#define printk(level,...)
Definition: stdlib.h:16
#define MSR_MISC_PWR_MGMT
Definition: haswell.h:51
#define MSR_POWER_CTL
Definition: haswell.h:56
#define MSR_TURBO_RATIO_LIMIT
Definition: haswell.h:53
#define MSR_TURBO_ACTIVATION_RATIO
Definition: haswell.h:99
#define MSR_VR_CURRENT_CONFIG
Definition: haswell.h:86
int cpu_config_tdp_levels(void)
Definition: haswell_init.c:300
#define MSR_CONFIG_TDP_NOMINAL
Definition: haswell.h:95
#define MSR_PKG_CST_CONFIG_CONTROL
Definition: haswell.h:41
#define CPU_BCLK
Definition: haswell.h:35
void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase)
Definition: smmrelocate.c:90
enum cb_err mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops *mp_ops)
Definition: mp_init.c:1145
void x86_mtrr_check(void)
Definition: mtrr.c:836
void x86_setup_mtrrs_with_detect(void)
Definition: mtrr.c:823
#define CPUID_SKYLAKE_SP_4
Definition: cpu_ids.h:13
#define CPUID_SKYLAKE_SP_B0
Definition: cpu_ids.h:12
#define CPUID_SKYLAKE_SP_A0_A1
Definition: cpu_ids.h:11
void mca_configure(void)
Definition: cpulib.c:376
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
@ CONFIG
Definition: dsi_common.h:201
#define MSR_PLATFORM_INFO
Definition: fsb.c:16
#define FUNC_ENTER()
Definition: debug.h:17
#define FUNC_EXIT()
Definition: debug.h:18
#define FAST_STRINGS_ENABLE_BIT
Definition: msr.h:46
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define IA32_MISC_ENABLE
Definition: msr.h:45
#define IA32_PERF_CTL
Definition: msr.h:43
static __always_inline void wrmsr(unsigned int index, msr_t msr)
Definition: msr.h:157
#define IA32_MCG_CAP
Definition: msr.h:39
#define SPEED_STEP_ENABLE_BIT
Definition: msr.h:47
void global_smi_enable(void)
Set the EOS bit and enable SMI generation from southbridge.
Definition: smi_util.c:60
void config_reset_cpl3_csrs(void)
Definition: soc_util.c:73
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void smm_southbridge_clear_state(void)
Definition: smm.c:22
u32 cpuid
bool cpu_soc_is_in_untrusted_mode(void)
Definition: cpu.c:33
static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size)
Definition: cpu.c:149
#define IA32_MCG_CTL
Definition: msr.h:19
#define IA32_MCG_CAP_CTL_P_MASK
Definition: msr.h:18
#define CURRENT_LIMIT_LOCK
Definition: msr.h:81
#define MSR_TURBO_RATIO_LIMIT_CORES
Definition: msr.h:76
#define PROCHOT_LOCK_ENABLE
Definition: msr.h:51
#define HWP_EPP_ENUM_ENABLE
Definition: msr.h:66
#define ENERGY_PERF_BIAS_ACCESS_ENABLE
Definition: msr.h:45
#define PWR_PERF_TUNING_DYN_SWITCHING_ENABLE
Definition: msr.h:49
#define MSR_IA32_PERF_CTRL
Definition: msr.h:56
#define PKG_CSTATE_NO_LIMIT
Definition: msr.h:30
#define PSTATE_REQ_MASK
Definition: msr.h:58
#define LOCK_MISC_PWR_MGMT_MSR
Definition: msr.h:68
#define EPB_ENERGY_POLICY_SHIFT
Definition: msr.h:90
#define LOCK_THERM_INT
Definition: msr.h:70
#define CFG_LOCK_ENABLE
Definition: msr.h:32
#define MSR_ENERGY_PERF_BIAS_CONFIG
Definition: msr.h:89
#define EPB_ENERGY_POLICY_MASK
Definition: msr.h:91
#define PSTATE_REQ_SHIFT
Definition: msr.h:57
#define HWP_ENUM_ENABLE
Definition: msr.h:64
#define MSR_IA32_ENERGY_PERF_BIAS
Definition: msr.h:23
#define MAX_NON_TURBO_RATIO
Definition: msr.h:86
int get_platform_thread_count(void)
Definition: util.c:84
void xeonsp_init_cpu_config(void)
static void set_max_turbo_freq(void)
Definition: cpu.c:159
static void xeon_configure_mca(void)
Definition: cpu.c:29
static const struct cpu_driver driver __cpu_driver
Definition: cpu.c:154
static void xeon_sp_core_init(struct device *cpu)
Definition: cpu.c:53
static const config_t * chip_config
Definition: cpu.c:21
void xeon_sp_init_cpus(struct device *dev)
Definition: cpu.c:226
static void pre_mp_init(void)
Definition: cpu.c:193
static const struct cpu_device_id cpu_table[]
Definition: cpu.c:144
static struct device_operations cpu_dev_ops
Definition: cpu.c:140
static void post_mp_init(void)
Definition: cpu.c:201
#define NULL
Definition: stddef.h:19
unsigned int apic_id
Definition: path.h:72
Definition: cpu.h:13
struct device_operations * ops
Definition: cpu.h:14
uint32_t edx
Definition: cpu.h:33
void(* init)(struct device *dev)
Definition: device.h:42
struct apic_path apic
Definition: path.h:119
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
DEVTREE_CONST void * chip_info
Definition: device.h:164
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
int get_turbo_state(void)
Definition: turbo.c:75
void enable_turbo(void)
Definition: turbo.c:89
@ TURBO_ENABLED
Definition: turbo.h:18