blob: 45c1a25bc093577e81e2cdc2af3acf3fd6ef51f3 [file] [log] [blame]
Aaron Durbin76c37002012-10-30 09:03:43 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 * MA 02110-1301 USA
21 */
22
23#include <console/console.h>
24#include <device/device.h>
25#include <device/pci.h>
26#include <string.h>
27#include <arch/acpi.h>
28#include <cpu/cpu.h>
29#include <cpu/x86/mtrr.h>
30#include <cpu/x86/msr.h>
31#include <cpu/x86/lapic.h>
32#include <cpu/intel/microcode.h>
33#include <cpu/intel/speedstep.h>
34#include <cpu/intel/turbo.h>
35#include <cpu/x86/cache.h>
36#include <cpu/x86/name.h>
37#include <pc80/mc146818rtc.h>
38#include <usbdebug.h>
39#include "haswell.h"
40#include "chip.h"
41
42/*
43 * List of suported C-states in this processor
44 *
45 * Latencies are typical worst-case package exit time in uS
46 * taken from the SandyBridge BIOS specification.
47 */
48#if 0
49static acpi_cstate_t cstate_map[] = {
50 { /* 0: C0 */
51 },{ /* 1: C1 */
52 .latency = 1,
53 .power = 1000,
54 .resource = {
55 .addrl = 0x00, /* MWAIT State 0 */
56 .space_id = ACPI_ADDRESS_SPACE_FIXED,
57 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
58 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
59 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
60 }
61 },
62 { /* 2: C1E */
63 .latency = 1,
64 .power = 1000,
65 .resource = {
66 .addrl = 0x01, /* MWAIT State 0 Sub-state 1 */
67 .space_id = ACPI_ADDRESS_SPACE_FIXED,
68 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
69 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
70 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
71 }
72 },
73 { /* 3: C3 */
74 .latency = 63,
75 .power = 500,
76 .resource = {
77 .addrl = 0x10, /* MWAIT State 1 */
78 .space_id = ACPI_ADDRESS_SPACE_FIXED,
79 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
80 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
81 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
82 }
83 },
84 { /* 4: C6 */
85 .latency = 87,
86 .power = 350,
87 .resource = {
88 .addrl = 0x20, /* MWAIT State 2 */
89 .space_id = ACPI_ADDRESS_SPACE_FIXED,
90 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
91 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
92 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
93 }
94 },
95 { /* 5: C7 */
96 .latency = 90,
97 .power = 200,
98 .resource = {
99 .addrl = 0x30, /* MWAIT State 3 */
100 .space_id = ACPI_ADDRESS_SPACE_FIXED,
101 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
102 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
103 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
104 }
105 },
106 { /* 6: C7S */
107 .latency = 90,
108 .power = 200,
109 .resource = {
110 .addrl = 0x31, /* MWAIT State 3 Sub-state 1 */
111 .space_id = ACPI_ADDRESS_SPACE_FIXED,
112 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
113 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
114 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
115 }
116 },
117 { 0 }
118};
119#endif
120
121/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
122static const u8 power_limit_time_sec_to_msr[] = {
123 [0] = 0x00,
124 [1] = 0x0a,
125 [2] = 0x0b,
126 [3] = 0x4b,
127 [4] = 0x0c,
128 [5] = 0x2c,
129 [6] = 0x4c,
130 [7] = 0x6c,
131 [8] = 0x0d,
132 [10] = 0x2d,
133 [12] = 0x4d,
134 [14] = 0x6d,
135 [16] = 0x0e,
136 [20] = 0x2e,
137 [24] = 0x4e,
138 [28] = 0x6e,
139 [32] = 0x0f,
140 [40] = 0x2f,
141 [48] = 0x4f,
142 [56] = 0x6f,
143 [64] = 0x10,
144 [80] = 0x30,
145 [96] = 0x50,
146 [112] = 0x70,
147 [128] = 0x11,
148};
149
150/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
151static const u8 power_limit_time_msr_to_sec[] = {
152 [0x00] = 0,
153 [0x0a] = 1,
154 [0x0b] = 2,
155 [0x4b] = 3,
156 [0x0c] = 4,
157 [0x2c] = 5,
158 [0x4c] = 6,
159 [0x6c] = 7,
160 [0x0d] = 8,
161 [0x2d] = 10,
162 [0x4d] = 12,
163 [0x6d] = 14,
164 [0x0e] = 16,
165 [0x2e] = 20,
166 [0x4e] = 24,
167 [0x6e] = 28,
168 [0x0f] = 32,
169 [0x2f] = 40,
170 [0x4f] = 48,
171 [0x6f] = 56,
172 [0x10] = 64,
173 [0x30] = 80,
174 [0x50] = 96,
175 [0x70] = 112,
176 [0x11] = 128,
177};
178
179int cpu_config_tdp_levels(void)
180{
181 msr_t platform_info;
182
183 /* Bits 34:33 indicate how many levels supported */
184 platform_info = rdmsr(MSR_PLATFORM_INFO);
185 return (platform_info.hi >> 1) & 3;
186}
187
188/*
189 * Configure processor power limits if possible
190 * This must be done AFTER set of BIOS_RESET_CPL
191 */
192void set_power_limits(u8 power_limit_1_time)
193{
194 msr_t msr = rdmsr(MSR_PLATFORM_INFO);
195 msr_t limit;
196 unsigned power_unit;
197 unsigned tdp, min_power, max_power, max_time;
198 u8 power_limit_1_val;
199
200 if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
201 return;
202
203 if (!(msr.lo & PLATFORM_INFO_SET_TDP))
204 return;
205
206 /* Get units */
207 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
208 power_unit = 2 << ((msr.lo & 0xf) - 1);
209
210 /* Get power defaults for this SKU */
211 msr = rdmsr(MSR_PKG_POWER_SKU);
212 tdp = msr.lo & 0x7fff;
213 min_power = (msr.lo >> 16) & 0x7fff;
214 max_power = msr.hi & 0x7fff;
215 max_time = (msr.hi >> 16) & 0x7f;
216
217 printk(BIOS_DEBUG, "CPU TDP: %u Watts\n", tdp / power_unit);
218
219 if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
220 power_limit_1_time = power_limit_time_msr_to_sec[max_time];
221
222 if (min_power > 0 && tdp < min_power)
223 tdp = min_power;
224
225 if (max_power > 0 && tdp > max_power)
226 tdp = max_power;
227
228 power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
229
230 /* Set long term power limit to TDP */
231 limit.lo = 0;
232 limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
233 limit.lo |= PKG_POWER_LIMIT_EN;
234 limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
235 PKG_POWER_LIMIT_TIME_SHIFT;
236
237 /* Set short term power limit to 1.25 * TDP */
238 limit.hi = 0;
239 limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK;
240 limit.hi |= PKG_POWER_LIMIT_EN;
241 /* Power limit 2 time is only programmable on SNB EP/EX */
242
243 wrmsr(MSR_PKG_POWER_LIMIT, limit);
244
245 /* Use nominal TDP values for CPUs with configurable TDP */
246 if (cpu_config_tdp_levels()) {
247 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
248 limit.hi = 0;
249 limit.lo = msr.lo & 0xff;
250 wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
251 }
252}
253
254#if 0
255static void configure_c_states(void)
256{
257 msr_t msr;
258
259 msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
260 msr.lo |= (1 << 28); // C1 Auto Undemotion Enable
261 msr.lo |= (1 << 27); // C3 Auto Undemotion Enable
262 msr.lo |= (1 << 26); // C1 Auto Demotion Enable
263 msr.lo |= (1 << 25); // C3 Auto Demotion Enable
264 msr.lo &= ~(1 << 10); // Disable IO MWAIT redirection
265 msr.lo |= 7; // No package C-state limit
266 wrmsr(MSR_PMG_CST_CONFIG_CONTROL, msr);
267
268 msr = rdmsr(MSR_PMG_IO_CAPTURE_BASE);
269 msr.lo &= ~0x7ffff;
270 msr.lo |= (PMB0_BASE + 4); // LVL_2 base address
271 msr.lo |= (2 << 16); // CST Range: C7 is max C-state
272 wrmsr(MSR_PMG_IO_CAPTURE_BASE, msr);
273
274 msr = rdmsr(MSR_MISC_PWR_MGMT);
275 msr.lo &= ~(1 << 0); // Enable P-state HW_ALL coordination
276 wrmsr(MSR_MISC_PWR_MGMT, msr);
277
278 msr = rdmsr(MSR_POWER_CTL);
279 msr.lo |= (1 << 18); // Enable Energy Perf Bias MSR 0x1b0
280 msr.lo |= (1 << 1); // C1E Enable
281 msr.lo |= (1 << 0); // Bi-directional PROCHOT#
282 wrmsr(MSR_POWER_CTL, msr);
283
284 /* C3 Interrupt Response Time Limit */
285 msr.hi = 0;
286 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x50;
287 wrmsr(MSR_PKGC3_IRTL, msr);
288
289 /* C6 Interrupt Response Time Limit */
290 msr.hi = 0;
291 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x68;
292 wrmsr(MSR_PKGC6_IRTL, msr);
293
294 /* C7 Interrupt Response Time Limit */
295 msr.hi = 0;
296 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x6D;
297 wrmsr(MSR_PKGC7_IRTL, msr);
298
299 /* Primary Plane Current Limit */
300 msr = rdmsr(MSR_PP0_CURRENT_CONFIG);
301 msr.lo &= ~0x1fff;
302 msr.lo |= PP0_CURRENT_LIMIT;
303 wrmsr(MSR_PP0_CURRENT_CONFIG, msr);
304
305 /* Secondary Plane Current Limit */
306 msr = rdmsr(MSR_PP1_CURRENT_CONFIG);
307 msr.lo &= ~0x1fff;
308 if (cpuid_eax(1) >= 0x30600)
309 msr.lo |= PP1_CURRENT_LIMIT_IVB;
310 else
311 msr.lo |= PP1_CURRENT_LIMIT_SNB;
312 wrmsr(MSR_PP1_CURRENT_CONFIG, msr);
313}
314#endif
315
316static void configure_thermal_target(void)
317{
318 struct cpu_intel_haswell_config *conf;
319 device_t lapic;
320 msr_t msr;
321
322 /* Find pointer to CPU configuration */
323 lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
324 if (!lapic || !lapic->chip_info)
325 return;
326 conf = lapic->chip_info;
327
328 /* Set TCC activaiton offset if supported */
329 msr = rdmsr(MSR_PLATFORM_INFO);
330 if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
331 msr = rdmsr(MSR_TEMPERATURE_TARGET);
332 msr.lo &= ~(0xf << 24); /* Bits 27:24 */
333 msr.lo |= (conf->tcc_offset & 0xf) << 24;
334 wrmsr(MSR_TEMPERATURE_TARGET, msr);
335 }
336}
337
338static void configure_misc(void)
339{
340 msr_t msr;
341
342 msr = rdmsr(IA32_MISC_ENABLE);
343 msr.lo |= (1 << 0); /* Fast String enable */
344 msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
345 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
346 wrmsr(IA32_MISC_ENABLE, msr);
347
348 /* Disable Thermal interrupts */
349 msr.lo = 0;
350 msr.hi = 0;
351 wrmsr(IA32_THERM_INTERRUPT, msr);
352
353 /* Enable package critical interrupt only */
354 msr.lo = 1 << 4;
355 msr.hi = 0;
356 wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
357}
358
359static void enable_lapic_tpr(void)
360{
361 msr_t msr;
362
363 msr = rdmsr(MSR_PIC_MSG_CONTROL);
364 msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
365 wrmsr(MSR_PIC_MSG_CONTROL, msr);
366}
367
368static void configure_dca_cap(void)
369{
370 struct cpuid_result cpuid_regs;
371 msr_t msr;
372
373 /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
374 cpuid_regs = cpuid(1);
375 if (cpuid_regs.ecx & (1 << 18)) {
376 msr = rdmsr(IA32_PLATFORM_DCA_CAP);
377 msr.lo |= 1;
378 wrmsr(IA32_PLATFORM_DCA_CAP, msr);
379 }
380}
381
382static void set_max_ratio(void)
383{
384 msr_t msr, perf_ctl;
385
386 perf_ctl.hi = 0;
387
388 /* Check for configurable TDP option */
389 if (cpu_config_tdp_levels()) {
390 /* Set to nominal TDP ratio */
391 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
392 perf_ctl.lo = (msr.lo & 0xff) << 8;
393 } else {
394 /* Platform Info bits 15:8 give max ratio */
395 msr = rdmsr(MSR_PLATFORM_INFO);
396 perf_ctl.lo = msr.lo & 0xff00;
397 }
398 wrmsr(IA32_PERF_CTL, perf_ctl);
399
400 printk(BIOS_DEBUG, "haswell: frequency set to %d\n",
401 ((perf_ctl.lo >> 8) & 0xff) * HASWELL_BCLK);
402}
403
404static void set_energy_perf_bias(u8 policy)
405{
406 msr_t msr;
Aaron Durbindc278f82012-12-11 17:15:13 -0600407 int ecx;
408
409 /* Determine if energy efficient policy is supported. */
410 ecx = cpuid_ecx(0x6);
411 if (!(ecx & (1 << 3)))
412 return;
Aaron Durbin76c37002012-10-30 09:03:43 -0500413
414 /* Energy Policy is bits 3:0 */
415 msr = rdmsr(IA32_ENERGY_PERFORMANCE_BIAS);
416 msr.lo &= ~0xf;
417 msr.lo |= policy & 0xf;
418 wrmsr(IA32_ENERGY_PERFORMANCE_BIAS, msr);
419
420 printk(BIOS_DEBUG, "haswell: energy policy set to %u\n",
421 policy);
422}
423
424static void configure_mca(void)
425{
426 msr_t msr;
Aaron Durbin24614af2013-01-12 01:07:28 -0600427 const unsigned int mcg_cap_msr = 0x179;
Aaron Durbin76c37002012-10-30 09:03:43 -0500428 int i;
Aaron Durbin24614af2013-01-12 01:07:28 -0600429 int num_banks;
Aaron Durbin76c37002012-10-30 09:03:43 -0500430
Aaron Durbin24614af2013-01-12 01:07:28 -0600431 msr = rdmsr(mcg_cap_msr);
432 num_banks = msr.lo & 0xff;
Aaron Durbin76c37002012-10-30 09:03:43 -0500433 msr.lo = msr.hi = 0;
Aaron Durbin24614af2013-01-12 01:07:28 -0600434 /* TODO(adurbin): This should only be done on a cold boot. Also, some
435 * of these banks are core vs package scope. For now every CPU clears
436 * every bank. */
437 for (i = 0; i < num_banks; i++)
Aaron Durbin76c37002012-10-30 09:03:43 -0500438 wrmsr(IA32_MC0_STATUS + (i * 4), msr);
439}
440
441#if CONFIG_USBDEBUG
442static unsigned ehci_debug_addr;
443#endif
444
445/*
446 * Initialize any extra cores/threads in this package.
447 */
448static void intel_cores_init(device_t cpu)
449{
450 struct cpuid_result result;
451 unsigned threads_per_package, threads_per_core, i;
452
453 /* Logical processors (threads) per core */
454 result = cpuid_ext(0xb, 0);
455 threads_per_core = result.ebx & 0xffff;
456
457 /* Logical processors (threads) per package */
458 result = cpuid_ext(0xb, 1);
459 threads_per_package = result.ebx & 0xffff;
460
461 /* Only initialize extra cores from BSP */
462 if (cpu->path.apic.apic_id)
463 return;
464
465 printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",
466 cpu->path.apic.apic_id, threads_per_package/threads_per_core,
467 threads_per_core);
468
469 for (i = 1; i < threads_per_package; ++i) {
470 struct device_path cpu_path;
471 device_t new;
472
473 /* Build the cpu device path */
474 cpu_path.type = DEVICE_PATH_APIC;
475 cpu_path.apic.apic_id =
476 cpu->path.apic.apic_id + i;
477
478 /* Update APIC ID if no hyperthreading */
479 if (threads_per_core == 1)
480 cpu_path.apic.apic_id <<= 1;
481
482 /* Allocate the new cpu device structure */
483 new = alloc_dev(cpu->bus, &cpu_path);
484 if (!new)
485 continue;
486
487 printk(BIOS_DEBUG, "CPU: %u has core %u\n",
488 cpu->path.apic.apic_id,
489 new->path.apic.apic_id);
490
491#if CONFIG_SMP && CONFIG_MAX_CPUS > 1
492 /* Start the new cpu */
493 if (!start_cpu(new)) {
494 /* Record the error in cpu? */
495 printk(BIOS_ERR, "CPU %u would not start!\n",
496 new->path.apic.apic_id);
497 }
498#endif
499 }
500}
501
502static void haswell_init(device_t cpu)
503{
504 char processor_name[49];
505 struct cpuid_result cpuid_regs;
506
507 intel_update_microcode_from_cbfs();
508
509 /* Turn on caching if we haven't already */
510 x86_enable_cache();
511
512 /* Clear out pending MCEs */
513 configure_mca();
514
515 /* Print processor name */
516 fill_processor_name(processor_name);
517 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
518
519#if CONFIG_USBDEBUG
520 // Is this caution really needed?
521 if(!ehci_debug_addr)
522 ehci_debug_addr = get_ehci_debug();
523 set_ehci_debug(0);
524#endif
525
526 /* Setup MTRRs based on physical address size */
527 cpuid_regs = cpuid(0x80000008);
528 x86_setup_fixed_mtrrs();
529 x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2);
530 x86_mtrr_check();
531
532 /* Setup Page Attribute Tables (PAT) */
533 // TODO set up PAT
534
535#if CONFIG_USBDEBUG
536 set_ehci_debug(ehci_debug_addr);
537#endif
538
539 /* Enable the local cpu apics */
540 enable_lapic_tpr();
541 setup_lapic();
542
543 /* Configure C States */
544 //configure_c_states();
545
546 /* Configure Enhanced SpeedStep and Thermal Sensors */
547 configure_misc();
548
549 /* Thermal throttle activation offset */
550 configure_thermal_target();
551
552 /* Enable Direct Cache Access */
553 configure_dca_cap();
554
555 /* Set energy policy */
556 set_energy_perf_bias(ENERGY_POLICY_NORMAL);
557
558 /* Set Max Ratio */
559 set_max_ratio();
560
561 /* Enable Turbo */
562 enable_turbo();
563
564 /* Start up extra cores */
565 intel_cores_init(cpu);
566}
567
568static struct device_operations cpu_dev_ops = {
569 .init = haswell_init,
570};
571
572static struct cpu_device_id cpu_table[] = {
573 { X86_VENDOR_INTEL, 0x306c1 }, /* Intel Haswell 4+2 A0 */
574 { X86_VENDOR_INTEL, 0x306c2 }, /* Intel Haswell 4+2 B0 */
Duncan Laurie512540492012-12-17 11:24:45 -0800575 { X86_VENDOR_INTEL, 0x40650 }, /* Intel Haswell ULT B0 */
576 { X86_VENDOR_INTEL, 0x40651 }, /* Intel Haswell ULT B1 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500577 { 0, 0 },
578};
579
580static const struct cpu_driver driver __cpu_driver = {
581 .ops = &cpu_dev_ops,
582 .id_table = cpu_table,
583 /* .cstates = cstate_map, */
584};
585