diff options
Diffstat (limited to 'arch/i386/kernel/cpu/intel.c')
-rw-r--r-- | arch/i386/kernel/cpu/intel.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c new file mode 100644 index 00000000000..b8d847b850d --- /dev/null +++ b/arch/i386/kernel/cpu/intel.c | |||
@@ -0,0 +1,248 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/kernel.h> | ||
4 | |||
5 | #include <linux/string.h> | ||
6 | #include <linux/bitops.h> | ||
7 | #include <linux/smp.h> | ||
8 | #include <linux/thread_info.h> | ||
9 | |||
10 | #include <asm/processor.h> | ||
11 | #include <asm/msr.h> | ||
12 | #include <asm/uaccess.h> | ||
13 | |||
14 | #include "cpu.h" | ||
15 | |||
16 | #ifdef CONFIG_X86_LOCAL_APIC | ||
17 | #include <asm/mpspec.h> | ||
18 | #include <asm/apic.h> | ||
19 | #include <mach_apic.h> | ||
20 | #endif | ||
21 | |||
22 | extern int trap_init_f00f_bug(void); | ||
23 | |||
24 | #ifdef CONFIG_X86_INTEL_USERCOPY | ||
25 | /* | ||
26 | * Alignment at which movsl is preferred for bulk memory copies. | ||
27 | */ | ||
28 | struct movsl_mask movsl_mask; | ||
29 | #endif | ||
30 | |||
31 | void __init early_intel_workaround(struct cpuinfo_x86 *c) | ||
32 | { | ||
33 | if (c->x86_vendor != X86_VENDOR_INTEL) | ||
34 | return; | ||
35 | /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */ | ||
36 | if (c->x86 == 15 && c->x86_cache_alignment == 64) | ||
37 | c->x86_cache_alignment = 128; | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | * Early probe support logic for ppro memory erratum #50 | ||
42 | * | ||
43 | * This is called before we do cpu ident work | ||
44 | */ | ||
45 | |||
46 | int __init ppro_with_ram_bug(void) | ||
47 | { | ||
48 | /* Uses data from early_cpu_detect now */ | ||
49 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
50 | boot_cpu_data.x86 == 6 && | ||
51 | boot_cpu_data.x86_model == 1 && | ||
52 | boot_cpu_data.x86_mask < 8) { | ||
53 | printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n"); | ||
54 | return 1; | ||
55 | } | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | |||
60 | /* | ||
61 | * P4 Xeon errata 037 workaround. | ||
62 | * Hardware prefetcher may cause stale data to be loaded into the cache. | ||
63 | */ | ||
64 | static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) | ||
65 | { | ||
66 | unsigned long lo, hi; | ||
67 | |||
68 | if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { | ||
69 | rdmsr (MSR_IA32_MISC_ENABLE, lo, hi); | ||
70 | if ((lo & (1<<9)) == 0) { | ||
71 | printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); | ||
72 | printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); | ||
73 | lo |= (1<<9); /* Disable hw prefetching */ | ||
74 | wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | |||
80 | static void __init init_intel(struct cpuinfo_x86 *c) | ||
81 | { | ||
82 | unsigned int l2 = 0; | ||
83 | char *p = NULL; | ||
84 | |||
85 | #ifdef CONFIG_X86_F00F_BUG | ||
86 | /* | ||
87 | * All current models of Pentium and Pentium with MMX technology CPUs | ||
88 | * have the F0 0F bug, which lets nonprivileged users lock up the system. | ||
89 | * Note that the workaround only should be initialized once... | ||
90 | */ | ||
91 | c->f00f_bug = 0; | ||
92 | if ( c->x86 == 5 ) { | ||
93 | static int f00f_workaround_enabled = 0; | ||
94 | |||
95 | c->f00f_bug = 1; | ||
96 | if ( !f00f_workaround_enabled ) { | ||
97 | trap_init_f00f_bug(); | ||
98 | printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); | ||
99 | f00f_workaround_enabled = 1; | ||
100 | } | ||
101 | } | ||
102 | #endif | ||
103 | |||
104 | select_idle_routine(c); | ||
105 | l2 = init_intel_cacheinfo(c); | ||
106 | |||
107 | /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ | ||
108 | if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) | ||
109 | clear_bit(X86_FEATURE_SEP, c->x86_capability); | ||
110 | |||
111 | /* Names for the Pentium II/Celeron processors | ||
112 | detectable only by also checking the cache size. | ||
113 | Dixon is NOT a Celeron. */ | ||
114 | if (c->x86 == 6) { | ||
115 | switch (c->x86_model) { | ||
116 | case 5: | ||
117 | if (c->x86_mask == 0) { | ||
118 | if (l2 == 0) | ||
119 | p = "Celeron (Covington)"; | ||
120 | else if (l2 == 256) | ||
121 | p = "Mobile Pentium II (Dixon)"; | ||
122 | } | ||
123 | break; | ||
124 | |||
125 | case 6: | ||
126 | if (l2 == 128) | ||
127 | p = "Celeron (Mendocino)"; | ||
128 | else if (c->x86_mask == 0 || c->x86_mask == 5) | ||
129 | p = "Celeron-A"; | ||
130 | break; | ||
131 | |||
132 | case 8: | ||
133 | if (l2 == 128) | ||
134 | p = "Celeron (Coppermine)"; | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | if ( p ) | ||
140 | strcpy(c->x86_model_id, p); | ||
141 | |||
142 | detect_ht(c); | ||
143 | |||
144 | /* Work around errata */ | ||
145 | Intel_errata_workarounds(c); | ||
146 | |||
147 | #ifdef CONFIG_X86_INTEL_USERCOPY | ||
148 | /* | ||
149 | * Set up the preferred alignment for movsl bulk memory moves | ||
150 | */ | ||
151 | switch (c->x86) { | ||
152 | case 4: /* 486: untested */ | ||
153 | break; | ||
154 | case 5: /* Old Pentia: untested */ | ||
155 | break; | ||
156 | case 6: /* PII/PIII only like movsl with 8-byte alignment */ | ||
157 | movsl_mask.mask = 7; | ||
158 | break; | ||
159 | case 15: /* P4 is OK down to 8-byte alignment */ | ||
160 | movsl_mask.mask = 7; | ||
161 | break; | ||
162 | } | ||
163 | #endif | ||
164 | |||
165 | if (c->x86 == 15) | ||
166 | set_bit(X86_FEATURE_P4, c->x86_capability); | ||
167 | if (c->x86 == 6) | ||
168 | set_bit(X86_FEATURE_P3, c->x86_capability); | ||
169 | } | ||
170 | |||
171 | |||
172 | static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) | ||
173 | { | ||
174 | /* Intel PIII Tualatin. This comes in two flavours. | ||
175 | * One has 256kb of cache, the other 512. We have no way | ||
176 | * to determine which, so we use a boottime override | ||
177 | * for the 512kb model, and assume 256 otherwise. | ||
178 | */ | ||
179 | if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0)) | ||
180 | size = 256; | ||
181 | return size; | ||
182 | } | ||
183 | |||
184 | static struct cpu_dev intel_cpu_dev __initdata = { | ||
185 | .c_vendor = "Intel", | ||
186 | .c_ident = { "GenuineIntel" }, | ||
187 | .c_models = { | ||
188 | { .vendor = X86_VENDOR_INTEL, .family = 4, .model_names = | ||
189 | { | ||
190 | [0] = "486 DX-25/33", | ||
191 | [1] = "486 DX-50", | ||
192 | [2] = "486 SX", | ||
193 | [3] = "486 DX/2", | ||
194 | [4] = "486 SL", | ||
195 | [5] = "486 SX/2", | ||
196 | [7] = "486 DX/2-WB", | ||
197 | [8] = "486 DX/4", | ||
198 | [9] = "486 DX/4-WB" | ||
199 | } | ||
200 | }, | ||
201 | { .vendor = X86_VENDOR_INTEL, .family = 5, .model_names = | ||
202 | { | ||
203 | [0] = "Pentium 60/66 A-step", | ||
204 | [1] = "Pentium 60/66", | ||
205 | [2] = "Pentium 75 - 200", | ||
206 | [3] = "OverDrive PODP5V83", | ||
207 | [4] = "Pentium MMX", | ||
208 | [7] = "Mobile Pentium 75 - 200", | ||
209 | [8] = "Mobile Pentium MMX" | ||
210 | } | ||
211 | }, | ||
212 | { .vendor = X86_VENDOR_INTEL, .family = 6, .model_names = | ||
213 | { | ||
214 | [0] = "Pentium Pro A-step", | ||
215 | [1] = "Pentium Pro", | ||
216 | [3] = "Pentium II (Klamath)", | ||
217 | [4] = "Pentium II (Deschutes)", | ||
218 | [5] = "Pentium II (Deschutes)", | ||
219 | [6] = "Mobile Pentium II", | ||
220 | [7] = "Pentium III (Katmai)", | ||
221 | [8] = "Pentium III (Coppermine)", | ||
222 | [10] = "Pentium III (Cascades)", | ||
223 | [11] = "Pentium III (Tualatin)", | ||
224 | } | ||
225 | }, | ||
226 | { .vendor = X86_VENDOR_INTEL, .family = 15, .model_names = | ||
227 | { | ||
228 | [0] = "Pentium 4 (Unknown)", | ||
229 | [1] = "Pentium 4 (Willamette)", | ||
230 | [2] = "Pentium 4 (Northwood)", | ||
231 | [4] = "Pentium 4 (Foster)", | ||
232 | [5] = "Pentium 4 (Foster)", | ||
233 | } | ||
234 | }, | ||
235 | }, | ||
236 | .c_init = init_intel, | ||
237 | .c_identify = generic_identify, | ||
238 | .c_size_cache = intel_size_cache, | ||
239 | }; | ||
240 | |||
241 | __init int intel_cpu_init(void) | ||
242 | { | ||
243 | cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev; | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | // arch_initcall(intel_cpu_init); | ||
248 | |||