1 /*
2 * arch/mips64/kernel/cpu-probe.c
3 *
4 * Processor capabilities determination functions.
5 *
6 * Copyright (C) xxxx the Anonymous
7 * Copyright (C) 2003, 2004 Maciej W. Rozycki
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/ptrace.h>
18 #include <linux/stddef.h>
19
20 #include <asm/bugs.h>
21 #include <asm/compiler.h>
22 #include <asm/cpu.h>
23 #include <asm/fpu.h>
24 #include <asm/mipsregs.h>
25 #include <asm/system.h>
26
27 /*
28 * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
29 * the implementation of the "wait" feature differs between CPU families. This
30 * points to the function that implements CPU specific wait.
31 * The wait instruction stops the pipeline and reduces the power consumption of
32 * the CPU very much.
33 */
34 void (*cpu_wait)(void) = NULL;
35
r3081_wait(void)36 static void r3081_wait(void)
37 {
38 unsigned long cfg = read_c0_conf();
39 write_c0_conf(cfg | R30XX_CONF_HALT);
40 }
41
r39xx_wait(void)42 static void r39xx_wait(void)
43 {
44 unsigned long cfg = read_c0_conf();
45 write_c0_conf(cfg | TX39_CONF_HALT);
46 }
47
r4k_wait(void)48 static void r4k_wait(void)
49 {
50 __asm__(".set\tmips3\n\t"
51 "wait\n\t"
52 ".set\tmips0");
53 }
54
au1k_wait(void)55 void au1k_wait(void)
56 {
57 #ifdef CONFIG_PM
58 /* using the wait instruction makes CP0 counter unusable */
59 __asm__(".set\tmips3\n\t"
60 "wait\n\t"
61 "nop\n\t"
62 "nop\n\t"
63 "nop\n\t"
64 "nop\n\t"
65 ".set\tmips0");
66 #else
67 __asm__("nop\n\t"
68 "nop");
69 #endif
70 }
71
check_wait(void)72 static inline void check_wait(void)
73 {
74 struct cpuinfo_mips *c = ¤t_cpu_data;
75
76 printk("Checking for 'wait' instruction... ");
77 switch (c->cputype) {
78 case CPU_R3081:
79 case CPU_R3081E:
80 cpu_wait = r3081_wait;
81 printk(" available.\n");
82 break;
83 case CPU_TX3927:
84 cpu_wait = r39xx_wait;
85 printk(" available.\n");
86 break;
87 case CPU_R4200:
88 /* case CPU_R4300: */
89 case CPU_R4600:
90 case CPU_R4640:
91 case CPU_R4650:
92 case CPU_R4700:
93 case CPU_R5000:
94 case CPU_NEVADA:
95 case CPU_RM7000:
96 case CPU_RM9000:
97 case CPU_TX49XX:
98 case CPU_4KC:
99 case CPU_4KEC:
100 case CPU_4KSC:
101 case CPU_5KC:
102 /* case CPU_20KC:*/
103 case CPU_24K:
104 case CPU_25KF:
105 cpu_wait = r4k_wait;
106 printk(" available.\n");
107 break;
108 case CPU_AU1000:
109 case CPU_AU1100:
110 case CPU_AU1500:
111 cpu_wait = au1k_wait;
112 printk(" available.\n");
113 break;
114 default:
115 printk(" unavailable.\n");
116 break;
117 }
118 }
119
align_mod(const int align,const int mod)120 static inline void align_mod(const int align, const int mod)
121 {
122 asm volatile(
123 ".set push\n\t"
124 ".set noreorder\n\t"
125 ".balign %0\n\t"
126 ".rept %1\n\t"
127 "nop\n\t"
128 ".endr\n\t"
129 ".set pop"
130 :
131 : "n" (align), "n" (mod));
132 }
133
mult_sh_align_mod(long * v1,long * v2,long * w,const int align,const int mod)134 static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
135 const int align, const int mod)
136 {
137 unsigned long flags;
138 int m1, m2;
139 long p, s, lv1, lv2, lw;
140
141 /*
142 * We want the multiply and the shift to be isolated from the
143 * rest of the code to disable gcc optimizations. Hence the
144 * asm statements that execute nothing, but make gcc not know
145 * what the values of m1, m2 and s are and what lv2 and p are
146 * used for.
147 */
148
149 local_irq_save(flags);
150 /*
151 * The following code leads to a wrong result of the first
152 * dsll32 when executed on R4000 rev. 2.2 or 3.0 (PRId
153 * 00000422 or 00000430, respectively).
154 *
155 * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
156 * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for
157 * details. I got no permission to duplicate them here,
158 * sigh... --macro
159 */
160 asm volatile(
161 ""
162 : "=r" (m1), "=r" (m2), "=r" (s)
163 : "0" (5), "1" (8), "2" (5));
164 align_mod(align, mod);
165 /*
166 * The trailing nop is needed to fullfill the two-instruction
167 * requirement between reading hi/lo and staring a mult/div.
168 * Leaving it out may cause gas insert a nop itself breaking
169 * the desired alignment of the next chunk.
170 */
171 asm volatile(
172 ".set push\n\t"
173 ".set noat\n\t"
174 ".set noreorder\n\t"
175 ".set nomacro\n\t"
176 "mult %2, %3\n\t"
177 "dsll32 %0, %4, %5\n\t"
178 "mflo $0\n\t"
179 "dsll32 %1, %4, %5\n\t"
180 "nop\n\t"
181 ".set pop"
182 : "=&r" (lv1), "=r" (lw)
183 : "r" (m1), "r" (m2), "r" (s), "I" (0)
184 : "hi", "lo", GCC_REG_ACCUM);
185 /* We have to use single integers for m1 and m2 and a double
186 * one for p to be sure the mulsidi3 gcc's RTL multiplication
187 * instruction has the workaround applied. Older versions of
188 * gcc have correct umulsi3 and mulsi3, but other
189 * multiplication variants lack the workaround.
190 */
191 asm volatile(
192 ""
193 : "=r" (m1), "=r" (m2), "=r" (s)
194 : "0" (m1), "1" (m2), "2" (s));
195 align_mod(align, mod);
196 p = m1 * m2;
197 lv2 = s << 32;
198 asm volatile(
199 ""
200 : "=r" (lv2)
201 : "0" (lv2), "r" (p));
202 local_irq_restore(flags);
203
204 *v1 = lv1;
205 *v2 = lv2;
206 *w = lw;
207 }
208
check_mult_sh(void)209 static inline void check_mult_sh(void)
210 {
211 long v1[8], v2[8], w[8];
212 int bug, fix, i;
213
214 printk("Checking for the multiply/shift bug... ");
215
216 /*
217 * Testing discovered false negatives for certain code offsets
218 * into cache lines. Hence we test all possible offsets for
219 * the worst assumption of an R4000 I-cache line width of 32
220 * bytes.
221 *
222 * We can't use a loop as alignment directives need to be
223 * immediates.
224 */
225 mult_sh_align_mod(&v1[0], &v2[0], &w[0], 32, 0);
226 mult_sh_align_mod(&v1[1], &v2[1], &w[1], 32, 1);
227 mult_sh_align_mod(&v1[2], &v2[2], &w[2], 32, 2);
228 mult_sh_align_mod(&v1[3], &v2[3], &w[3], 32, 3);
229 mult_sh_align_mod(&v1[4], &v2[4], &w[4], 32, 4);
230 mult_sh_align_mod(&v1[5], &v2[5], &w[5], 32, 5);
231 mult_sh_align_mod(&v1[6], &v2[6], &w[6], 32, 6);
232 mult_sh_align_mod(&v1[7], &v2[7], &w[7], 32, 7);
233
234 bug = 0;
235 for (i = 0; i < 8; i++)
236 if (v1[i] != w[i])
237 bug = 1;
238
239 if (bug == 0) {
240 printk("no.\n");
241 return;
242 }
243
244 printk("yes, workaround... ");
245
246 fix = 1;
247 for (i = 0; i < 8; i++)
248 if (v2[i] != w[i])
249 fix = 0;
250
251 if (fix == 1) {
252 printk("yes.\n");
253 return;
254 }
255
256 printk("no.\n");
257 panic("Reliable operation impossible!\n"
258 #ifndef CONFIG_CPU_R4000
259 "Configure for R4000 to enable the workaround."
260 #else
261 "Please report to <linux-mips@linux-mips.org>."
262 #endif
263 );
264 }
265
266 static volatile int daddi_ov __initdata = 0;
267
do_daddi_ov(struct pt_regs * regs)268 asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
269 {
270 daddi_ov = 1;
271 regs->cp0_epc += 4;
272 }
273
check_daddi(void)274 static inline void check_daddi(void)
275 {
276 extern asmlinkage void handle_daddi_ov(void);
277 unsigned long flags;
278 void *handler;
279 long v, tmp;
280
281 printk("Checking for the daddi bug... ");
282
283 local_irq_save(flags);
284 handler = set_except_vector(12, handle_daddi_ov);
285 /*
286 * The following code fails to trigger an overflow exception
287 * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
288 * 00000430, respectively).
289 *
290 * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
291 * 3.0" by MIPS Technologies, Inc., erratum #23 for details.
292 * I got no permission to duplicate it here, sigh... --macro
293 */
294 asm volatile(
295 ".set push\n\t"
296 ".set noat\n\t"
297 ".set noreorder\n\t"
298 ".set nomacro\n\t"
299 "addiu %1, $0, %2\n\t"
300 "dsrl %1, %1, 1\n\t"
301 #ifdef HAVE_AS_SET_DADDI
302 ".set daddi\n\t"
303 #endif
304 "daddi %0, %1, %3\n\t"
305 ".set pop"
306 : "=r" (v), "=&r" (tmp)
307 : "I" (0xffffffffffffdb9a), "I" (0x1234));
308 set_except_vector(12, handler);
309 local_irq_restore(flags);
310
311 if (daddi_ov) {
312 printk("no.\n");
313 return;
314 }
315
316 printk("yes, workaround... ");
317
318 local_irq_save(flags);
319 handler = set_except_vector(12, handle_daddi_ov);
320 asm volatile(
321 "addiu %1, $0, %2\n\t"
322 "dsrl %1, %1, 1\n\t"
323 "daddi %0, %1, %3"
324 : "=r" (v), "=&r" (tmp)
325 : "I" (0xffffffffffffdb9a), "I" (0x1234));
326 set_except_vector(12, handler);
327 local_irq_restore(flags);
328
329 if (daddi_ov) {
330 printk("yes.\n");
331 return;
332 }
333
334 printk("no.\n");
335 panic("Reliable operation impossible!\n"
336 #if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
337 "Configure for R4000 or R4400 to enable the workaround."
338 #else
339 "Please report to <linux-mips@linux-mips.org>."
340 #endif
341 );
342 }
343
check_daddiu(void)344 static inline void check_daddiu(void)
345 {
346 long v, w, tmp;
347
348 printk("Checking for the daddiu bug... ");
349
350 /*
351 * The following code leads to a wrong result of daddiu when
352 * executed on R4400 rev. 1.0 (PRId 00000440).
353 *
354 * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by
355 * MIPS Technologies, Inc., erratum #7 for details.
356 *
357 * According to "MIPS R4000PC/SC Errata, Processor Revision
358 * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this
359 * problem affects R4000 rev. 2.2 and 3.0 (PRId 00000422 and
360 * 00000430, respectively), too. Testing failed to trigger it
361 * so far.
362 *
363 * I got no permission to duplicate the errata here, sigh...
364 * --macro
365 */
366 asm volatile(
367 ".set push\n\t"
368 ".set noat\n\t"
369 ".set noreorder\n\t"
370 ".set nomacro\n\t"
371 "addiu %2, $0, %3\n\t"
372 "dsrl %2, %2, 1\n\t"
373 #ifdef HAVE_AS_SET_DADDI
374 ".set daddi\n\t"
375 #endif
376 "daddiu %0, %2, %4\n\t"
377 "addiu %1, $0, %4\n\t"
378 "daddu %1, %2\n\t"
379 ".set pop"
380 : "=&r" (v), "=&r" (w), "=&r" (tmp)
381 : "I" (0xffffffffffffdb9a), "I" (0x1234));
382
383 if (v == w) {
384 printk("no.\n");
385 return;
386 }
387
388 printk("yes, workaround... ");
389
390 asm volatile(
391 "addiu %2, $0, %3\n\t"
392 "dsrl %2, %2, 1\n\t"
393 "daddiu %0, %2, %4\n\t"
394 "addiu %1, $0, %4\n\t"
395 "daddu %1, %2"
396 : "=&r" (v), "=&r" (w), "=&r" (tmp)
397 : "I" (0xffffffffffffdb9a), "I" (0x1234));
398
399 if (v == w) {
400 printk("yes.\n");
401 return;
402 }
403
404 printk("no.\n");
405 panic("Reliable operation impossible!\n"
406 #if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
407 "Configure for R4000 or R4400 to enable the workaround."
408 #else
409 "Please report to <linux-mips@linux-mips.org>."
410 #endif
411 );
412 }
413
check_bugs(void)414 void __init check_bugs(void)
415 {
416 check_wait();
417 check_mult_sh();
418 check_daddi();
419 check_daddiu();
420 }
421
422 /*
423 * Probe whether cpu has config register by trying to play with
424 * alternate cache bit and see whether it matters.
425 * It's used by cpu_probe to distinguish between R3000A and R3081.
426 */
cpu_has_confreg(void)427 static inline int cpu_has_confreg(void)
428 {
429 #ifdef CONFIG_CPU_R3000
430 extern unsigned long r3k_cache_size(unsigned long);
431 unsigned long size1, size2;
432 unsigned long cfg = read_c0_conf();
433
434 size1 = r3k_cache_size(ST0_ISC);
435 write_c0_conf(cfg ^ R30XX_CONF_AC);
436 size2 = r3k_cache_size(ST0_ISC);
437 write_c0_conf(cfg);
438 return size1 != size2;
439 #else
440 return 0;
441 #endif
442 }
443
444 /*
445 * Get the FPU Implementation/Revision.
446 */
cpu_get_fpu_id(void)447 static inline unsigned long cpu_get_fpu_id(void)
448 {
449 unsigned long tmp, fpu_id;
450
451 tmp = read_c0_status();
452 __enable_fpu();
453 fpu_id = read_32bit_cp1_register(CP1_REVISION);
454 write_c0_status(tmp);
455 return fpu_id;
456 }
457
458 /*
459 * Check the CPU has an FPU the official way.
460 */
__cpu_has_fpu(void)461 static inline int __cpu_has_fpu(void)
462 {
463 return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
464 }
465
466 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
467 | MIPS_CPU_COUNTER)
468
cpu_probe_legacy(struct cpuinfo_mips * c)469 static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
470 {
471 switch (c->processor_id & 0xff00) {
472 case PRID_IMP_R2000:
473 c->cputype = CPU_R2000;
474 c->isa_level = MIPS_CPU_ISA_I;
475 c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
476 if (__cpu_has_fpu())
477 c->options |= MIPS_CPU_FPU;
478 c->tlbsize = 64;
479 break;
480 case PRID_IMP_R3000:
481 if ((c->processor_id & 0xff) == PRID_REV_R3000A)
482 if (cpu_has_confreg())
483 c->cputype = CPU_R3081E;
484 else
485 c->cputype = CPU_R3000A;
486 else
487 c->cputype = CPU_R3000;
488 c->isa_level = MIPS_CPU_ISA_I;
489 c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
490 if (__cpu_has_fpu())
491 c->options |= MIPS_CPU_FPU;
492 c->tlbsize = 64;
493 break;
494 case PRID_IMP_R4000:
495 if (read_c0_config() & CONF_SC) {
496 if ((c->processor_id & 0xff) >= PRID_REV_R4400)
497 c->cputype = CPU_R4400PC;
498 else
499 c->cputype = CPU_R4000PC;
500 } else {
501 if ((c->processor_id & 0xff) >= PRID_REV_R4400)
502 c->cputype = CPU_R4400SC;
503 else
504 c->cputype = CPU_R4000SC;
505 }
506
507 c->isa_level = MIPS_CPU_ISA_III;
508 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
509 MIPS_CPU_WATCH | MIPS_CPU_VCE |
510 MIPS_CPU_LLSC;
511 c->tlbsize = 48;
512 break;
513 case PRID_IMP_VR41XX:
514 switch (c->processor_id & 0xf0) {
515 #ifndef CONFIG_VR4181
516 case PRID_REV_VR4111:
517 c->cputype = CPU_VR4111;
518 break;
519 #else
520 case PRID_REV_VR4181:
521 c->cputype = CPU_VR4181;
522 break;
523 #endif
524 case PRID_REV_VR4121:
525 c->cputype = CPU_VR4121;
526 break;
527 case PRID_REV_VR4122:
528 if ((c->processor_id & 0xf) < 0x3)
529 c->cputype = CPU_VR4122;
530 else
531 c->cputype = CPU_VR4181A;
532 break;
533 case PRID_REV_VR4130:
534 if ((c->processor_id & 0xf) < 0x4)
535 c->cputype = CPU_VR4131;
536 else
537 c->cputype = CPU_VR4133;
538 break;
539 default:
540 printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
541 c->cputype = CPU_VR41XX;
542 break;
543 }
544 c->isa_level = MIPS_CPU_ISA_III;
545 c->options = R4K_OPTS;
546 c->tlbsize = 32;
547 break;
548 case PRID_IMP_R4300:
549 c->cputype = CPU_R4300;
550 c->isa_level = MIPS_CPU_ISA_III;
551 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
552 MIPS_CPU_LLSC;
553 c->tlbsize = 32;
554 break;
555 case PRID_IMP_R4600:
556 c->cputype = CPU_R4600;
557 c->isa_level = MIPS_CPU_ISA_III;
558 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
559 c->tlbsize = 48;
560 break;
561 #if 0
562 case PRID_IMP_R4650:
563 /*
564 * This processor doesn't have an MMU, so it's not
565 * "real easy" to run Linux on it. It is left purely
566 * for documentation. Commented out because it shares
567 * it's c0_prid id number with the TX3900.
568 */
569 c->cputype = CPU_R4650;
570 c->isa_level = MIPS_CPU_ISA_III;
571 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
572 c->tlbsize = 48;
573 break;
574 #endif
575 case PRID_IMP_TX39:
576 c->isa_level = MIPS_CPU_ISA_I;
577 c->options = MIPS_CPU_TLB;
578
579 if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
580 c->cputype = CPU_TX3927;
581 c->tlbsize = 64;
582 } else {
583 switch (c->processor_id & 0xff) {
584 case PRID_REV_TX3912:
585 c->cputype = CPU_TX3912;
586 c->tlbsize = 32;
587 break;
588 case PRID_REV_TX3922:
589 c->cputype = CPU_TX3922;
590 c->tlbsize = 64;
591 break;
592 default:
593 c->cputype = CPU_UNKNOWN;
594 break;
595 }
596 }
597 break;
598 case PRID_IMP_R4700:
599 c->cputype = CPU_R4700;
600 c->isa_level = MIPS_CPU_ISA_III;
601 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
602 MIPS_CPU_LLSC;
603 c->tlbsize = 48;
604 break;
605 case PRID_IMP_TX49:
606 c->cputype = CPU_TX49XX;
607 c->isa_level = MIPS_CPU_ISA_III;
608 c->options = R4K_OPTS | MIPS_CPU_LLSC;
609 if (!(c->processor_id & 0x08))
610 c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
611 c->tlbsize = 48;
612 break;
613 case PRID_IMP_R5000:
614 c->cputype = CPU_R5000;
615 c->isa_level = MIPS_CPU_ISA_IV;
616 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
617 MIPS_CPU_LLSC;
618 c->tlbsize = 48;
619 break;
620 case PRID_IMP_R5432:
621 c->cputype = CPU_R5432;
622 c->isa_level = MIPS_CPU_ISA_IV;
623 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
624 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
625 c->tlbsize = 48;
626 break;
627 case PRID_IMP_R5500:
628 c->cputype = CPU_R5500;
629 c->isa_level = MIPS_CPU_ISA_IV;
630 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
631 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
632 c->tlbsize = 48;
633 break;
634 case PRID_IMP_NEVADA:
635 c->cputype = CPU_NEVADA;
636 c->isa_level = MIPS_CPU_ISA_IV;
637 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
638 MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
639 c->tlbsize = 48;
640 break;
641 case PRID_IMP_R6000:
642 c->cputype = CPU_R6000;
643 c->isa_level = MIPS_CPU_ISA_II;
644 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
645 MIPS_CPU_LLSC;
646 c->tlbsize = 32;
647 break;
648 case PRID_IMP_R6000A:
649 c->cputype = CPU_R6000A;
650 c->isa_level = MIPS_CPU_ISA_II;
651 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
652 MIPS_CPU_LLSC;
653 c->tlbsize = 32;
654 break;
655 case PRID_IMP_RM7000:
656 c->cputype = CPU_RM7000;
657 c->isa_level = MIPS_CPU_ISA_IV;
658 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
659 MIPS_CPU_LLSC;
660 /*
661 * Undocumented RM7000: Bit 29 in the info register of
662 * the RM7000 v2.0 indicates if the TLB has 48 or 64
663 * entries.
664 *
665 * 29 1 => 64 entry JTLB
666 * 0 => 48 entry JTLB
667 */
668 c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
669 break;
670 case PRID_IMP_RM9000:
671 c->cputype = CPU_RM9000;
672 c->isa_level = MIPS_CPU_ISA_IV;
673 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
674 MIPS_CPU_LLSC;
675 /*
676 * Bit 29 in the info register of the RM9000
677 * indicates if the TLB has 48 or 64 entries.
678 *
679 * 29 1 => 64 entry JTLB
680 * 0 => 48 entry JTLB
681 */
682 c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
683 break;
684 case PRID_IMP_R8000:
685 c->cputype = CPU_R8000;
686 c->isa_level = MIPS_CPU_ISA_IV;
687 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
688 MIPS_CPU_FPU | MIPS_CPU_32FPR |
689 MIPS_CPU_LLSC;
690 c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
691 break;
692 case PRID_IMP_R10000:
693 c->cputype = CPU_R10000;
694 c->isa_level = MIPS_CPU_ISA_IV;
695 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
696 MIPS_CPU_FPU | MIPS_CPU_32FPR |
697 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
698 MIPS_CPU_LLSC;
699 c->tlbsize = 64;
700 break;
701 case PRID_IMP_R12000:
702 c->cputype = CPU_R12000;
703 c->isa_level = MIPS_CPU_ISA_IV;
704 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
705 MIPS_CPU_FPU | MIPS_CPU_32FPR |
706 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
707 MIPS_CPU_LLSC;
708 c->tlbsize = 64;
709 break;
710 default:
711 c->cputype = CPU_UNKNOWN;
712 break;
713 }
714 }
715
decode_config1(struct cpuinfo_mips * c)716 static inline void decode_config1(struct cpuinfo_mips *c)
717 {
718 unsigned long config0 = read_c0_config();
719 unsigned long config1;
720
721 if ((config0 & (1 << 31)) == 0)
722 return; /* actually wort a panic() */
723
724 /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
725 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
726 MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
727 MIPS_CPU_LLSC;
728 config1 = read_c0_config1();
729 if (config1 & (1 << 3))
730 c->options |= MIPS_CPU_WATCH;
731 if (config1 & (1 << 2))
732 c->options |= MIPS_CPU_MIPS16;
733 if (config1 & (1 << 1))
734 c->options |= MIPS_CPU_EJTAG;
735 if (config1 & 1) {
736 c->options |= MIPS_CPU_FPU;
737 c->options |= MIPS_CPU_32FPR;
738 }
739 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
740
741 c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
742 }
743
cpu_probe_mips(struct cpuinfo_mips * c)744 static inline void cpu_probe_mips(struct cpuinfo_mips *c)
745 {
746 decode_config1(c);
747 switch (c->processor_id & 0xff00) {
748 case PRID_IMP_4KC:
749 c->cputype = CPU_4KC;
750 c->isa_level = MIPS_CPU_ISA_M32;
751 break;
752 case PRID_IMP_4KEC:
753 c->cputype = CPU_4KEC;
754 c->isa_level = MIPS_CPU_ISA_M32;
755 break;
756 case PRID_IMP_4KSC:
757 c->cputype = CPU_4KSC;
758 c->isa_level = MIPS_CPU_ISA_M32;
759 break;
760 case PRID_IMP_5KC:
761 c->cputype = CPU_5KC;
762 c->isa_level = MIPS_CPU_ISA_M64;
763 break;
764 case PRID_IMP_20KC:
765 c->cputype = CPU_20KC;
766 c->isa_level = MIPS_CPU_ISA_M64;
767 break;
768 case PRID_IMP_24K:
769 c->cputype = CPU_24K;
770 c->isa_level = MIPS_CPU_ISA_M32;
771 break;
772 case PRID_IMP_25KF:
773 c->cputype = CPU_25KF;
774 c->isa_level = MIPS_CPU_ISA_M64;
775 /* Probe for L2 cache */
776 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
777 break;
778 default:
779 c->cputype = CPU_UNKNOWN;
780 break;
781 }
782 }
783
cpu_probe_alchemy(struct cpuinfo_mips * c)784 static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
785 {
786 decode_config1(c);
787 switch (c->processor_id & 0xff00) {
788 case PRID_IMP_AU1_REV1:
789 case PRID_IMP_AU1_REV2:
790 switch ((c->processor_id >> 24) & 0xff) {
791 case 0:
792 c->cputype = CPU_AU1000;
793 break;
794 case 1:
795 c->cputype = CPU_AU1500;
796 break;
797 case 2:
798 c->cputype = CPU_AU1100;
799 break;
800 default:
801 panic("Unknown Au Core!");
802 break;
803 }
804 c->isa_level = MIPS_CPU_ISA_M32;
805 break;
806 }
807 }
808
cpu_probe_sibyte(struct cpuinfo_mips * c)809 static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
810 {
811 decode_config1(c);
812 switch (c->processor_id & 0xff00) {
813 case PRID_IMP_SB1:
814 c->cputype = CPU_SB1;
815 c->isa_level = MIPS_CPU_ISA_M64;
816 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
817 MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
818 MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
819 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
820 #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
821 /* FPU in pass1 is known to have issues. */
822 c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
823 #endif
824 break;
825 default:
826 c->cputype = CPU_UNKNOWN;
827 break;
828 }
829 }
830
cpu_probe_sandcraft(struct cpuinfo_mips * c)831 static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
832 {
833 decode_config1(c);
834 switch (c->processor_id & 0xff00) {
835 case PRID_IMP_SR71000:
836 c->cputype = CPU_SR71000;
837 c->isa_level = MIPS_CPU_ISA_M64;
838 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
839 MIPS_CPU_4KTLB | MIPS_CPU_FPU |
840 MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
841 c->scache.ways = 8;
842 c->tlbsize = 64;
843 break;
844 default:
845 c->cputype = CPU_UNKNOWN;
846 break;
847 }
848 }
849
cpu_probe(void)850 __init void cpu_probe(void)
851 {
852 struct cpuinfo_mips *c = ¤t_cpu_data;
853
854 c->processor_id = PRID_IMP_UNKNOWN;
855 c->fpu_id = FPIR_IMP_NONE;
856 c->cputype = CPU_UNKNOWN;
857
858 c->processor_id = read_c0_prid();
859 switch (c->processor_id & 0xff0000) {
860 case PRID_COMP_LEGACY:
861 cpu_probe_legacy(c);
862 break;
863 case PRID_COMP_MIPS:
864 cpu_probe_mips(c);
865 break;
866 case PRID_COMP_ALCHEMY:
867 cpu_probe_alchemy(c);
868 break;
869 case PRID_COMP_SIBYTE:
870 cpu_probe_sibyte(c);
871 break;
872
873 case PRID_COMP_SANDCRAFT:
874 cpu_probe_sandcraft(c);
875 break;
876 default:
877 c->cputype = CPU_UNKNOWN;
878 }
879 if (c->options & MIPS_CPU_FPU)
880 c->fpu_id = cpu_get_fpu_id();
881 }
882
cpu_report(void)883 __init void cpu_report(void)
884 {
885 struct cpuinfo_mips *c = ¤t_cpu_data;
886
887 printk("CPU revision is: %08x\n", c->processor_id);
888 if (c->options & MIPS_CPU_FPU)
889 printk("FPU revision is: %08x\n", c->fpu_id);
890 }
891