blob: 6e5b339444c03bb2105807efa44b6b069e16cc23 [file] [log] [blame]
Stefan Reinauerc7757f22009-04-30 10:14:22 +00001/*
2 * This file is part of the coreboot project.
Stefan Reinauer14e22772010-04-27 06:56:47 +00003 *
Stefan Reinauerc7757f22009-04-30 10:14:22 +00004 * Copyright (C) 2007-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauerc7757f22009-04-30 10:14:22 +000015 */
16
Stefan Reinauer00a889c2008-10-29 04:48:44 +000017#include <console/console.h>
18#include <device/device.h>
Stefan Reinauer00a889c2008-10-29 04:48:44 +000019#include <string.h>
20#include <cpu/cpu.h>
21#include <cpu/x86/mtrr.h>
22#include <cpu/x86/msr.h>
23#include <cpu/x86/lapic.h>
Stefan Reinauer00a889c2008-10-29 04:48:44 +000024#include <cpu/intel/hyperthreading.h>
Paul Menzel7129ccb2017-02-27 01:01:55 +010025#include <cpu/intel/microcode.h>
Stefan Reinauer2a27b202010-12-11 22:14:44 +000026#include <cpu/intel/speedstep.h>
Stefan Reinauer00a889c2008-10-29 04:48:44 +000027#include <cpu/x86/cache.h>
Uwe Hermannaac8f662010-09-29 09:54:16 +000028#include <cpu/x86/name.h>
Matt DeVilliered6fe2f2016-12-14 16:12:43 -060029#include <cpu/intel/common/common.h>
Stefan Reinauer45cc5502009-03-06 19:54:15 +000030
Stefan Reinauerc7757f22009-04-30 10:14:22 +000031#define HIGHEST_CLEVEL 3
Stefan Reinauer45cc5502009-03-06 19:54:15 +000032static void configure_c_states(void)
33{
34 msr_t msr;
35
Patrick Georgi644e83b2013-02-09 15:35:30 +010036 msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
Paul Menzel7129ccb2017-02-27 01:01:55 +010037 msr.lo |= (1 << 15); // config lock until next reset
Stefan Reinauer4da810b2009-07-21 21:41:42 +000038 msr.lo |= (1 << 10); // Enable I/O MWAIT redirection for C-States
Stefan Reinauerc7757f22009-04-30 10:14:22 +000039 msr.lo &= ~(1 << 9); // Issue a single stop grant cycle upon stpclk
Paul Menzel7129ccb2017-02-27 01:01:55 +010040 msr.lo |= (1 << 3); // dynamic L2
Stefan Reinauer4da810b2009-07-21 21:41:42 +000041
42 /* Number of supported C-States */
43 msr.lo &= ~7;
44 msr.lo |= HIGHEST_CLEVEL; // support at most C3
45
Patrick Georgi644e83b2013-02-09 15:35:30 +010046 wrmsr(MSR_PMG_CST_CONFIG_CONTROL, msr);
Stefan Reinauerc7757f22009-04-30 10:14:22 +000047
Stefan Reinauer4da810b2009-07-21 21:41:42 +000048 /* Set Processor MWAIT IO BASE (P_BLK) */
49 msr.hi = 0;
Lee Leahycdc50482017-03-15 18:26:18 -070050 msr.lo = ((PMB0_BASE + 4) & 0xffff) | (((PMB1_BASE + 9) & 0xffff)
51 << 16);
Patrick Georgi644e83b2013-02-09 15:35:30 +010052 wrmsr(MSR_PMG_IO_BASE_ADDR, msr);
Stefan Reinauerc7757f22009-04-30 10:14:22 +000053
Paul Menzel7129ccb2017-02-27 01:01:55 +010054 /* Set C_LVL controls and IO Capture Address */
Stefan Reinauer4da810b2009-07-21 21:41:42 +000055 msr.hi = 0;
Lee Leahycdc50482017-03-15 18:26:18 -070056 // -2 because LVL0+1 aren't counted
57 msr.lo = (PMB0_BASE + 4) | ((HIGHEST_CLEVEL - 2) << 16);
Patrick Georgi644e83b2013-02-09 15:35:30 +010058 wrmsr(MSR_PMG_IO_CAPTURE_ADDR, msr);
Stefan Reinauer45cc5502009-03-06 19:54:15 +000059}
60
61#define IA32_MISC_ENABLE 0x1a0
62static void configure_misc(void)
63{
64 msr_t msr;
65
66 msr = rdmsr(IA32_MISC_ENABLE);
Lee Leahy7b5f12b92017-03-15 17:16:59 -070067 msr.lo |= (1 << 3); /* TM1 enable */
Stefan Reinauer45cc5502009-03-06 19:54:15 +000068 msr.lo |= (1 << 13); /* TM2 enable */
69 msr.lo |= (1 << 17); /* Bidirectional PROCHOT# */
70
71 msr.lo |= (1 << 10); /* FERR# multiplexing */
72
73 // TODO: Only if IA32_PLATFORM_ID[17] = 0 and IA32_PLATFORM_ID[50] = 1
74 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
75
Arthur Heymansaacd5482016-10-06 12:14:14 +020076 /* Enable C2E */
77 msr.lo |= (1 << 26);
78
79 /* Enable C4E */
80 msr.hi |= (1 << (32 - 32)); // C4E
81 msr.hi |= (1 << (33 - 32)); // Hard C4E
82
Stefan Reinauer45cc5502009-03-06 19:54:15 +000083 wrmsr(IA32_MISC_ENABLE, msr);
84
85 msr.lo |= (1 << 20); /* Lock Enhanced SpeedStep Enable */
86 wrmsr(IA32_MISC_ENABLE, msr);
Patrick Georgiac624a62011-08-09 08:52:14 +020087
88 // set maximum CPU speed
89 msr = rdmsr(IA32_PERF_STS);
Lee Leahy9d62e7e2017-03-15 17:40:50 -070090 int busratio_max = (msr.hi >> (40-32)) & 0x1f;
Patrick Georgiac624a62011-08-09 08:52:14 +020091
92 msr = rdmsr(IA32_PLATFORM_ID);
Lee Leahy9d62e7e2017-03-15 17:40:50 -070093 int vid_max = msr.lo & 0x3f;
Patrick Georgiac624a62011-08-09 08:52:14 +020094
95 msr.lo &= ~0xffff;
96 msr.lo |= busratio_max << 8;
97 msr.lo |= vid_max;
98
99 wrmsr(IA32_PERF_CTL, msr);
Stefan Reinauer45cc5502009-03-06 19:54:15 +0000100}
101
Stefan Reinauer4da810b2009-07-21 21:41:42 +0000102#define PIC_SENS_CFG 0x1aa
103static void configure_pic_thermal_sensors(void)
104{
105 msr_t msr;
106
107 msr = rdmsr(PIC_SENS_CFG);
108
109 msr.lo |= (1 << 21); // inter-core lock TM1
110 msr.lo |= (1 << 4); // Enable bypass filter
111
112 wrmsr(PIC_SENS_CFG, msr);
113}
114
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +1100115static void model_6ex_init(struct device *cpu)
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000116{
117 char processor_name[49];
118
119 /* Turn on caching if we haven't already */
120 x86_enable_cache();
121
122 /* Update the microcode */
Alexandru Gagniuc2c38f502013-12-06 23:14:54 -0600123 intel_update_microcode_from_cbfs();
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000124
125 /* Print processor name */
126 fill_processor_name(processor_name);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000127 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000128
129 /* Setup MTRRs */
Sven Schnelleadfbcb792012-01-10 12:01:43 +0100130 x86_setup_mtrrs();
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000131 x86_mtrr_check();
Stefan Reinauer45cc5502009-03-06 19:54:15 +0000132
Paul Menzel7129ccb2017-02-27 01:01:55 +0100133 /* Setup Page Attribute Tables (PAT) */
134 // TODO set up PAT
135
Elyes HAOUASd6e96862016-08-21 10:12:15 +0200136 /* Enable the local CPU APICs */
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000137 setup_lapic();
138
Matt DeVilliered6fe2f2016-12-14 16:12:43 -0600139 /* Set virtualization based on Kconfig option */
140 set_vmx();
Stefan Reinauer45cc5502009-03-06 19:54:15 +0000141
142 /* Configure C States */
143 configure_c_states();
144
145 /* Configure Enhanced SpeedStep and Thermal Sensors */
146 configure_misc();
147
Stefan Reinauer4da810b2009-07-21 21:41:42 +0000148 /* PIC thermal sensor control */
149 configure_pic_thermal_sensors();
Sven Schnelle51676b12012-07-29 19:18:03 +0200150
Elyes HAOUASd82be922016-07-28 18:58:27 +0200151 /* Start up my CPU siblings */
Sven Schnelle51676b12012-07-29 19:18:03 +0200152 intel_sibling_init(cpu);
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000153}
154
155static struct device_operations cpu_dev_ops = {
156 .init = model_6ex_init,
157};
158
Jonathan Neuschäfer8f06ce32017-11-20 01:56:44 +0100159static const struct cpu_device_id cpu_table[] = {
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000160 { X86_VENDOR_INTEL, 0x06e0 }, /* Intel Core Solo/Core Duo */
161 { X86_VENDOR_INTEL, 0x06e8 }, /* Intel Core Solo/Core Duo */
Stefan Reinauerc7757f22009-04-30 10:14:22 +0000162 { X86_VENDOR_INTEL, 0x06ec }, /* Intel Core Solo/Core Duo */
Stefan Reinauer00a889c2008-10-29 04:48:44 +0000163 { 0, 0 },
164};
165
166static const struct cpu_driver driver __cpu_driver = {
167 .ops = &cpu_dev_ops,
168 .id_table = cpu_table,
169};