aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/cpu-probe.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-05-05 12:45:59 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:12 -0400
commit4194318c3941fa9cfaa63dfdab9054fcae5e08d3 (patch)
tree2b44341a9cb911e34efbb33a35142fd2dcd536ff /arch/mips/kernel/cpu-probe.c
parentcd21dfcfbb5c43de54f6be795dde07397da2bc2f (diff)
Cleanup decoding of MIPSxx config registers.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
-rw-r--r--arch/mips/kernel/cpu-probe.c141
1 files changed, 98 insertions, 43 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 21ef82de8c5b..ba2dbc266d51 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2,9 +2,9 @@
2 * Processor capabilities determination functions. 2 * Processor capabilities determination functions.
3 * 3 *
4 * Copyright (C) xxxx the Anonymous 4 * Copyright (C) xxxx the Anonymous
5 * Copyright (C) 2003 Maciej W. Rozycki 5 * Copyright (C) 2003, 2004 Maciej W. Rozycki
6 * Copyright (C) 1994 - 2003 Ralf Baechle 6 * Copyright (C) 1994 - 2003 Ralf Baechle
7 * Copyright (C) 2001 MIPS Inc. 7 * Copyright (C) 2001, 2004 MIPS Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -415,69 +415,126 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
415 } 415 }
416} 416}
417 417
418static inline void decode_config1(struct cpuinfo_mips *c) 418static inline unsigned int decode_config0(struct cpuinfo_mips *c)
419{ 419{
420 unsigned long config0 = read_c0_config(); 420 unsigned int config0;
421 unsigned long config1; 421 int isa;
422 422
423 if ((config0 & (1 << 31)) == 0) 423 config0 = read_c0_config();
424 return; /* actually wort a panic() */ 424
425 if (((config0 & MIPS_CONF_MT) >> 7) == 1)
426 c->options |= MIPS_CPU_TLB;
427 isa = (config0 & MIPS_CONF_AT) >> 13;
428 switch (isa) {
429 case 0:
430 c->isa_level = MIPS_CPU_ISA_M32;
431 break;
432 case 2:
433 c->isa_level = MIPS_CPU_ISA_M64;
434 break;
435 default:
436 panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
437 }
438
439 return config0 & MIPS_CONF_M;
440}
441
442static inline unsigned int decode_config1(struct cpuinfo_mips *c)
443{
444 unsigned int config1;
425 445
426 /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
427 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
428 MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
429 MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
430 config1 = read_c0_config1(); 446 config1 = read_c0_config1();
431 if (config1 & (1 << 3)) 447
448 if (config1 & MIPS_CONF1_MD)
449 c->ases |= MIPS_ASE_MDMX;
450 if (config1 & MIPS_CONF1_WR)
432 c->options |= MIPS_CPU_WATCH; 451 c->options |= MIPS_CPU_WATCH;
433 if (config1 & (1 << 2)) 452 if (config1 & MIPS_CONF1_CA)
434 c->options |= MIPS_CPU_MIPS16; 453 c->ases |= MIPS_ASE_MIPS16;
435 if (config1 & (1 << 1)) 454 if (config1 & MIPS_CONF1_EP)
436 c->options |= MIPS_CPU_EJTAG; 455 c->options |= MIPS_CPU_EJTAG;
437 if (config1 & 1) { 456 if (config1 & MIPS_CONF1_FP) {
438 c->options |= MIPS_CPU_FPU; 457 c->options |= MIPS_CPU_FPU;
439 c->options |= MIPS_CPU_32FPR; 458 c->options |= MIPS_CPU_32FPR;
440 } 459 }
460 if (cpu_has_tlb)
461 c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
462
463 return config1 & MIPS_CONF_M;
464}
465
466static inline unsigned int decode_config2(struct cpuinfo_mips *c)
467{
468 unsigned int config2;
469
470 config2 = read_c0_config2();
471
472 if (config2 & MIPS_CONF2_SL)
473 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
474
475 return config2 & MIPS_CONF_M;
476}
477
478static inline unsigned int decode_config3(struct cpuinfo_mips *c)
479{
480 unsigned int config3;
481
482 config3 = read_c0_config3();
483
484 if (config3 & MIPS_CONF3_SM)
485 c->ases |= MIPS_ASE_SMARTMIPS;
486
487 return config3 & MIPS_CONF_M;
488}
489
490static inline void decode_configs(struct cpuinfo_mips *c)
491{
492 /* MIPS32 or MIPS64 compliant CPU. */
493 c->options = MIPS_CPU_4KEX | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
494 MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
495
441 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 496 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
442 497
443 c->tlbsize = ((config1 >> 25) & 0x3f) + 1; 498 /* Read Config registers. */
499 if (!decode_config0(c))
500 return; /* actually worth a panic() */
501 if (!decode_config1(c))
502 return;
503 if (!decode_config2(c))
504 return;
505 if (!decode_config3(c))
506 return;
444} 507}
445 508
446static inline void cpu_probe_mips(struct cpuinfo_mips *c) 509static inline void cpu_probe_mips(struct cpuinfo_mips *c)
447{ 510{
448 decode_config1(c); 511 decode_configs(c);
512 if (cpu_has_tlb)
513 c->options |= MIPS_CPU_4KTLB;
449 switch (c->processor_id & 0xff00) { 514 switch (c->processor_id & 0xff00) {
450 case PRID_IMP_4KC: 515 case PRID_IMP_4KC:
451 c->cputype = CPU_4KC; 516 c->cputype = CPU_4KC;
452 c->isa_level = MIPS_CPU_ISA_M32;
453 break; 517 break;
454 case PRID_IMP_4KEC: 518 case PRID_IMP_4KEC:
455 c->cputype = CPU_4KEC; 519 c->cputype = CPU_4KEC;
456 c->isa_level = MIPS_CPU_ISA_M32;
457 break; 520 break;
458 case PRID_IMP_4KECR2: 521 case PRID_IMP_4KECR2:
459 c->cputype = CPU_4KEC; 522 c->cputype = CPU_4KEC;
460 c->isa_level = MIPS_CPU_ISA_M32;
461 break; 523 break;
462 case PRID_IMP_4KSC: 524 case PRID_IMP_4KSC:
463 c->cputype = CPU_4KSC; 525 c->cputype = CPU_4KSC;
464 c->isa_level = MIPS_CPU_ISA_M32;
465 break; 526 break;
466 case PRID_IMP_5KC: 527 case PRID_IMP_5KC:
467 c->cputype = CPU_5KC; 528 c->cputype = CPU_5KC;
468 c->isa_level = MIPS_CPU_ISA_M64;
469 break; 529 break;
470 case PRID_IMP_20KC: 530 case PRID_IMP_20KC:
471 c->cputype = CPU_20KC; 531 c->cputype = CPU_20KC;
472 c->isa_level = MIPS_CPU_ISA_M64;
473 break; 532 break;
474 case PRID_IMP_24K: 533 case PRID_IMP_24K:
475 c->cputype = CPU_24K; 534 c->cputype = CPU_24K;
476 c->isa_level = MIPS_CPU_ISA_M32;
477 break; 535 break;
478 case PRID_IMP_25KF: 536 case PRID_IMP_25KF:
479 c->cputype = CPU_25KF; 537 c->cputype = CPU_25KF;
480 c->isa_level = MIPS_CPU_ISA_M64;
481 /* Probe for L2 cache */ 538 /* Probe for L2 cache */
482 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 539 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
483 break; 540 break;
@@ -486,7 +543,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
486 543
487static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) 544static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
488{ 545{
489 decode_config1(c); 546 decode_configs(c);
490 switch (c->processor_id & 0xff00) { 547 switch (c->processor_id & 0xff00) {
491 case PRID_IMP_AU1_REV1: 548 case PRID_IMP_AU1_REV1:
492 case PRID_IMP_AU1_REV2: 549 case PRID_IMP_AU1_REV2:
@@ -510,25 +567,19 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
510 panic("Unknown Au Core!"); 567 panic("Unknown Au Core!");
511 break; 568 break;
512 } 569 }
513 c->isa_level = MIPS_CPU_ISA_M32;
514 break; 570 break;
515 } 571 }
516} 572}
517 573
518static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) 574static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
519{ 575{
520 decode_config1(c); 576 decode_configs(c);
521 switch (c->processor_id & 0xff00) { 577 switch (c->processor_id & 0xff00) {
522 case PRID_IMP_SB1: 578 case PRID_IMP_SB1:
523 c->cputype = CPU_SB1; 579 c->cputype = CPU_SB1;
524 c->isa_level = MIPS_CPU_ISA_M64; 580#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
525 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
526 MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
527 MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
528 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
529#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
530 /* FPU in pass1 is known to have issues. */ 581 /* FPU in pass1 is known to have issues. */
531 c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; 582 c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
532#endif 583#endif
533 break; 584 break;
534 } 585 }
@@ -536,14 +587,12 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
536 587
537static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) 588static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
538{ 589{
539 decode_config1(c); 590 decode_configs(c);
591 if (cpu_has_tlb)
592 c->options |= MIPS_CPU_4KTLB;
540 switch (c->processor_id & 0xff00) { 593 switch (c->processor_id & 0xff00) {
541 case PRID_IMP_SR71000: 594 case PRID_IMP_SR71000:
542 c->cputype = CPU_SR71000; 595 c->cputype = CPU_SR71000;
543 c->isa_level = MIPS_CPU_ISA_M64;
544 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
545 MIPS_CPU_4KTLB | MIPS_CPU_FPU |
546 MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
547 c->scache.ways = 8; 596 c->scache.ways = 8;
548 c->tlbsize = 64; 597 c->tlbsize = 64;
549 break; 598 break;
@@ -572,15 +621,21 @@ __init void cpu_probe(void)
572 case PRID_COMP_SIBYTE: 621 case PRID_COMP_SIBYTE:
573 cpu_probe_sibyte(c); 622 cpu_probe_sibyte(c);
574 break; 623 break;
575
576 case PRID_COMP_SANDCRAFT: 624 case PRID_COMP_SANDCRAFT:
577 cpu_probe_sandcraft(c); 625 cpu_probe_sandcraft(c);
578 break; 626 break;
579 default: 627 default:
580 c->cputype = CPU_UNKNOWN; 628 c->cputype = CPU_UNKNOWN;
581 } 629 }
582 if (c->options & MIPS_CPU_FPU) 630 if (c->options & MIPS_CPU_FPU) {
583 c->fpu_id = cpu_get_fpu_id(); 631 c->fpu_id = cpu_get_fpu_id();
632
633 if (c->isa_level == MIPS_CPU_ISA_M32 ||
634 c->isa_level == MIPS_CPU_ISA_M64) {
635 if (c->fpu_id & MIPS_FPIR_3D)
636 c->ases |= MIPS_ASE_MIPS3D;
637 }
638 }
584} 639}
585 640
586__init void cpu_report(void) 641__init void cpu_report(void)