Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Cleanup decoding of MIPSxx config registers.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+175 -49
+98 -43
arch/mips/kernel/cpu-probe.c
··· 2 2 * Processor capabilities determination functions. 3 3 * 4 4 * Copyright (C) xxxx the Anonymous 5 - * Copyright (C) 2003 Maciej W. Rozycki 5 + * Copyright (C) 2003, 2004 Maciej W. Rozycki 6 6 * Copyright (C) 1994 - 2003 Ralf Baechle 7 - * Copyright (C) 2001 MIPS Inc. 7 + * Copyright (C) 2001, 2004 MIPS Inc. 8 8 * 9 9 * This program is free software; you can redistribute it and/or 10 10 * modify it under the terms of the GNU General Public License ··· 415 415 } 416 416 } 417 417 418 - static inline void decode_config1(struct cpuinfo_mips *c) 418 + static inline unsigned int decode_config0(struct cpuinfo_mips *c) 419 419 { 420 - unsigned long config0 = read_c0_config(); 421 - unsigned long config1; 420 + unsigned int config0; 421 + int isa; 422 422 423 - if ((config0 & (1 << 31)) == 0) 424 - return; /* actually wort a panic() */ 423 + config0 = read_c0_config(); 425 424 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; 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 + 442 + static inline unsigned int decode_config1(struct cpuinfo_mips *c) 443 + { 444 + unsigned int config1; 445 + 430 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 451 c->options |= MIPS_CPU_WATCH; 433 - if (config1 & (1 << 2)) 434 - c->options |= MIPS_CPU_MIPS16; 435 - if (config1 & (1 << 1)) 452 + if (config1 & MIPS_CONF1_CA) 453 + c->ases |= MIPS_ASE_MIPS16; 454 + if (config1 & MIPS_CONF1_EP) 436 455 c->options |= MIPS_CPU_EJTAG; 437 - if (config1 & 1) { 456 + if (config1 & MIPS_CONF1_FP) { 438 457 c->options |= MIPS_CPU_FPU; 439 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 + 466 + static 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 + 478 + static 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 + 490 + static 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 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 446 509 static 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 514 switch (c->processor_id & 0xff00) { 450 515 case PRID_IMP_4KC: 451 516 c->cputype = CPU_4KC; 452 - c->isa_level = MIPS_CPU_ISA_M32; 453 517 break; 454 518 case PRID_IMP_4KEC: 455 519 c->cputype = CPU_4KEC; 456 - c->isa_level = MIPS_CPU_ISA_M32; 457 520 break; 458 521 case PRID_IMP_4KECR2: 459 522 c->cputype = CPU_4KEC; 460 - c->isa_level = MIPS_CPU_ISA_M32; 461 523 break; 462 524 case PRID_IMP_4KSC: 463 525 c->cputype = CPU_4KSC; 464 - c->isa_level = MIPS_CPU_ISA_M32; 465 526 break; 466 527 case PRID_IMP_5KC: 467 528 c->cputype = CPU_5KC; 468 - c->isa_level = MIPS_CPU_ISA_M64; 469 529 break; 470 530 case PRID_IMP_20KC: 471 531 c->cputype = CPU_20KC; 472 - c->isa_level = MIPS_CPU_ISA_M64; 473 532 break; 474 533 case PRID_IMP_24K: 475 534 c->cputype = CPU_24K; 476 - c->isa_level = MIPS_CPU_ISA_M32; 477 535 break; 478 536 case PRID_IMP_25KF: 479 537 c->cputype = CPU_25KF; 480 - c->isa_level = MIPS_CPU_ISA_M64; 481 538 /* Probe for L2 cache */ 482 539 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 483 540 break; ··· 543 486 544 487 static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) 545 488 { 546 - decode_config1(c); 489 + decode_configs(c); 547 490 switch (c->processor_id & 0xff00) { 548 491 case PRID_IMP_AU1_REV1: 549 492 case PRID_IMP_AU1_REV2: ··· 567 510 panic("Unknown Au Core!"); 568 511 break; 569 512 } 570 - c->isa_level = MIPS_CPU_ISA_M32; 571 513 break; 572 514 } 573 515 } 574 516 575 517 static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) 576 518 { 577 - decode_config1(c); 519 + decode_configs(c); 578 520 switch (c->processor_id & 0xff00) { 579 521 case PRID_IMP_SB1: 580 522 c->cputype = CPU_SB1; 581 - c->isa_level = MIPS_CPU_ISA_M64; 582 - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 583 - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | 584 - MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | 585 - MIPS_CPU_WATCH | MIPS_CPU_LLSC; 586 - #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS 523 + #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS 587 524 /* FPU in pass1 is known to have issues. */ 588 - c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; 525 + c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); 589 526 #endif 590 527 break; 591 528 } ··· 587 536 588 537 static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) 589 538 { 590 - decode_config1(c); 539 + decode_configs(c); 540 + if (cpu_has_tlb) 541 + c->options |= MIPS_CPU_4KTLB; 591 542 switch (c->processor_id & 0xff00) { 592 543 case PRID_IMP_SR71000: 593 544 c->cputype = CPU_SR71000; 594 - c->isa_level = MIPS_CPU_ISA_M64; 595 - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 596 - MIPS_CPU_4KTLB | MIPS_CPU_FPU | 597 - MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; 598 545 c->scache.ways = 8; 599 546 c->tlbsize = 64; 600 547 break; ··· 621 572 case PRID_COMP_SIBYTE: 622 573 cpu_probe_sibyte(c); 623 574 break; 624 - 625 575 case PRID_COMP_SANDCRAFT: 626 576 cpu_probe_sandcraft(c); 627 577 break; 628 578 default: 629 579 c->cputype = CPU_UNKNOWN; 630 580 } 631 - if (c->options & MIPS_CPU_FPU) 581 + if (c->options & MIPS_CPU_FPU) { 632 582 c->fpu_id = cpu_get_fpu_id(); 583 + 584 + if (c->isa_level == MIPS_CPU_ISA_M32 || 585 + c->isa_level == MIPS_CPU_ISA_M64) { 586 + if (c->fpu_id & MIPS_FPIR_3D) 587 + c->ases |= MIPS_ASE_MIPS3D; 588 + } 589 + } 633 590 } 634 591 635 592 __init void cpu_report(void)
+7 -1
arch/mips/kernel/proc.c
··· 2 2 * linux/arch/mips/kernel/proc.c 3 3 * 4 4 * Copyright (C) 1995, 1996, 2001 Ralf Baechle 5 - * Copyright (C) 2001 MIPS Technologies, Inc. 5 + * Copyright (C) 2001, 2004 MIPS Technologies, Inc. 6 + * Copyright (C) 2004 Maciej W. Rozycki 6 7 */ 7 8 #include <linux/config.h> 8 9 #include <linux/delay.h> ··· 119 118 cpu_has_divec ? "yes" : "no"); 120 119 seq_printf(m, "hardware watchpoint\t: %s\n", 121 120 cpu_has_watch ? "yes" : "no"); 121 + seq_printf(m, "ASEs implemented\t:%s%s%s%s\n", 122 + cpu_has_mips16 ? " mips16" : "", 123 + cpu_has_mdmx ? " mdmx" : "", 124 + cpu_has_mips3d ? " mips3d" : "", 125 + cpu_has_smartmips ? " smartmips" : ""); 122 126 123 127 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 124 128 cpu_has_vce ? "%u" : "not available");
+13 -3
include/asm-mips/cpu-features.h
··· 4 4 * for more details. 5 5 * 6 6 * Copyright (C) 2003, 2004 Ralf Baechle 7 + * Copyright (C) 2004 Maciej W. Rozycki 7 8 */ 8 9 #ifndef __ASM_CPU_FEATURES_H 9 10 #define __ASM_CPU_FEATURES_H ··· 40 39 #ifndef cpu_has_watch 41 40 #define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH) 42 41 #endif 43 - #ifndef cpu_has_mips16 44 - #define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16) 45 - #endif 46 42 #ifndef cpu_has_divec 47 43 #define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC) 48 44 #endif ··· 63 65 #endif 64 66 #ifndef cpu_has_llsc 65 67 #define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) 68 + #endif 69 + #ifndef cpu_has_mips16 70 + #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) 71 + #endif 72 + #ifndef cpu_has_mdmx 73 + #define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX) 74 + #endif 75 + #ifndef cpu_has_mips3d 76 + #define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D) 77 + #endif 78 + #ifndef cpu_has_smartmips 79 + #define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS) 66 80 #endif 67 81 #ifndef cpu_has_vtag_icache 68 82 #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
+2
include/asm-mips/cpu-info.h
··· 7 7 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle 8 8 * Copyright (C) 1996 Paul M. Antoine 9 9 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 10 + * Copyright (C) 2004 Maciej W. Rozycki 10 11 */ 11 12 #ifndef __ASM_CPU_INFO_H 12 13 #define __ASM_CPU_INFO_H ··· 62 61 * Capability and feature descriptor structure for MIPS CPU 63 62 */ 64 63 unsigned long options; 64 + unsigned long ases; 65 65 unsigned int processor_id; 66 66 unsigned int fpu_id; 67 67 unsigned int cputype;
+9 -1
include/asm-mips/cpu.h
··· 3 3 * various MIPS cpu types. 4 4 * 5 5 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 6 + * Copyright (C) 2004 Maciej W. Rozycki 6 7 */ 7 8 #ifndef _ASM_CPU_H 8 9 #define _ASM_CPU_H ··· 214 213 #define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ 215 214 #define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ 216 215 #define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ 217 - #define MIPS_CPU_MIPS16 0x00000100 /* code compression */ 218 216 #define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ 219 217 #define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ 220 218 #define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */ ··· 224 224 #define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */ 225 225 #define MIPS_CPU_SUBSET_CACHES 0x00020000 /* P-cache subset enforced */ 226 226 #define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */ 227 + 228 + /* 229 + * CPU ASE encodings 230 + */ 231 + #define MIPS_ASE_MIPS16 0x00000001 /* code compression */ 232 + #define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */ 233 + #define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */ 234 + #define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */ 227 235 228 236 #endif /* _ASM_CPU_H */
+46 -1
include/asm-mips/mipsregs.h
··· 8 8 * Modified for further R[236]000 support by Paul M. Antoine, 1996. 9 9 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 10 10 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 11 - * Copyright (C) 2003 Maciej W. Rozycki 11 + * Copyright (C) 2003, 2004 Maciej W. Rozycki 12 12 */ 13 13 #ifndef _ASM_MIPSREGS_H 14 14 #define _ASM_MIPSREGS_H ··· 476 476 #define MIPS_CONF_AR (_ULCAST_(7) << 10) 477 477 #define MIPS_CONF_AT (_ULCAST_(3) << 13) 478 478 #define MIPS_CONF_M (_ULCAST_(1) << 31) 479 + 480 + /* 481 + * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above. 482 + */ 483 + #define MIPS_CONF1_FP (_ULCAST_(1) << 0) 484 + #define MIPS_CONF1_EP (_ULCAST_(1) << 1) 485 + #define MIPS_CONF1_CA (_ULCAST_(1) << 2) 486 + #define MIPS_CONF1_WR (_ULCAST_(1) << 3) 487 + #define MIPS_CONF1_PC (_ULCAST_(1) << 4) 488 + #define MIPS_CONF1_MD (_ULCAST_(1) << 5) 489 + #define MIPS_CONF1_C2 (_ULCAST_(1) << 6) 490 + #define MIPS_CONF1_DA (_ULCAST_(7) << 7) 491 + #define MIPS_CONF1_DL (_ULCAST_(7) << 10) 492 + #define MIPS_CONF1_DS (_ULCAST_(7) << 13) 493 + #define MIPS_CONF1_IA (_ULCAST_(7) << 16) 494 + #define MIPS_CONF1_IL (_ULCAST_(7) << 19) 495 + #define MIPS_CONF1_IS (_ULCAST_(7) << 22) 496 + #define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25) 497 + 498 + #define MIPS_CONF2_SA (_ULCAST_(15)<< 0) 499 + #define MIPS_CONF2_SL (_ULCAST_(15)<< 4) 500 + #define MIPS_CONF2_SS (_ULCAST_(15)<< 8) 501 + #define MIPS_CONF2_SU (_ULCAST_(15)<< 12) 502 + #define MIPS_CONF2_TA (_ULCAST_(15)<< 16) 503 + #define MIPS_CONF2_TL (_ULCAST_(15)<< 20) 504 + #define MIPS_CONF2_TS (_ULCAST_(15)<< 24) 505 + #define MIPS_CONF2_TU (_ULCAST_(7) << 28) 506 + 507 + #define MIPS_CONF3_TL (_ULCAST_(1) << 0) 508 + #define MIPS_CONF3_SM (_ULCAST_(1) << 1) 509 + #define MIPS_CONF3_SP (_ULCAST_(1) << 4) 510 + #define MIPS_CONF3_VINT (_ULCAST_(1) << 5) 511 + #define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) 512 + #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) 513 + 514 + /* 515 + * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. 516 + */ 517 + #define MIPS_FPIR_S (_ULCAST_(1) << 16) 518 + #define MIPS_FPIR_D (_ULCAST_(1) << 17) 519 + #define MIPS_FPIR_PS (_ULCAST_(1) << 18) 520 + #define MIPS_FPIR_3D (_ULCAST_(1) << 19) 521 + #define MIPS_FPIR_W (_ULCAST_(1) << 20) 522 + #define MIPS_FPIR_L (_ULCAST_(1) << 21) 523 + #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) 479 524 480 525 /* 481 526 * R10000 performance counter definitions.