blob: 85f6afd031f17b439bb2e122d9522666c4488193 [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>
Aaron Durbin76c37002012-10-30 09:03:43 -050038#include "haswell.h"
39#include "chip.h"
40
41/*
Martin Roth4c3ab732013-07-08 16:23:54 -060042 * List of supported C-states in this processor
Aaron Durbin76c37002012-10-30 09:03:43 -050043 *
44 * Latencies are typical worst-case package exit time in uS
45 * taken from the SandyBridge BIOS specification.
46 */
47#if 0
48static acpi_cstate_t cstate_map[] = {
49 { /* 0: C0 */
50 },{ /* 1: C1 */
51 .latency = 1,
52 .power = 1000,
53 .resource = {
54 .addrl = 0x00, /* MWAIT State 0 */
55 .space_id = ACPI_ADDRESS_SPACE_FIXED,
56 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
57 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
58 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
59 }
60 },
61 { /* 2: C1E */
62 .latency = 1,
63 .power = 1000,
64 .resource = {
65 .addrl = 0x01, /* MWAIT State 0 Sub-state 1 */
66 .space_id = ACPI_ADDRESS_SPACE_FIXED,
67 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
68 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
69 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
70 }
71 },
72 { /* 3: C3 */
73 .latency = 63,
74 .power = 500,
75 .resource = {
76 .addrl = 0x10, /* MWAIT State 1 */
77 .space_id = ACPI_ADDRESS_SPACE_FIXED,
78 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
79 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
80 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
81 }
82 },
83 { /* 4: C6 */
84 .latency = 87,
85 .power = 350,
86 .resource = {
87 .addrl = 0x20, /* MWAIT State 2 */
88 .space_id = ACPI_ADDRESS_SPACE_FIXED,
89 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
90 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
91 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
92 }
93 },
94 { /* 5: C7 */
95 .latency = 90,
96 .power = 200,
97 .resource = {
98 .addrl = 0x30, /* MWAIT State 3 */
99 .space_id = ACPI_ADDRESS_SPACE_FIXED,
100 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
101 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
102 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
103 }
104 },
105 { /* 6: C7S */
106 .latency = 90,
107 .power = 200,
108 .resource = {
109 .addrl = 0x31, /* MWAIT State 3 Sub-state 1 */
110 .space_id = ACPI_ADDRESS_SPACE_FIXED,
111 .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
112 .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
113 .resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
114 }
115 },
116 { 0 }
117};
118#endif
119
120/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
121static const u8 power_limit_time_sec_to_msr[] = {
122 [0] = 0x00,
123 [1] = 0x0a,
124 [2] = 0x0b,
125 [3] = 0x4b,
126 [4] = 0x0c,
127 [5] = 0x2c,
128 [6] = 0x4c,
129 [7] = 0x6c,
130 [8] = 0x0d,
131 [10] = 0x2d,
132 [12] = 0x4d,
133 [14] = 0x6d,
134 [16] = 0x0e,
135 [20] = 0x2e,
136 [24] = 0x4e,
137 [28] = 0x6e,
138 [32] = 0x0f,
139 [40] = 0x2f,
140 [48] = 0x4f,
141 [56] = 0x6f,
142 [64] = 0x10,
143 [80] = 0x30,
144 [96] = 0x50,
145 [112] = 0x70,
146 [128] = 0x11,
147};
148
149/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
150static const u8 power_limit_time_msr_to_sec[] = {
151 [0x00] = 0,
152 [0x0a] = 1,
153 [0x0b] = 2,
154 [0x4b] = 3,
155 [0x0c] = 4,
156 [0x2c] = 5,
157 [0x4c] = 6,
158 [0x6c] = 7,
159 [0x0d] = 8,
160 [0x2d] = 10,
161 [0x4d] = 12,
162 [0x6d] = 14,
163 [0x0e] = 16,
164 [0x2e] = 20,
165 [0x4e] = 24,
166 [0x6e] = 28,
167 [0x0f] = 32,
168 [0x2f] = 40,
169 [0x4f] = 48,
170 [0x6f] = 56,
171 [0x10] = 64,
172 [0x30] = 80,
173 [0x50] = 96,
174 [0x70] = 112,
175 [0x11] = 128,
176};
177
178int cpu_config_tdp_levels(void)
179{
180 msr_t platform_info;
181
182 /* Bits 34:33 indicate how many levels supported */
183 platform_info = rdmsr(MSR_PLATFORM_INFO);
184 return (platform_info.hi >> 1) & 3;
185}
186
187/*
188 * Configure processor power limits if possible
189 * This must be done AFTER set of BIOS_RESET_CPL
190 */
191void set_power_limits(u8 power_limit_1_time)
192{
193 msr_t msr = rdmsr(MSR_PLATFORM_INFO);
194 msr_t limit;
195 unsigned power_unit;
196 unsigned tdp, min_power, max_power, max_time;
197 u8 power_limit_1_val;
198
199 if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr))
200 return;
201
202 if (!(msr.lo & PLATFORM_INFO_SET_TDP))
203 return;
204
205 /* Get units */
206 msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
207 power_unit = 2 << ((msr.lo & 0xf) - 1);
208
209 /* Get power defaults for this SKU */
210 msr = rdmsr(MSR_PKG_POWER_SKU);
211 tdp = msr.lo & 0x7fff;
212 min_power = (msr.lo >> 16) & 0x7fff;
213 max_power = msr.hi & 0x7fff;
214 max_time = (msr.hi >> 16) & 0x7f;
215
216 printk(BIOS_DEBUG, "CPU TDP: %u Watts\n", tdp / power_unit);
217
218 if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time)
219 power_limit_1_time = power_limit_time_msr_to_sec[max_time];
220
221 if (min_power > 0 && tdp < min_power)
222 tdp = min_power;
223
224 if (max_power > 0 && tdp > max_power)
225 tdp = max_power;
226
227 power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time];
228
229 /* Set long term power limit to TDP */
230 limit.lo = 0;
231 limit.lo |= tdp & PKG_POWER_LIMIT_MASK;
232 limit.lo |= PKG_POWER_LIMIT_EN;
233 limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) <<
234 PKG_POWER_LIMIT_TIME_SHIFT;
235
236 /* Set short term power limit to 1.25 * TDP */
237 limit.hi = 0;
238 limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK;
239 limit.hi |= PKG_POWER_LIMIT_EN;
240 /* Power limit 2 time is only programmable on SNB EP/EX */
241
242 wrmsr(MSR_PKG_POWER_LIMIT, limit);
243
244 /* Use nominal TDP values for CPUs with configurable TDP */
245 if (cpu_config_tdp_levels()) {
246 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
247 limit.hi = 0;
248 limit.lo = msr.lo & 0xff;
249 wrmsr(MSR_TURBO_ACTIVATION_RATIO, limit);
250 }
251}
252
253#if 0
254static void configure_c_states(void)
255{
256 msr_t msr;
257
258 msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
259 msr.lo |= (1 << 28); // C1 Auto Undemotion Enable
260 msr.lo |= (1 << 27); // C3 Auto Undemotion Enable
261 msr.lo |= (1 << 26); // C1 Auto Demotion Enable
262 msr.lo |= (1 << 25); // C3 Auto Demotion Enable
263 msr.lo &= ~(1 << 10); // Disable IO MWAIT redirection
264 msr.lo |= 7; // No package C-state limit
265 wrmsr(MSR_PMG_CST_CONFIG_CONTROL, msr);
266
267 msr = rdmsr(MSR_PMG_IO_CAPTURE_BASE);
268 msr.lo &= ~0x7ffff;
Duncan Laurie1ad55642013-03-07 14:08:04 -0800269 msr.lo |= (get_pmbase() + 4); // LVL_2 base address
Aaron Durbin76c37002012-10-30 09:03:43 -0500270 msr.lo |= (2 << 16); // CST Range: C7 is max C-state
271 wrmsr(MSR_PMG_IO_CAPTURE_BASE, msr);
272
273 msr = rdmsr(MSR_MISC_PWR_MGMT);
274 msr.lo &= ~(1 << 0); // Enable P-state HW_ALL coordination
275 wrmsr(MSR_MISC_PWR_MGMT, msr);
276
277 msr = rdmsr(MSR_POWER_CTL);
278 msr.lo |= (1 << 18); // Enable Energy Perf Bias MSR 0x1b0
279 msr.lo |= (1 << 1); // C1E Enable
280 msr.lo |= (1 << 0); // Bi-directional PROCHOT#
281 wrmsr(MSR_POWER_CTL, msr);
282
283 /* C3 Interrupt Response Time Limit */
284 msr.hi = 0;
285 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x50;
286 wrmsr(MSR_PKGC3_IRTL, msr);
287
288 /* C6 Interrupt Response Time Limit */
289 msr.hi = 0;
290 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x68;
291 wrmsr(MSR_PKGC6_IRTL, msr);
292
293 /* C7 Interrupt Response Time Limit */
294 msr.hi = 0;
295 msr.lo = IRTL_VALID | IRTL_1024_NS | 0x6D;
296 wrmsr(MSR_PKGC7_IRTL, msr);
297
298 /* Primary Plane Current Limit */
299 msr = rdmsr(MSR_PP0_CURRENT_CONFIG);
300 msr.lo &= ~0x1fff;
301 msr.lo |= PP0_CURRENT_LIMIT;
302 wrmsr(MSR_PP0_CURRENT_CONFIG, msr);
303
304 /* Secondary Plane Current Limit */
305 msr = rdmsr(MSR_PP1_CURRENT_CONFIG);
306 msr.lo &= ~0x1fff;
307 if (cpuid_eax(1) >= 0x30600)
308 msr.lo |= PP1_CURRENT_LIMIT_IVB;
309 else
310 msr.lo |= PP1_CURRENT_LIMIT_SNB;
311 wrmsr(MSR_PP1_CURRENT_CONFIG, msr);
312}
313#endif
314
315static void configure_thermal_target(void)
316{
317 struct cpu_intel_haswell_config *conf;
318 device_t lapic;
319 msr_t msr;
320
321 /* Find pointer to CPU configuration */
322 lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
323 if (!lapic || !lapic->chip_info)
324 return;
325 conf = lapic->chip_info;
326
Martin Roth4c3ab732013-07-08 16:23:54 -0600327 /* Set TCC activation offset if supported */
Aaron Durbin76c37002012-10-30 09:03:43 -0500328 msr = rdmsr(MSR_PLATFORM_INFO);
329 if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
330 msr = rdmsr(MSR_TEMPERATURE_TARGET);
331 msr.lo &= ~(0xf << 24); /* Bits 27:24 */
332 msr.lo |= (conf->tcc_offset & 0xf) << 24;
333 wrmsr(MSR_TEMPERATURE_TARGET, msr);
334 }
335}
336
337static void configure_misc(void)
338{
339 msr_t msr;
340
341 msr = rdmsr(IA32_MISC_ENABLE);
342 msr.lo |= (1 << 0); /* Fast String enable */
343 msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
344 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
345 wrmsr(IA32_MISC_ENABLE, msr);
346
347 /* Disable Thermal interrupts */
348 msr.lo = 0;
349 msr.hi = 0;
350 wrmsr(IA32_THERM_INTERRUPT, msr);
351
352 /* Enable package critical interrupt only */
353 msr.lo = 1 << 4;
354 msr.hi = 0;
355 wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
356}
357
358static void enable_lapic_tpr(void)
359{
360 msr_t msr;
361
362 msr = rdmsr(MSR_PIC_MSG_CONTROL);
363 msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
364 wrmsr(MSR_PIC_MSG_CONTROL, msr);
365}
366
367static void configure_dca_cap(void)
368{
369 struct cpuid_result cpuid_regs;
370 msr_t msr;
371
372 /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
373 cpuid_regs = cpuid(1);
374 if (cpuid_regs.ecx & (1 << 18)) {
375 msr = rdmsr(IA32_PLATFORM_DCA_CAP);
376 msr.lo |= 1;
377 wrmsr(IA32_PLATFORM_DCA_CAP, msr);
378 }
379}
380
381static void set_max_ratio(void)
382{
383 msr_t msr, perf_ctl;
384
385 perf_ctl.hi = 0;
386
387 /* Check for configurable TDP option */
388 if (cpu_config_tdp_levels()) {
389 /* Set to nominal TDP ratio */
390 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
391 perf_ctl.lo = (msr.lo & 0xff) << 8;
392 } else {
393 /* Platform Info bits 15:8 give max ratio */
394 msr = rdmsr(MSR_PLATFORM_INFO);
395 perf_ctl.lo = msr.lo & 0xff00;
396 }
397 wrmsr(IA32_PERF_CTL, perf_ctl);
398
399 printk(BIOS_DEBUG, "haswell: frequency set to %d\n",
400 ((perf_ctl.lo >> 8) & 0xff) * HASWELL_BCLK);
401}
402
403static void set_energy_perf_bias(u8 policy)
404{
405 msr_t msr;
Aaron Durbindc278f82012-12-11 17:15:13 -0600406 int ecx;
407
408 /* Determine if energy efficient policy is supported. */
409 ecx = cpuid_ecx(0x6);
410 if (!(ecx & (1 << 3)))
411 return;
Aaron Durbin76c37002012-10-30 09:03:43 -0500412
413 /* Energy Policy is bits 3:0 */
414 msr = rdmsr(IA32_ENERGY_PERFORMANCE_BIAS);
415 msr.lo &= ~0xf;
416 msr.lo |= policy & 0xf;
417 wrmsr(IA32_ENERGY_PERFORMANCE_BIAS, msr);
418
419 printk(BIOS_DEBUG, "haswell: energy policy set to %u\n",
420 policy);
421}
422
423static void configure_mca(void)
424{
425 msr_t msr;
Aaron Durbin24614af2013-01-12 01:07:28 -0600426 const unsigned int mcg_cap_msr = 0x179;
Aaron Durbin76c37002012-10-30 09:03:43 -0500427 int i;
Aaron Durbin24614af2013-01-12 01:07:28 -0600428 int num_banks;
Aaron Durbin76c37002012-10-30 09:03:43 -0500429
Aaron Durbin24614af2013-01-12 01:07:28 -0600430 msr = rdmsr(mcg_cap_msr);
431 num_banks = msr.lo & 0xff;
Aaron Durbin76c37002012-10-30 09:03:43 -0500432 msr.lo = msr.hi = 0;
Aaron Durbin24614af2013-01-12 01:07:28 -0600433 /* TODO(adurbin): This should only be done on a cold boot. Also, some
434 * of these banks are core vs package scope. For now every CPU clears
435 * every bank. */
436 for (i = 0; i < num_banks; i++)
Aaron Durbin76c37002012-10-30 09:03:43 -0500437 wrmsr(IA32_MC0_STATUS + (i * 4), msr);
438}
439
Aaron Durbin305b1f02013-01-15 08:27:05 -0600440static void bsp_init_before_ap_bringup(struct bus *cpu_bus)
Aaron Durbin76c37002012-10-30 09:03:43 -0500441{
Aaron Durbin305b1f02013-01-15 08:27:05 -0600442 struct device_path cpu_path;
443 struct cpu_info *info;
Aaron Durbin76c37002012-10-30 09:03:43 -0500444 char processor_name[49];
Aaron Durbin76c37002012-10-30 09:03:43 -0500445
446 /* Print processor name */
447 fill_processor_name(processor_name);
448 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
449
Aaron Durbin305b1f02013-01-15 08:27:05 -0600450 /* Ensure the local apic is enabled */
451 enable_lapic();
452
453 /* Set the device path of the boot cpu. */
454 cpu_path.type = DEVICE_PATH_APIC;
455 cpu_path.apic.apic_id = lapicid();
456
457 /* Find the device structure for the boot cpu. */
458 info = cpu_info();
459 info->cpu = alloc_find_dev(cpu_bus, &cpu_path);
460
461 if (info->index != 0)
462 printk(BIOS_CRIT, "BSP index(%d) != 0!\n", info->index);
463
Aaron Durbin7af20692013-01-14 14:54:41 -0600464 /* Setup MTRRs based on physical address size. */
Aaron Durbin76c37002012-10-30 09:03:43 -0500465 x86_setup_fixed_mtrrs();
Aaron Durbin7af20692013-01-14 14:54:41 -0600466 x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2);
Aaron Durbin76c37002012-10-30 09:03:43 -0500467 x86_mtrr_check();
468
Aaron Durbin305b1f02013-01-15 08:27:05 -0600469 /* Call through the cpu driver's initialization. */
470 cpu_initialize(0);
Aaron Durbin7af20692013-01-14 14:54:41 -0600471}
472
Aaron Durbin305b1f02013-01-15 08:27:05 -0600473/* All CPUs including BSP will run the following function. */
474static void haswell_init(device_t cpu)
Aaron Durbin7af20692013-01-14 14:54:41 -0600475{
476 /* Clear out pending MCEs */
477 configure_mca();
478
Aaron Durbin76c37002012-10-30 09:03:43 -0500479 /* Enable the local cpu apics */
480 enable_lapic_tpr();
481 setup_lapic();
482
483 /* Configure C States */
484 //configure_c_states();
485
486 /* Configure Enhanced SpeedStep and Thermal Sensors */
487 configure_misc();
488
489 /* Thermal throttle activation offset */
490 configure_thermal_target();
491
492 /* Enable Direct Cache Access */
493 configure_dca_cap();
494
495 /* Set energy policy */
496 set_energy_perf_bias(ENERGY_POLICY_NORMAL);
497
498 /* Set Max Ratio */
499 set_max_ratio();
500
501 /* Enable Turbo */
502 enable_turbo();
Aaron Durbin7af20692013-01-14 14:54:41 -0600503}
Aaron Durbin76c37002012-10-30 09:03:43 -0500504
Aaron Durbin7af20692013-01-14 14:54:41 -0600505void bsp_init_and_start_aps(struct bus *cpu_bus)
506{
Aaron Durbin305b1f02013-01-15 08:27:05 -0600507 int max_cpus;
508 int num_aps;
509 const void *microcode_patch;
510
Martin Roth4c3ab732013-07-08 16:23:54 -0600511 /* Perform any necessary BSP initialization before APs are brought up.
512 * This call also allows the BSP to prepare for any secondary effects
Aaron Durbin7af20692013-01-14 14:54:41 -0600513 * from calling cpu_initialize() such as smm_init(). */
Aaron Durbin305b1f02013-01-15 08:27:05 -0600514 bsp_init_before_ap_bringup(cpu_bus);
Aaron Durbin7af20692013-01-14 14:54:41 -0600515
Aaron Durbin305b1f02013-01-15 08:27:05 -0600516 microcode_patch = intel_microcode_find();
Aaron Durbin7af20692013-01-14 14:54:41 -0600517
Aaron Durbin305b1f02013-01-15 08:27:05 -0600518 /* This needs to be called after the mtrr setup so the BSP mtrrs
519 * can be mirrored by the APs. */
520 if (setup_ap_init(cpu_bus, &max_cpus, microcode_patch)) {
521 printk(BIOS_CRIT, "AP setup initialization failed. "
522 "No APs will be brought up.\n");
523 return;
Aaron Durbin7af20692013-01-14 14:54:41 -0600524 }
Aaron Durbin305b1f02013-01-15 08:27:05 -0600525
526 num_aps = max_cpus - 1;
527 if (start_aps(cpu_bus, num_aps)) {
528 printk(BIOS_CRIT, "AP startup failed. Trying to continue.\n");
529 }
530
531 if (smm_initialize()) {
Martin Roth4c3ab732013-07-08 16:23:54 -0600532 printk(BIOS_CRIT, "SMM Initialization failed...\n");
Aaron Durbin305b1f02013-01-15 08:27:05 -0600533 return;
534 }
535
Aaron Durbin305b1f02013-01-15 08:27:05 -0600536 /* After SMM relocation a 2nd microcode load is required. */
537 intel_microcode_load_unlocked(microcode_patch);
Aaron Durbin23f50162013-04-03 09:55:22 -0500538
539 /* Enable ROM caching if option was selected. */
540 x86_mtrr_enable_rom_caching();
Aaron Durbin76c37002012-10-30 09:03:43 -0500541}
542
543static struct device_operations cpu_dev_ops = {
544 .init = haswell_init,
545};
546
547static struct cpu_device_id cpu_table[] = {
548 { X86_VENDOR_INTEL, 0x306c1 }, /* Intel Haswell 4+2 A0 */
549 { X86_VENDOR_INTEL, 0x306c2 }, /* Intel Haswell 4+2 B0 */
Duncan Laurie512540492012-12-17 11:24:45 -0800550 { X86_VENDOR_INTEL, 0x40650 }, /* Intel Haswell ULT B0 */
551 { X86_VENDOR_INTEL, 0x40651 }, /* Intel Haswell ULT B1 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500552 { 0, 0 },
553};
554
555static const struct cpu_driver driver __cpu_driver = {
556 .ops = &cpu_dev_ops,
557 .id_table = cpu_table,
558 /* .cstates = cstate_map, */
559};
560