diff options
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
| -rw-r--r-- | arch/mips/kernel/cpu-probe.c | 256 |
1 files changed, 186 insertions, 70 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 7685f8baf3f0..a263fb7a3971 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 |
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
| 18 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
| 19 | 19 | ||
| 20 | #include <asm/bugs.h> | ||
| 21 | #include <asm/cpu.h> | 20 | #include <asm/cpu.h> |
| 22 | #include <asm/fpu.h> | 21 | #include <asm/fpu.h> |
| 23 | #include <asm/mipsregs.h> | 22 | #include <asm/mipsregs.h> |
| @@ -51,36 +50,48 @@ static void r4k_wait(void) | |||
| 51 | ".set\tmips0"); | 50 | ".set\tmips0"); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | /* | 53 | /* The Au1xxx wait is available only if using 32khz counter or |
| 55 | * The Au1xxx wait is available only if we run CONFIG_PM and | 54 | * external timer source, but specifically not CP0 Counter. */ |
| 56 | * the timer setup found we had a 32KHz counter available. | 55 | int allow_au1k_wait; |
| 57 | * There are still problems with functions that may call au1k_wait | ||
| 58 | * directly, but that will be discovered pretty quickly. | ||
| 59 | */ | ||
| 60 | extern void (*au1k_wait_ptr)(void); | ||
| 61 | 56 | ||
| 62 | void au1k_wait(void) | 57 | static void au1k_wait(void) |
| 63 | { | 58 | { |
| 64 | #ifdef CONFIG_PM | ||
| 65 | /* using the wait instruction makes CP0 counter unusable */ | 59 | /* using the wait instruction makes CP0 counter unusable */ |
| 66 | __asm__(".set\tmips3\n\t" | 60 | __asm__(".set mips3\n\t" |
| 61 | "cache 0x14, 0(%0)\n\t" | ||
| 62 | "cache 0x14, 32(%0)\n\t" | ||
| 63 | "sync\n\t" | ||
| 64 | "nop\n\t" | ||
| 67 | "wait\n\t" | 65 | "wait\n\t" |
| 68 | "nop\n\t" | 66 | "nop\n\t" |
| 69 | "nop\n\t" | 67 | "nop\n\t" |
| 70 | "nop\n\t" | 68 | "nop\n\t" |
| 71 | "nop\n\t" | 69 | "nop\n\t" |
| 72 | ".set\tmips0"); | 70 | ".set mips0\n\t" |
| 73 | #else | 71 | : : "r" (au1k_wait)); |
| 74 | __asm__("nop\n\t" | ||
| 75 | "nop"); | ||
| 76 | #endif | ||
| 77 | } | 72 | } |
| 78 | 73 | ||
| 74 | static int __initdata nowait = 0; | ||
| 75 | |||
| 76 | int __init wait_disable(char *s) | ||
| 77 | { | ||
| 78 | nowait = 1; | ||
| 79 | |||
| 80 | return 1; | ||
| 81 | } | ||
| 82 | |||
| 83 | __setup("nowait", wait_disable); | ||
| 84 | |||
| 79 | static inline void check_wait(void) | 85 | static inline void check_wait(void) |
| 80 | { | 86 | { |
| 81 | struct cpuinfo_mips *c = ¤t_cpu_data; | 87 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| 82 | 88 | ||
| 83 | printk("Checking for 'wait' instruction... "); | 89 | printk("Checking for 'wait' instruction... "); |
| 90 | if (nowait) { | ||
| 91 | printk (" disabled.\n"); | ||
| 92 | return; | ||
| 93 | } | ||
| 94 | |||
| 84 | switch (c->cputype) { | 95 | switch (c->cputype) { |
| 85 | case CPU_R3081: | 96 | case CPU_R3081: |
| 86 | case CPU_R3081E: | 97 | case CPU_R3081E: |
| @@ -109,22 +120,22 @@ static inline void check_wait(void) | |||
| 109 | /* case CPU_20KC:*/ | 120 | /* case CPU_20KC:*/ |
| 110 | case CPU_24K: | 121 | case CPU_24K: |
| 111 | case CPU_25KF: | 122 | case CPU_25KF: |
| 123 | case CPU_34K: | ||
| 124 | case CPU_PR4450: | ||
| 112 | cpu_wait = r4k_wait; | 125 | cpu_wait = r4k_wait; |
| 113 | printk(" available.\n"); | 126 | printk(" available.\n"); |
| 114 | break; | 127 | break; |
| 115 | #ifdef CONFIG_PM | ||
| 116 | case CPU_AU1000: | 128 | case CPU_AU1000: |
| 117 | case CPU_AU1100: | 129 | case CPU_AU1100: |
| 118 | case CPU_AU1500: | 130 | case CPU_AU1500: |
| 119 | if (au1k_wait_ptr != NULL) { | 131 | case CPU_AU1550: |
| 120 | cpu_wait = au1k_wait_ptr; | 132 | case CPU_AU1200: |
| 133 | if (allow_au1k_wait) { | ||
| 134 | cpu_wait = au1k_wait; | ||
| 121 | printk(" available.\n"); | 135 | printk(" available.\n"); |
| 122 | } | 136 | } else |
| 123 | else { | ||
| 124 | printk(" unavailable.\n"); | 137 | printk(" unavailable.\n"); |
| 125 | } | ||
| 126 | break; | 138 | break; |
| 127 | #endif | ||
| 128 | default: | 139 | default: |
| 129 | printk(" unavailable.\n"); | 140 | printk(" unavailable.\n"); |
| 130 | break; | 141 | break; |
| @@ -180,7 +191,7 @@ static inline int __cpu_has_fpu(void) | |||
| 180 | return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); | 191 | return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); |
| 181 | } | 192 | } |
| 182 | 193 | ||
| 183 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ | 194 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
| 184 | | MIPS_CPU_COUNTER) | 195 | | MIPS_CPU_COUNTER) |
| 185 | 196 | ||
| 186 | static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | 197 | static inline void cpu_probe_legacy(struct cpuinfo_mips *c) |
| @@ -189,7 +200,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | |||
| 189 | case PRID_IMP_R2000: | 200 | case PRID_IMP_R2000: |
| 190 | c->cputype = CPU_R2000; | 201 | c->cputype = CPU_R2000; |
| 191 | c->isa_level = MIPS_CPU_ISA_I; | 202 | c->isa_level = MIPS_CPU_ISA_I; |
| 192 | c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; | 203 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | |
| 204 | MIPS_CPU_NOFPUEX; | ||
| 193 | if (__cpu_has_fpu()) | 205 | if (__cpu_has_fpu()) |
| 194 | c->options |= MIPS_CPU_FPU; | 206 | c->options |= MIPS_CPU_FPU; |
| 195 | c->tlbsize = 64; | 207 | c->tlbsize = 64; |
| @@ -203,7 +215,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | |||
| 203 | else | 215 | else |
| 204 | c->cputype = CPU_R3000; | 216 | c->cputype = CPU_R3000; |
| 205 | c->isa_level = MIPS_CPU_ISA_I; | 217 | c->isa_level = MIPS_CPU_ISA_I; |
| 206 | c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; | 218 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | |
| 219 | MIPS_CPU_NOFPUEX; | ||
| 207 | if (__cpu_has_fpu()) | 220 | if (__cpu_has_fpu()) |
| 208 | c->options |= MIPS_CPU_FPU; | 221 | c->options |= MIPS_CPU_FPU; |
| 209 | c->tlbsize = 64; | 222 | c->tlbsize = 64; |
| @@ -266,7 +279,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | |||
| 266 | case PRID_IMP_R4600: | 279 | case PRID_IMP_R4600: |
| 267 | c->cputype = CPU_R4600; | 280 | c->cputype = CPU_R4600; |
| 268 | c->isa_level = MIPS_CPU_ISA_III; | 281 | c->isa_level = MIPS_CPU_ISA_III; |
| 269 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; | 282 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
| 283 | MIPS_CPU_LLSC; | ||
| 270 | c->tlbsize = 48; | 284 | c->tlbsize = 48; |
| 271 | break; | 285 | break; |
| 272 | #if 0 | 286 | #if 0 |
| @@ -285,7 +299,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | |||
| 285 | #endif | 299 | #endif |
| 286 | case PRID_IMP_TX39: | 300 | case PRID_IMP_TX39: |
| 287 | c->isa_level = MIPS_CPU_ISA_I; | 301 | c->isa_level = MIPS_CPU_ISA_I; |
| 288 | c->options = MIPS_CPU_TLB; | 302 | c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE; |
| 289 | 303 | ||
| 290 | if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { | 304 | if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { |
| 291 | c->cputype = CPU_TX3927; | 305 | c->cputype = CPU_TX3927; |
| @@ -421,74 +435,147 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) | |||
| 421 | } | 435 | } |
| 422 | } | 436 | } |
| 423 | 437 | ||
| 424 | static inline void decode_config1(struct cpuinfo_mips *c) | 438 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) |
| 425 | { | 439 | { |
| 426 | unsigned long config0 = read_c0_config(); | 440 | unsigned int config0; |
| 427 | unsigned long config1; | 441 | int isa; |
| 442 | |||
| 443 | config0 = read_c0_config(); | ||
| 428 | 444 | ||
| 429 | if ((config0 & (1 << 31)) == 0) | 445 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) |
| 430 | return; /* actually wort a panic() */ | 446 | c->options |= MIPS_CPU_TLB; |
| 447 | isa = (config0 & MIPS_CONF_AT) >> 13; | ||
| 448 | switch (isa) { | ||
| 449 | case 0: | ||
| 450 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 451 | break; | ||
| 452 | case 2: | ||
| 453 | c->isa_level = MIPS_CPU_ISA_M64; | ||
| 454 | break; | ||
| 455 | default: | ||
| 456 | panic("Unsupported ISA type, cp0.config0.at: %d.", isa); | ||
| 457 | } | ||
| 458 | |||
| 459 | return config0 & MIPS_CONF_M; | ||
| 460 | } | ||
| 461 | |||
| 462 | static inline unsigned int decode_config1(struct cpuinfo_mips *c) | ||
| 463 | { | ||
| 464 | unsigned int config1; | ||
| 431 | 465 | ||
| 432 | /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ | ||
| 433 | c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | | ||
| 434 | MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | | ||
| 435 | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
| 436 | config1 = read_c0_config1(); | 466 | config1 = read_c0_config1(); |
| 437 | if (config1 & (1 << 3)) | 467 | |
| 468 | if (config1 & MIPS_CONF1_MD) | ||
| 469 | c->ases |= MIPS_ASE_MDMX; | ||
| 470 | if (config1 & MIPS_CONF1_WR) | ||
| 438 | c->options |= MIPS_CPU_WATCH; | 471 | c->options |= MIPS_CPU_WATCH; |
| 439 | if (config1 & (1 << 2)) | 472 | if (config1 & MIPS_CONF1_CA) |
| 440 | c->options |= MIPS_CPU_MIPS16; | 473 | c->ases |= MIPS_ASE_MIPS16; |
| 441 | if (config1 & (1 << 1)) | 474 | if (config1 & MIPS_CONF1_EP) |
| 442 | c->options |= MIPS_CPU_EJTAG; | 475 | c->options |= MIPS_CPU_EJTAG; |
| 443 | if (config1 & 1) { | 476 | if (config1 & MIPS_CONF1_FP) { |
| 444 | c->options |= MIPS_CPU_FPU; | 477 | c->options |= MIPS_CPU_FPU; |
| 445 | c->options |= MIPS_CPU_32FPR; | 478 | c->options |= MIPS_CPU_32FPR; |
| 446 | } | 479 | } |
| 480 | if (cpu_has_tlb) | ||
| 481 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | ||
| 482 | |||
| 483 | return config1 & MIPS_CONF_M; | ||
| 484 | } | ||
| 485 | |||
| 486 | static inline unsigned int decode_config2(struct cpuinfo_mips *c) | ||
| 487 | { | ||
| 488 | unsigned int config2; | ||
| 489 | |||
| 490 | config2 = read_c0_config2(); | ||
| 491 | |||
| 492 | if (config2 & MIPS_CONF2_SL) | ||
| 493 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | ||
| 494 | |||
| 495 | return config2 & MIPS_CONF_M; | ||
| 496 | } | ||
| 497 | |||
| 498 | static inline unsigned int decode_config3(struct cpuinfo_mips *c) | ||
| 499 | { | ||
| 500 | unsigned int config3; | ||
| 501 | |||
| 502 | config3 = read_c0_config3(); | ||
| 503 | |||
| 504 | if (config3 & MIPS_CONF3_SM) | ||
| 505 | c->ases |= MIPS_ASE_SMARTMIPS; | ||
| 506 | if (config3 & MIPS_CONF3_DSP) | ||
| 507 | c->ases |= MIPS_ASE_DSP; | ||
| 508 | if (config3 & MIPS_CONF3_VINT) | ||
| 509 | c->options |= MIPS_CPU_VINT; | ||
| 510 | if (config3 & MIPS_CONF3_VEIC) | ||
| 511 | c->options |= MIPS_CPU_VEIC; | ||
| 512 | if (config3 & MIPS_CONF3_MT) | ||
| 513 | c->ases |= MIPS_ASE_MIPSMT; | ||
| 514 | |||
| 515 | return config3 & MIPS_CONF_M; | ||
| 516 | } | ||
| 517 | |||
| 518 | static inline void decode_configs(struct cpuinfo_mips *c) | ||
| 519 | { | ||
| 520 | /* MIPS32 or MIPS64 compliant CPU. */ | ||
| 521 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | ||
| 522 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
| 523 | |||
| 447 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 524 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
| 448 | 525 | ||
| 449 | c->tlbsize = ((config1 >> 25) & 0x3f) + 1; | 526 | /* Read Config registers. */ |
| 527 | if (!decode_config0(c)) | ||
| 528 | return; /* actually worth a panic() */ | ||
| 529 | if (!decode_config1(c)) | ||
| 530 | return; | ||
| 531 | if (!decode_config2(c)) | ||
| 532 | return; | ||
| 533 | if (!decode_config3(c)) | ||
| 534 | return; | ||
| 450 | } | 535 | } |
| 451 | 536 | ||
| 452 | static inline void cpu_probe_mips(struct cpuinfo_mips *c) | 537 | static inline void cpu_probe_mips(struct cpuinfo_mips *c) |
| 453 | { | 538 | { |
| 454 | decode_config1(c); | 539 | decode_configs(c); |
| 455 | switch (c->processor_id & 0xff00) { | 540 | switch (c->processor_id & 0xff00) { |
| 456 | case PRID_IMP_4KC: | 541 | case PRID_IMP_4KC: |
| 457 | c->cputype = CPU_4KC; | 542 | c->cputype = CPU_4KC; |
| 458 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 459 | break; | 543 | break; |
| 460 | case PRID_IMP_4KEC: | 544 | case PRID_IMP_4KEC: |
| 461 | c->cputype = CPU_4KEC; | 545 | c->cputype = CPU_4KEC; |
| 462 | c->isa_level = MIPS_CPU_ISA_M32; | 546 | break; |
| 547 | case PRID_IMP_4KECR2: | ||
| 548 | c->cputype = CPU_4KEC; | ||
| 463 | break; | 549 | break; |
| 464 | case PRID_IMP_4KSC: | 550 | case PRID_IMP_4KSC: |
| 551 | case PRID_IMP_4KSD: | ||
| 465 | c->cputype = CPU_4KSC; | 552 | c->cputype = CPU_4KSC; |
| 466 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 467 | break; | 553 | break; |
| 468 | case PRID_IMP_5KC: | 554 | case PRID_IMP_5KC: |
| 469 | c->cputype = CPU_5KC; | 555 | c->cputype = CPU_5KC; |
| 470 | c->isa_level = MIPS_CPU_ISA_M64; | ||
| 471 | break; | 556 | break; |
| 472 | case PRID_IMP_20KC: | 557 | case PRID_IMP_20KC: |
| 473 | c->cputype = CPU_20KC; | 558 | c->cputype = CPU_20KC; |
| 474 | c->isa_level = MIPS_CPU_ISA_M64; | ||
| 475 | break; | 559 | break; |
| 476 | case PRID_IMP_24K: | 560 | case PRID_IMP_24K: |
| 561 | case PRID_IMP_24KE: | ||
| 477 | c->cputype = CPU_24K; | 562 | c->cputype = CPU_24K; |
| 478 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 479 | break; | 563 | break; |
| 480 | case PRID_IMP_25KF: | 564 | case PRID_IMP_25KF: |
| 481 | c->cputype = CPU_25KF; | 565 | c->cputype = CPU_25KF; |
| 482 | c->isa_level = MIPS_CPU_ISA_M64; | ||
| 483 | /* Probe for L2 cache */ | 566 | /* Probe for L2 cache */ |
| 484 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | 567 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; |
| 485 | break; | 568 | break; |
| 569 | case PRID_IMP_34K: | ||
| 570 | c->cputype = CPU_34K; | ||
| 571 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 572 | break; | ||
| 486 | } | 573 | } |
| 487 | } | 574 | } |
| 488 | 575 | ||
| 489 | static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) | 576 | static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) |
| 490 | { | 577 | { |
| 491 | decode_config1(c); | 578 | decode_configs(c); |
| 492 | switch (c->processor_id & 0xff00) { | 579 | switch (c->processor_id & 0xff00) { |
| 493 | case PRID_IMP_AU1_REV1: | 580 | case PRID_IMP_AU1_REV1: |
| 494 | case PRID_IMP_AU1_REV2: | 581 | case PRID_IMP_AU1_REV2: |
| @@ -505,50 +592,70 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c) | |||
| 505 | case 3: | 592 | case 3: |
| 506 | c->cputype = CPU_AU1550; | 593 | c->cputype = CPU_AU1550; |
| 507 | break; | 594 | break; |
| 595 | case 4: | ||
| 596 | c->cputype = CPU_AU1200; | ||
| 597 | break; | ||
| 508 | default: | 598 | default: |
| 509 | panic("Unknown Au Core!"); | 599 | panic("Unknown Au Core!"); |
| 510 | break; | 600 | break; |
| 511 | } | 601 | } |
| 512 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 513 | break; | 602 | break; |
| 514 | } | 603 | } |
| 515 | } | 604 | } |
| 516 | 605 | ||
| 517 | static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) | 606 | static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) |
| 518 | { | 607 | { |
| 519 | decode_config1(c); | 608 | decode_configs(c); |
| 609 | |||
| 610 | /* | ||
| 611 | * For historical reasons the SB1 comes with it's own variant of | ||
| 612 | * cache code which eventually will be folded into c-r4k.c. Until | ||
| 613 | * then we pretend it's got it's own cache architecture. | ||
| 614 | */ | ||
| 615 | c->options &= ~MIPS_CPU_4K_CACHE; | ||
| 616 | c->options |= MIPS_CPU_SB1_CACHE; | ||
| 617 | |||
| 520 | switch (c->processor_id & 0xff00) { | 618 | switch (c->processor_id & 0xff00) { |
| 521 | case PRID_IMP_SB1: | 619 | case PRID_IMP_SB1: |
| 522 | c->cputype = CPU_SB1; | 620 | c->cputype = CPU_SB1; |
| 523 | c->isa_level = MIPS_CPU_ISA_M64; | 621 | #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS |
| 524 | c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | | ||
| 525 | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | | ||
| 526 | MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | | ||
| 527 | MIPS_CPU_WATCH | MIPS_CPU_LLSC; | ||
| 528 | #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS | ||
| 529 | /* FPU in pass1 is known to have issues. */ | 622 | /* FPU in pass1 is known to have issues. */ |
| 530 | c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; | 623 | c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); |
| 531 | #endif | 624 | #endif |
| 532 | break; | 625 | break; |
| 626 | case PRID_IMP_SB1A: | ||
| 627 | c->cputype = CPU_SB1A; | ||
| 628 | break; | ||
| 533 | } | 629 | } |
| 534 | } | 630 | } |
| 535 | 631 | ||
| 536 | static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) | 632 | static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) |
| 537 | { | 633 | { |
| 538 | decode_config1(c); | 634 | decode_configs(c); |
| 539 | switch (c->processor_id & 0xff00) { | 635 | switch (c->processor_id & 0xff00) { |
| 540 | case PRID_IMP_SR71000: | 636 | case PRID_IMP_SR71000: |
| 541 | c->cputype = CPU_SR71000; | 637 | c->cputype = CPU_SR71000; |
| 542 | c->isa_level = MIPS_CPU_ISA_M64; | ||
| 543 | c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | | ||
| 544 | MIPS_CPU_4KTLB | MIPS_CPU_FPU | | ||
| 545 | MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; | ||
| 546 | c->scache.ways = 8; | 638 | c->scache.ways = 8; |
| 547 | c->tlbsize = 64; | 639 | c->tlbsize = 64; |
| 548 | break; | 640 | break; |
| 549 | } | 641 | } |
| 550 | } | 642 | } |
| 551 | 643 | ||
| 644 | static inline void cpu_probe_philips(struct cpuinfo_mips *c) | ||
| 645 | { | ||
| 646 | decode_configs(c); | ||
| 647 | switch (c->processor_id & 0xff00) { | ||
| 648 | case PRID_IMP_PR4450: | ||
| 649 | c->cputype = CPU_PR4450; | ||
| 650 | c->isa_level = MIPS_CPU_ISA_M32; | ||
| 651 | break; | ||
| 652 | default: | ||
| 653 | panic("Unknown Philips Core!"); /* REVISIT: die? */ | ||
| 654 | break; | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | |||
| 552 | __init void cpu_probe(void) | 659 | __init void cpu_probe(void) |
| 553 | { | 660 | { |
| 554 | struct cpuinfo_mips *c = ¤t_cpu_data; | 661 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -571,15 +678,24 @@ __init void cpu_probe(void) | |||
| 571 | case PRID_COMP_SIBYTE: | 678 | case PRID_COMP_SIBYTE: |
| 572 | cpu_probe_sibyte(c); | 679 | cpu_probe_sibyte(c); |
| 573 | break; | 680 | break; |
| 574 | |||
| 575 | case PRID_COMP_SANDCRAFT: | 681 | case PRID_COMP_SANDCRAFT: |
| 576 | cpu_probe_sandcraft(c); | 682 | cpu_probe_sandcraft(c); |
| 577 | break; | 683 | break; |
| 684 | case PRID_COMP_PHILIPS: | ||
| 685 | cpu_probe_philips(c); | ||
| 686 | break; | ||
| 578 | default: | 687 | default: |
| 579 | c->cputype = CPU_UNKNOWN; | 688 | c->cputype = CPU_UNKNOWN; |
| 580 | } | 689 | } |
| 581 | if (c->options & MIPS_CPU_FPU) | 690 | if (c->options & MIPS_CPU_FPU) { |
| 582 | c->fpu_id = cpu_get_fpu_id(); | 691 | c->fpu_id = cpu_get_fpu_id(); |
| 692 | |||
| 693 | if (c->isa_level == MIPS_CPU_ISA_M32 || | ||
| 694 | c->isa_level == MIPS_CPU_ISA_M64) { | ||
| 695 | if (c->fpu_id & MIPS_FPIR_3D) | ||
| 696 | c->ases |= MIPS_ASE_MIPS3D; | ||
| 697 | } | ||
| 698 | } | ||
| 583 | } | 699 | } |
| 584 | 700 | ||
| 585 | __init void cpu_report(void) | 701 | __init void cpu_report(void) |
