coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
model_1067x_init.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 <cpu/cpu.h>
6 #include <cpu/x86/msr.h>
7 #include <cpu/intel/speedstep.h>
8 #include <cpu/x86/cache.h>
9 #include <cpu/x86/name.h>
10 #include <cpu/intel/smm_reloc.h>
11 
12 #include "chip.h"
13 
14 #define MSR_BBL_CR_CTL3 0x11e
15 
16 static void configure_c_states(const int quad)
17 {
18  msr_t msr;
19 
20  /* Find pointer to CPU configuration. */
21  const struct device *lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
22  const struct cpu_intel_model_1067x_config *const conf =
23  (lapic && lapic->chip_info) ? lapic->chip_info : NULL;
24 
25  /* Is C5 requested and supported? */
26  const int c5 = conf && conf->c5 &&
27  (rdmsr(MSR_BBL_CR_CTL3).lo & (3 << 30)) &&
28  !(rdmsr(MSR_FSB_FREQ).lo & (1 << 31));
29  /* Is C6 requested and supported? */
30  const int c6 = conf && conf->c6 &&
31  ((cpuid_edx(5) >> (6 * 4)) & 0xf) && c5;
32 
33  const int cst_range = (c6 ? 6 : (c5 ? 5 : 4)) - 2; /* zero means lvl2 */
34 
36  msr.lo &= ~(1 << 9); // Issue a single stop grant cycle upon stpclk
37  msr.lo |= (1 << 8);
38  if (quad)
39  msr.lo = (msr.lo & ~(7 << 0)) | (4 << 0);
40  if (c5) {
41  msr.lo &= ~(1 << 13);
42  msr.lo &= ~(7 << 0);
43  msr.lo |= (1 << 3); /* Enable dynamic L2. */
44  msr.lo |= (1 << 14); /* Enable deeper sleep */
45  }
46  /* Next two fields seem to be mutually exclusive: */
47  msr.lo &= ~(7 << 4);
48  msr.lo |= (1 << 10); /* Enable IO MWAIT redirection. */
49  if (c6)
50  msr.lo |= (1 << 25);
52 
53  /* Set Processor MWAIT IO BASE */
54  msr.hi = 0;
55  msr.lo = ((PMB0_BASE + 4) & 0xffff) | (((PMB1_BASE + 9) & 0xffff)
56  << 16);
58 
59  /* Set IO Capture Address */
60  msr.hi = 0;
61  msr.lo = ((PMB0_BASE + 4) & 0xffff) | ((cst_range & 0xffff) << 16);
63 
64  if (c5) {
65  msr = rdmsr(MSR_BBL_CR_CTL3);
66  msr.lo &= ~(7 << 25);
67  msr.lo |= (2 << 25);
68  msr.lo &= ~(3 << 30);
69  msr.lo |= (1 << 30);
70  wrmsr(MSR_BBL_CR_CTL3, msr);
71  }
72 }
73 
74 static void configure_p_states(const char stepping, const char cores)
75 {
76  msr_t msr;
77 
78  /* Find pointer to CPU configuration. */
79  const struct device *lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
80  struct cpu_intel_model_1067x_config *const conf =
81  (lapic && lapic->chip_info) ? lapic->chip_info : NULL;
82 
84  /* Super LFM supported? */
85  if (conf && conf->slfm && (msr.lo & (1 << 27)))
86  msr.lo |= (1 << 28); /* Enable Super LFM. */
88 
89  if (rdmsr(MSR_FSB_CLOCK_VCC).hi & (1 << (63 - 32))) {
90  /* Turbo supported? */
91  if ((stepping == 0xa) && (cores < 4)) {
92  msr = rdmsr(MSR_FSB_FREQ);
93  msr.lo |= (1 << 3); /* Enable hysteresis. */
94  wrmsr(MSR_FSB_FREQ, msr);
95  }
96  msr = rdmsr(IA32_PERF_CTL);
97  msr.hi &= ~(1 << (32 - 32)); /* Clear turbo disable. */
98  wrmsr(IA32_PERF_CTL, msr);
99  }
100 
102  msr.lo &= ~(1 << 11); /* Enable hw coordination. */
103  msr.lo |= (1 << 15); /* Lock config until next reset. */
105 }
106 
107 #define MSR_EMTTM_CR_TABLE(x) (0xa8 + (x))
108 #define MSR_EMTTM_TABLE_NUM 6
109 static void configure_emttm_tables(void)
110 {
111  int i;
112  int num_states, pstate_idx;
113  msr_t msr;
114  sst_table_t pstates;
115 
116  /* Gather p-state information. */
117  speedstep_gen_pstates(&pstates);
118 
119  /* Never turbo mode or Super LFM. */
120  num_states = pstates.num_states;
121  if (pstates.states[0].is_turbo)
122  --num_states;
123  if (pstates.states[pstates.num_states - 1].is_slfm)
124  --num_states;
125  /* Repeat lowest p-state if we haven't enough states. */
126  const int num_lowest_pstate =
127  (num_states < MSR_EMTTM_TABLE_NUM)
128  ? (MSR_EMTTM_TABLE_NUM - num_states) + 1
129  : 1;
130  /* Start from the lowest entry but skip Super LFM. */
131  if (pstates.states[pstates.num_states - 1].is_slfm)
132  pstate_idx = pstates.num_states - 2;
133  else
134  pstate_idx = pstates.num_states - 1;
135  for (i = 0; i < MSR_EMTTM_TABLE_NUM; ++i) {
136  if (i >= num_lowest_pstate)
137  --pstate_idx;
138  const sst_state_t *const pstate = &pstates.states[pstate_idx];
139  printk(BIOS_DEBUG, "writing P-State %d: %d, %d, "
140  "%2d, 0x%02x, %d; encoded: 0x%04x\n",
141  pstate_idx, pstate->dynfsb, pstate->nonint,
142  pstate->ratio, pstate->vid, pstate->power,
143  SPEEDSTEP_ENCODE_STATE(*pstate));
144  msr.hi = 0;
145  msr.lo = SPEEDSTEP_ENCODE_STATE(pstates.states[pstate_idx]) &
146  /* Don't set half ratios. */
148  wrmsr(MSR_EMTTM_CR_TABLE(i), msr);
149  }
150 
151  msr = rdmsr(MSR_EMTTM_CR_TABLE(5));
152  msr.lo |= (1 << 31); /* lock tables */
153  wrmsr(MSR_EMTTM_CR_TABLE(5), msr);
154 }
155 
156 #define IA32_PECI_CTL 0x5a0
157 
158 static void configure_misc(const int eist, const int tm2, const int emttm)
159 {
160  msr_t msr;
161 
162  const u32 sub_cstates = cpuid_edx(5);
163 
164  msr = rdmsr(IA32_MISC_ENABLE);
165  msr.lo |= (1 << 3); /* TM1 enable */
166  if (tm2)
167  msr.lo |= (1 << 13); /* TM2 enable */
168  msr.lo |= (1 << 17); /* Bidirectional PROCHOT# */
169  msr.lo |= (1 << 18); /* MONITOR/MWAIT enable */
170 
171  msr.lo |= (1 << 10); /* FERR# multiplexing */
172 
173  if (eist)
174  msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
175 
176  /* Enable C2E */
177  if (((sub_cstates >> (2 * 4)) & 0xf) >= 2)
178  msr.lo |= (1 << 26);
179 
180  /* Enable C4E */
181  if (((sub_cstates >> (4 * 4)) & 0xf) >= 2) {
182  msr.hi |= (1 << (32 - 32)); // C4E
183  msr.hi |= (1 << (33 - 32)); // Hard C4E
184  }
185 
186  /* Enable EMTTM */
187  if (emttm)
188  msr.hi |= (1 << (36 - 32));
189 
190  /* Enable turbo mode */
191  if (rdmsr(MSR_FSB_CLOCK_VCC).hi & (1 << (63 - 32)))
192  msr.hi &= ~(1 << (38 - 32));
193 
194  wrmsr(IA32_MISC_ENABLE, msr);
195 
196  if (eist) {
197  msr.lo |= (1 << 20); /* Lock Enhanced SpeedStep Enable */
198  wrmsr(IA32_MISC_ENABLE, msr);
199  }
200 
201  /* Enable PECI
202  WARNING: due to Erratum AW67 described in Intel document #318733
203  the microcode must be updated before this MSR is written to. */
204  msr = rdmsr(IA32_PECI_CTL);
205  msr.lo |= 1;
206  wrmsr(IA32_PECI_CTL, msr);
207 }
208 
209 #define PIC_SENS_CFG 0x1aa
210 static void configure_pic_thermal_sensors(const int tm2, const int quad)
211 {
212  msr_t msr;
213 
214  msr = rdmsr(PIC_SENS_CFG);
215 
216  if (quad)
217  msr.lo |= (1 << 31);
218  else
219  msr.lo &= ~(1 << 31);
220  if (tm2)
221  msr.lo |= (1 << 20); /* Enable TM1 if TM2 fails. */
222  msr.lo |= (1 << 21); // inter-core lock TM1
223  msr.lo |= (1 << 4); // Enable bypass filter /* What does it do? */
224 
225  wrmsr(PIC_SENS_CFG, msr);
226 }
227 
228 static void model_1067x_init(struct device *cpu)
229 {
230  char processor_name[49];
231 
232  /* Gather some information: */
233 
234  const struct cpuid_result cpuid1 = cpuid(1);
235 
236  /* Read stepping. */
237  const char stepping = cpuid1.eax & 0xf;
238  /* Read number of cores. */
239  const char cores = (cpuid1.ebx >> 16) & 0xf;
240  /* Is this a quad core? */
241  const char quad = cores > 2;
242  /* Is this even a multiprocessor? */
243  const char mp = cores > 1;
244 
245  /* Enable EMTTM on uni- and on multi-processors if it's not disabled. */
246  const char emttm = !mp || !(rdmsr(MSR_EXTENDED_CONFIG).lo & 4);
247 
248  /* Is enhanced speedstep supported? */
249  const char eist = (cpuid1.ecx & (1 << 7)) &&
250  !(rdmsr(IA32_PLATFORM_ID).lo & (1 << 17));
251  /* Test for TM2 only if EIST is available. */
252  const char tm2 = eist && (cpuid1.ecx & (1 << 8));
253 
254  /* Print processor name */
256  printk(BIOS_INFO, "CPU: %s.\n", processor_name);
257 
258  /* Configure C States */
259  configure_c_states(quad);
260 
261  /* Configure P States */
263 
264  /* EMTTM */
265  if (emttm)
267 
268  /* Configure Enhanced SpeedStep and Thermal Sensors */
269  configure_misc(eist, tm2, emttm);
270 
271  /* PIC thermal sensor control */
273 }
274 
275 static struct device_operations cpu_dev_ops = {
277 };
278 
279 static const struct cpu_device_id cpu_table[] = {
280  { X86_VENDOR_INTEL, 0x10676 },
281  { X86_VENDOR_INTEL, 0x10677 },
282  { X86_VENDOR_INTEL, 0x1067A },
283  { 0, 0 },
284 };
285 
286 static const struct cpu_driver driver __cpu_driver = {
287  .ops = &cpu_dev_ops,
288  .id_table = cpu_table,
289 };
290 
292  CHIP_NAME("Intel Penryn CPU")
293 };
static unsigned int cpuid_edx(unsigned int op)
Definition: cpu.h:119
#define X86_VENDOR_INTEL
Definition: cpu.h:138
#define printk(level,...)
Definition: stdlib.h:16
#define SPEEDSTEP_APIC_MAGIC
Definition: chip.h:4
#define MSR_PKG_CST_CONFIG_CONTROL
Definition: haswell.h:41
static char processor_name[49]
Definition: mp_init.c:37
struct device * dev_find_lapic(unsigned int apic_id)
Given a Local APIC ID, find the device structure.
Definition: device_util.c:17
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_PLATFORM_ID
Definition: msr.h:18
#define CHIP_NAME(X)
Definition: device.h:32
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define MSR_BBL_CR_CTL3
#define IA32_PECI_CTL
static void configure_emttm_tables(void)
static const struct cpu_driver driver __cpu_driver
static void configure_p_states(const char stepping, const char cores)
static void configure_misc(const int eist, const int tm2, const int emttm)
static void model_1067x_init(struct device *cpu)
static void configure_pic_thermal_sensors(const int tm2, const int quad)
struct chip_operations cpu_intel_model_1067x_ops
static void configure_c_states(const int quad)
static const struct cpu_device_id cpu_table[]
static struct device_operations cpu_dev_ops
#define MSR_EMTTM_CR_TABLE(x)
#define MSR_EMTTM_TABLE_NUM
#define PIC_SENS_CFG
void fill_processor_name(char *processor_name)
Definition: name.c:8
u32 cpuid
const char * stepping
void speedstep_gen_pstates(sst_table_t *const table)
Generate full p-states table from processor parameters.
Definition: speedstep.c:101
#define MSR_FSB_CLOCK_VCC
Definition: speedstep.h:25
#define MSR_EXTENDED_CONFIG
Definition: speedstep.h:29
#define MSR_PMG_IO_BASE_ADDR
Definition: speedstep.h:27
#define SPEEDSTEP_RATIO_NONINT
Definition: speedstep.h:45
#define PMB1_BASE
Definition: speedstep.h:19
#define MSR_FSB_FREQ
Definition: speedstep.h:24
#define PMB0_BASE
Definition: speedstep.h:14
#define MSR_PMG_IO_CAPTURE_ADDR
Definition: speedstep.h:28
#define SPEEDSTEP_ENCODE_STATE(state)
Definition: speedstep.h:58
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
Definition: cpu.h:13
struct device_operations * ops
Definition: cpu.h:14
uint32_t ecx
Definition: cpu.h:32
uint32_t ebx
Definition: cpu.h:31
uint32_t eax
Definition: cpu.h:30
void(* init)(struct device *dev)
Definition: device.h:42
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
uint8_t is_turbo
Definition: speedstep.h:37
uint8_t is_slfm
Definition: speedstep.h:38
uint8_t dynfsb
Definition: speedstep.h:33
uint32_t power
Definition: speedstep.h:39
uint8_t ratio
Definition: speedstep.h:35
uint8_t vid
Definition: speedstep.h:36
uint8_t nonint
Definition: speedstep.h:34
sst_state_t states[SPEEDSTEP_MAX_STATES]
Definition: speedstep.h:80
int num_states
Definition: speedstep.h:81