aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/centaur.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-02-17 21:30:47 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:40:47 -0400
commitedc05e6de3e2fd203da21ba984b19d92e5398b62 (patch)
tree87678402401a57acd7419a7a9931bf3d14dd0e6f /arch/x86/kernel/cpu/centaur.c
parent29a9994bd8dbafc17f43d31651d31ea7b0add6a4 (diff)
x86: more coding style fixes in centaur.c
no code changed: arch/x86/kernel/cpu/centaur.o: text data bss dec hex filename 1031 324 0 1355 54b centaur.o.before 1031 324 0 1355 54b centaur.o.after md5: 4f306a7f980b58eb69c4bdcfcde565f1 centaur.o.before.asm 4f306a7f980b58eb69c4bdcfcde565f1 centaur.o.after.asm Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu/centaur.c')
-rw-r--r--arch/x86/kernel/cpu/centaur.c394
1 files changed, 199 insertions, 195 deletions
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index 710fe1ed0731..efe8da88da53 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -1,10 +1,12 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/init.h> 2#include <linux/init.h>
3#include <linux/bitops.h> 3#include <linux/bitops.h>
4
4#include <asm/processor.h> 5#include <asm/processor.h>
5#include <asm/msr.h> 6#include <asm/msr.h>
6#include <asm/e820.h> 7#include <asm/e820.h>
7#include <asm/mtrr.h> 8#include <asm/mtrr.h>
9
8#include "cpu.h" 10#include "cpu.h"
9 11
10#ifdef CONFIG_X86_OOSTORE 12#ifdef CONFIG_X86_OOSTORE
@@ -12,16 +14,17 @@
12static u32 __cpuinit power2(u32 x) 14static u32 __cpuinit power2(u32 x)
13{ 15{
14 u32 s = 1; 16 u32 s = 1;
15 while(s <= x) 17
18 while (s <= x)
16 s <<= 1; 19 s <<= 1;
20
17 return s >>= 1; 21 return s >>= 1;
18} 22}
19 23
20 24
21/* 25/*
22 * Set up an actual MCR 26 * Set up an actual MCR
23 */ 27 */
24
25static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key) 28static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
26{ 29{
27 u32 lo, hi; 30 u32 lo, hi;
@@ -35,16 +38,15 @@ static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
35} 38}
36 39
37/* 40/*
38 * Figure what we can cover with MCR's 41 * Figure what we can cover with MCR's
39 * 42 *
40 * Shortcut: We know you can't put 4Gig of RAM on a winchip 43 * Shortcut: We know you can't put 4Gig of RAM on a winchip
41 */ 44 */
42 45static u32 __cpuinit ramtop(void)
43static u32 __cpuinit ramtop(void) /* 16388 */
44{ 46{
45 int i;
46 u32 top = 0;
47 u32 clip = 0xFFFFFFFFUL; 47 u32 clip = 0xFFFFFFFFUL;
48 u32 top = 0;
49 int i;
48 50
49 for (i = 0; i < e820.nr_map; i++) { 51 for (i = 0; i < e820.nr_map; i++) {
50 unsigned long start, end; 52 unsigned long start, end;
@@ -52,13 +54,12 @@ static u32 __cpuinit ramtop(void) /* 16388 */
52 if (e820.map[i].addr > 0xFFFFFFFFUL) 54 if (e820.map[i].addr > 0xFFFFFFFFUL)
53 continue; 55 continue;
54 /* 56 /*
55 * Don't MCR over reserved space. Ignore the ISA hole 57 * Don't MCR over reserved space. Ignore the ISA hole
56 * we frob around that catastrophe already 58 * we frob around that catastrophe already
57 */ 59 */
58 60 if (e820.map[i].type == E820_RESERVED) {
59 if (e820.map[i].type == E820_RESERVED) 61 if (e820.map[i].addr >= 0x100000UL &&
60 { 62 e820.map[i].addr < clip)
61 if (e820.map[i].addr >= 0x100000UL && e820.map[i].addr < clip)
62 clip = e820.map[i].addr; 63 clip = e820.map[i].addr;
63 continue; 64 continue;
64 } 65 }
@@ -69,28 +70,27 @@ static u32 __cpuinit ramtop(void) /* 16388 */
69 if (end > top) 70 if (end > top)
70 top = end; 71 top = end;
71 } 72 }
72 /* Everything below 'top' should be RAM except for the ISA hole. 73 /*
73 Because of the limited MCR's we want to map NV/ACPI into our 74 * Everything below 'top' should be RAM except for the ISA hole.
74 MCR range for gunk in RAM 75 * Because of the limited MCR's we want to map NV/ACPI into our
75 76 * MCR range for gunk in RAM
76 Clip might cause us to MCR insufficient RAM but that is an 77 *
77 acceptable failure mode and should only bite obscure boxes with 78 * Clip might cause us to MCR insufficient RAM but that is an
78 a VESA hole at 15Mb 79 * acceptable failure mode and should only bite obscure boxes with
79 80 * a VESA hole at 15Mb
80 The second case Clip sometimes kicks in is when the EBDA is marked 81 *
81 as reserved. Again we fail safe with reasonable results 82 * The second case Clip sometimes kicks in is when the EBDA is marked
82 */ 83 * as reserved. Again we fail safe with reasonable results
83 84 */
84 if(top > clip) 85 if (top > clip)
85 top = clip; 86 top = clip;
86 87
87 return top; 88 return top;
88} 89}
89 90
90/* 91/*
91 * Compute a set of MCR's to give maximum coverage 92 * Compute a set of MCR's to give maximum coverage
92 */ 93 */
93
94static int __cpuinit centaur_mcr_compute(int nr, int key) 94static int __cpuinit centaur_mcr_compute(int nr, int key)
95{ 95{
96 u32 mem = ramtop(); 96 u32 mem = ramtop();
@@ -100,33 +100,31 @@ static int __cpuinit centaur_mcr_compute(int nr, int key)
100 u32 floor = 0; 100 u32 floor = 0;
101 int ct = 0; 101 int ct = 0;
102 102
103 while (ct < nr) 103 while (ct < nr) {
104 {
105 u32 fspace = 0; 104 u32 fspace = 0;
105 u32 high;
106 u32 low;
106 107
107 /* 108 /*
108 * Find the largest block we will fill going upwards 109 * Find the largest block we will fill going upwards
109 */ 110 */
110 111 high = power2(mem-top);
111 u32 high = power2(mem-top);
112 112
113 /* 113 /*
114 * Find the largest block we will fill going downwards 114 * Find the largest block we will fill going downwards
115 */ 115 */
116 116 low = base/2;
117 u32 low = base/2;
118 117
119 /* 118 /*
120 * Don't fill below 1Mb going downwards as there 119 * Don't fill below 1Mb going downwards as there
121 * is an ISA hole in the way. 120 * is an ISA hole in the way.
122 */ 121 */
123
124 if (base <= 1024*1024) 122 if (base <= 1024*1024)
125 low = 0; 123 low = 0;
126 124
127 /* 125 /*
128 * See how much space we could cover by filling below 126 * See how much space we could cover by filling below
129 * the ISA hole 127 * the ISA hole
130 */ 128 */
131 129
132 if (floor == 0) 130 if (floor == 0)
@@ -137,52 +135,48 @@ static int __cpuinit centaur_mcr_compute(int nr, int key)
137 /* And forget ROM space */ 135 /* And forget ROM space */
138 136
139 /* 137 /*
140 * Now install the largest coverage we get 138 * Now install the largest coverage we get
141 */ 139 */
142 140 if (fspace > high && fspace > low) {
143 if (fspace > high && fspace > low)
144 {
145 centaur_mcr_insert(ct, floor, fspace, key); 141 centaur_mcr_insert(ct, floor, fspace, key);
146 floor += fspace; 142 floor += fspace;
147 } 143 } else if (high > low) {
148 else if (high > low) {
149 centaur_mcr_insert(ct, top, high, key); 144 centaur_mcr_insert(ct, top, high, key);
150 top += high; 145 top += high;
151 } 146 } else if (low > 0) {
152 else if (low > 0) {
153 base -= low; 147 base -= low;
154 centaur_mcr_insert(ct, base, low, key); 148 centaur_mcr_insert(ct, base, low, key);
155 } 149 } else
156 else break; 150 break;
157 ct++; 151 ct++;
158 } 152 }
159 /* 153 /*
160 * We loaded ct values. We now need to set the mask. The caller 154 * We loaded ct values. We now need to set the mask. The caller
161 * must do this bit. 155 * must do this bit.
162 */ 156 */
163
164 return ct; 157 return ct;
165} 158}
166 159
167static void __cpuinit centaur_create_optimal_mcr(void) 160static void __cpuinit centaur_create_optimal_mcr(void)
168{ 161{
162 int used;
169 int i; 163 int i;
164
170 /* 165 /*
171 * Allocate up to 6 mcrs to mark as much of ram as possible 166 * Allocate up to 6 mcrs to mark as much of ram as possible
172 * as write combining and weak write ordered. 167 * as write combining and weak write ordered.
173 * 168 *
174 * To experiment with: Linux never uses stack operations for 169 * To experiment with: Linux never uses stack operations for
175 * mmio spaces so we could globally enable stack operation wc 170 * mmio spaces so we could globally enable stack operation wc
176 * 171 *
177 * Load the registers with type 31 - full write combining, all 172 * Load the registers with type 31 - full write combining, all
178 * writes weakly ordered. 173 * writes weakly ordered.
179 */ 174 */
180 int used = centaur_mcr_compute(6, 31); 175 used = centaur_mcr_compute(6, 31);
181 176
182 /* 177 /*
183 * Wipe unused MCRs 178 * Wipe unused MCRs
184 */ 179 */
185
186 for (i = used; i < 8; i++) 180 for (i = used; i < 8; i++)
187 wrmsr(MSR_IDT_MCR0+i, 0, 0); 181 wrmsr(MSR_IDT_MCR0+i, 0, 0);
188} 182}
@@ -190,31 +184,30 @@ static void __cpuinit centaur_create_optimal_mcr(void)
190static void __cpuinit winchip2_create_optimal_mcr(void) 184static void __cpuinit winchip2_create_optimal_mcr(void)
191{ 185{
192 u32 lo, hi; 186 u32 lo, hi;
187 int used;
193 int i; 188 int i;
194 189
195 /* 190 /*
196 * Allocate up to 6 mcrs to mark as much of ram as possible 191 * Allocate up to 6 mcrs to mark as much of ram as possible
197 * as write combining, weak store ordered. 192 * as write combining, weak store ordered.
198 * 193 *
199 * Load the registers with type 25 194 * Load the registers with type 25
200 * 8 - weak write ordering 195 * 8 - weak write ordering
201 * 16 - weak read ordering 196 * 16 - weak read ordering
202 * 1 - write combining 197 * 1 - write combining
203 */ 198 */
204 199 used = centaur_mcr_compute(6, 25);
205 int used = centaur_mcr_compute(6, 25);
206 200
207 /* 201 /*
208 * Mark the registers we are using. 202 * Mark the registers we are using.
209 */ 203 */
210
211 rdmsr(MSR_IDT_MCR_CTRL, lo, hi); 204 rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
212 for (i = 0; i < used; i++) 205 for (i = 0; i < used; i++)
213 lo |= 1<<(9+i); 206 lo |= 1<<(9+i);
214 wrmsr(MSR_IDT_MCR_CTRL, lo, hi); 207 wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
215 208
216 /* 209 /*
217 * Wipe unused MCRs 210 * Wipe unused MCRs
218 */ 211 */
219 212
220 for (i = used; i < 8; i++) 213 for (i = used; i < 8; i++)
@@ -222,9 +215,8 @@ static void __cpuinit winchip2_create_optimal_mcr(void)
222} 215}
223 216
224/* 217/*
225 * Handle the MCR key on the Winchip 2. 218 * Handle the MCR key on the Winchip 2.
226 */ 219 */
227
228static void __cpuinit winchip2_unprotect_mcr(void) 220static void __cpuinit winchip2_unprotect_mcr(void)
229{ 221{
230 u32 lo, hi; 222 u32 lo, hi;
@@ -301,28 +293,29 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
301 display_cacheinfo(c); 293 display_cacheinfo(c);
302} 294}
303 295
296enum {
297 ECX8 = 1<<1,
298 EIERRINT = 1<<2,
299 DPM = 1<<3,
300 DMCE = 1<<4,
301 DSTPCLK = 1<<5,
302 ELINEAR = 1<<6,
303 DSMC = 1<<7,
304 DTLOCK = 1<<8,
305 EDCTLB = 1<<8,
306 EMMX = 1<<9,
307 DPDC = 1<<11,
308 EBRPRED = 1<<12,
309 DIC = 1<<13,
310 DDC = 1<<14,
311 DNA = 1<<15,
312 ERETSTK = 1<<16,
313 E2MMX = 1<<19,
314 EAMD3D = 1<<20,
315};
316
304static void __cpuinit init_centaur(struct cpuinfo_x86 *c) 317static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
305{ 318{
306 enum {
307 ECX8 = 1<<1,
308 EIERRINT = 1<<2,
309 DPM = 1<<3,
310 DMCE = 1<<4,
311 DSTPCLK = 1<<5,
312 ELINEAR = 1<<6,
313 DSMC = 1<<7,
314 DTLOCK = 1<<8,
315 EDCTLB = 1<<8,
316 EMMX = 1<<9,
317 DPDC = 1<<11,
318 EBRPRED = 1<<12,
319 DIC = 1<<13,
320 DDC = 1<<14,
321 DNA = 1<<15,
322 ERETSTK = 1<<16,
323 E2MMX = 1<<19,
324 EAMD3D = 1<<20,
325 };
326 319
327 char *name; 320 char *name;
328 u32 fcr_set = 0; 321 u32 fcr_set = 0;
@@ -330,126 +323,137 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
330 u32 lo, hi, newlo; 323 u32 lo, hi, newlo;
331 u32 aa, bb, cc, dd; 324 u32 aa, bb, cc, dd;
332 325
333 /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; 326 /*
334 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ 327 * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
328 * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
329 */
335 clear_bit(0*32+31, c->x86_capability); 330 clear_bit(0*32+31, c->x86_capability);
336 331
337 switch (c->x86) { 332 switch (c->x86) {
338
339 case 5: 333 case 5:
340 switch (c->x86_model) { 334 switch (c->x86_model) {
341 case 4: 335 case 4:
342 name = "C6"; 336 name = "C6";
343 fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK; 337 fcr_set = ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
344 fcr_clr = DPDC; 338 fcr_clr = DPDC;
345 printk(KERN_NOTICE "Disabling bugged TSC.\n"); 339 printk(KERN_NOTICE "Disabling bugged TSC.\n");
346 clear_bit(X86_FEATURE_TSC, c->x86_capability); 340 clear_bit(X86_FEATURE_TSC, c->x86_capability);
347#ifdef CONFIG_X86_OOSTORE 341#ifdef CONFIG_X86_OOSTORE
348 centaur_create_optimal_mcr(); 342 centaur_create_optimal_mcr();
349 /* Enable 343 /*
350 write combining on non-stack, non-string 344 * Enable:
351 write combining on string, all types 345 * write combining on non-stack, non-string
352 weak write ordering 346 * write combining on string, all types
353 347 * weak write ordering
354 The C6 original lacks weak read order 348 *
355 349 * The C6 original lacks weak read order
356 Note 0x120 is write only on Winchip 1 */ 350 *
357 351 * Note 0x120 is write only on Winchip 1
358 wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); 352 */
353 wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);
359#endif 354#endif
355 break;
356 case 8:
357 switch (c->x86_mask) {
358 default:
359 name = "2";
360 break; 360 break;
361 case 8: 361 case 7 ... 9:
362 switch (c->x86_mask) { 362 name = "2A";
363 default: 363 break;
364 name = "2"; 364 case 10 ... 15:
365 break; 365 name = "2B";
366 case 7 ... 9: 366 break;
367 name = "2A"; 367 }
368 break; 368 fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
369 case 10 ... 15: 369 E2MMX|EAMD3D;
370 name = "2B"; 370 fcr_clr = DPDC;
371 break;
372 }
373 fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D;
374 fcr_clr = DPDC;
375#ifdef CONFIG_X86_OOSTORE 371#ifdef CONFIG_X86_OOSTORE
376 winchip2_unprotect_mcr(); 372 winchip2_unprotect_mcr();
377 winchip2_create_optimal_mcr(); 373 winchip2_create_optimal_mcr();
378 rdmsr(MSR_IDT_MCR_CTRL, lo, hi); 374 rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
379 /* Enable 375 /*
380 write combining on non-stack, non-string 376 * Enable:
381 write combining on string, all types 377 * write combining on non-stack, non-string
382 weak write ordering 378 * write combining on string, all types
383 */ 379 * weak write ordering
384 lo |= 31; 380 */
385 wrmsr(MSR_IDT_MCR_CTRL, lo, hi); 381 lo |= 31;
386 winchip2_protect_mcr(); 382 wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
383 winchip2_protect_mcr();
387#endif 384#endif
388 break; 385 break;
389 case 9: 386 case 9:
390 name = "3"; 387 name = "3";
391 fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; 388 fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
392 fcr_clr = DPDC; 389 E2MMX|EAMD3D;
390 fcr_clr = DPDC;
393#ifdef CONFIG_X86_OOSTORE 391#ifdef CONFIG_X86_OOSTORE
394 winchip2_unprotect_mcr(); 392 winchip2_unprotect_mcr();
395 winchip2_create_optimal_mcr(); 393 winchip2_create_optimal_mcr();
396 rdmsr(MSR_IDT_MCR_CTRL, lo, hi); 394 rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
397 /* Enable 395 /*
398 write combining on non-stack, non-string 396 * Enable:
399 write combining on string, all types 397 * write combining on non-stack, non-string
400 weak write ordering 398 * write combining on string, all types
401 */ 399 * weak write ordering
402 lo |= 31; 400 */
403 wrmsr(MSR_IDT_MCR_CTRL, lo, hi); 401 lo |= 31;
404 winchip2_protect_mcr(); 402 wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
403 winchip2_protect_mcr();
405#endif 404#endif
406 break; 405 break;
407 default: 406 default:
408 name = "??"; 407 name = "??";
409 } 408 }
410 409
411 rdmsr(MSR_IDT_FCR1, lo, hi); 410 rdmsr(MSR_IDT_FCR1, lo, hi);
412 newlo = (lo|fcr_set) & (~fcr_clr); 411 newlo = (lo|fcr_set) & (~fcr_clr);
413 412
414 if (newlo != lo) { 413 if (newlo != lo) {
415 printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo); 414 printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n",
416 wrmsr(MSR_IDT_FCR1, newlo, hi); 415 lo, newlo);
417 } else { 416 wrmsr(MSR_IDT_FCR1, newlo, hi);
418 printk(KERN_INFO "Centaur FCR is 0x%X\n", lo); 417 } else {
419 } 418 printk(KERN_INFO "Centaur FCR is 0x%X\n", lo);
420 /* Emulate MTRRs using Centaur's MCR. */ 419 }
421 set_bit(X86_FEATURE_CENTAUR_MCR, c->x86_capability); 420 /* Emulate MTRRs using Centaur's MCR. */
422 /* Report CX8 */ 421 set_bit(X86_FEATURE_CENTAUR_MCR, c->x86_capability);
423 set_bit(X86_FEATURE_CX8, c->x86_capability); 422 /* Report CX8 */
424 /* Set 3DNow! on Winchip 2 and above. */ 423 set_bit(X86_FEATURE_CX8, c->x86_capability);
425 if (c->x86_model >= 8) 424 /* Set 3DNow! on Winchip 2 and above. */
426 set_bit(X86_FEATURE_3DNOW, c->x86_capability); 425 if (c->x86_model >= 8)
427 /* See if we can find out some more. */ 426 set_bit(X86_FEATURE_3DNOW, c->x86_capability);
428 if (cpuid_eax(0x80000000) >= 0x80000005) { 427 /* See if we can find out some more. */
429 /* Yes, we can. */ 428 if (cpuid_eax(0x80000000) >= 0x80000005) {
430 cpuid(0x80000005, &aa, &bb, &cc, &dd); 429 /* Yes, we can. */
431 /* Add L1 data and code cache sizes. */ 430 cpuid(0x80000005, &aa, &bb, &cc, &dd);
432 c->x86_cache_size = (cc>>24)+(dd>>24); 431 /* Add L1 data and code cache sizes. */
433 } 432 c->x86_cache_size = (cc>>24)+(dd>>24);
434 sprintf(c->x86_model_id, "WinChip %s", name); 433 }
435 break; 434 sprintf(c->x86_model_id, "WinChip %s", name);
435 break;
436 436
437 case 6: 437 case 6:
438 init_c3(c); 438 init_c3(c);
439 break; 439 break;
440 } 440 }
441} 441}
442 442
443static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) 443static unsigned int __cpuinit
444centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
444{ 445{
445 /* VIA C3 CPUs (670-68F) need further shifting. */ 446 /* VIA C3 CPUs (670-68F) need further shifting. */
446 if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) 447 if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
447 size >>= 8; 448 size >>= 8;
448 449
449 /* VIA also screwed up Nehemiah stepping 1, and made 450 /*
450 it return '65KB' instead of '64KB' 451 * There's also an erratum in Nehemiah stepping 1, which
451 - Note, it seems this may only be in engineering samples. */ 452 * returns '65KB' instead of '64KB'
452 if ((c->x86 == 6) && (c->x86_model == 9) && (c->x86_mask == 1) && (size == 65)) 453 * - Note, it seems this may only be in engineering samples.
454 */
455 if ((c->x86 == 6) && (c->x86_model == 9) &&
456 (c->x86_mask == 1) && (size == 65))
453 size -= 1; 457 size -= 1;
454 458
455 return size; 459 return size;