linux-old/arch/mips/kernel/cpu-probe.c
<<
>>
Prefs
   1#include <linux/init.h>
   2#include <linux/kernel.h>
   3#include <linux/stddef.h>
   4#include <asm/bugs.h>
   5#include <asm/cpu.h>
   6#include <asm/fpu.h>
   7#include <asm/mipsregs.h>
   8
   9/*
  10 * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
  11 * the implementation of the "wait" feature differs between CPU families. This
  12 * points to the function that implements CPU specific wait.
  13 * The wait instruction stops the pipeline and reduces the power consumption of
  14 * the CPU very much.
  15 */
  16void (*cpu_wait)(void) = NULL;
  17
  18static void r3081_wait(void)
  19{
  20        unsigned long cfg = read_c0_conf();
  21        write_c0_conf(cfg | R30XX_CONF_HALT);
  22}
  23
  24static void r39xx_wait(void)
  25{
  26        unsigned long cfg = read_c0_conf();
  27        write_c0_conf(cfg | TX39_CONF_HALT);
  28}
  29
  30static void r4k_wait(void)
  31{
  32        __asm__(".set\tmips3\n\t"
  33                "wait\n\t"
  34                ".set\tmips0");
  35}
  36
  37/* The Au1xxx wait is available only if we run CONFIG_PM and
  38 * the timer setup found we had a 32KHz counter available.
  39 * There are still problems with functions that may call au1k_wait
  40 * directly, but that will be discovered pretty quickly.
  41 */
  42extern void (*au1k_wait_ptr)(void);
  43void au1k_wait(void)
  44{
  45#ifdef CONFIG_PM
  46        /* using the wait instruction makes CP0 counter unusable */
  47        __asm__(".set\tmips3\n\t"
  48                "wait\n\t"
  49                "nop\n\t"
  50                "nop\n\t"
  51                "nop\n\t"
  52                "nop\n\t"
  53                ".set\tmips0");
  54#else
  55        __asm__("nop\n\t"
  56                "nop");
  57#endif
  58}
  59
  60static inline void check_wait(void)
  61{
  62        struct cpuinfo_mips *c = &current_cpu_data;
  63
  64        printk("Checking for 'wait' instruction... ");
  65        switch (c->cputype) {
  66        case CPU_R3081:
  67        case CPU_R3081E:
  68                cpu_wait = r3081_wait;
  69                printk(" available.\n");
  70                break;
  71        case CPU_TX3927:
  72                cpu_wait = r39xx_wait;
  73                printk(" available.\n");
  74                break;
  75        case CPU_R4200:
  76/*      case CPU_R4300: */
  77        case CPU_R4600:
  78        case CPU_R4640:
  79        case CPU_R4650:
  80        case CPU_R4700:
  81        case CPU_R5000:
  82        case CPU_NEVADA:
  83        case CPU_RM7000:
  84/*      case CPU_RM9000: */
  85        case CPU_TX49XX:
  86        case CPU_4KC:
  87        case CPU_4KEC:
  88        case CPU_4KSC:
  89        case CPU_5KC:
  90/*      case CPU_20KC:*/
  91        case CPU_24K:
  92        case CPU_25KF:
  93                cpu_wait = r4k_wait;
  94                printk(" available.\n");
  95                break;
  96#ifdef CONFIG_PM
  97        case CPU_AU1000:
  98        case CPU_AU1100:
  99        case CPU_AU1500:
 100                if (au1k_wait_ptr != NULL) {
 101                        cpu_wait = au1k_wait_ptr;
 102                        printk(" available.\n");
 103                }
 104                else {
 105                        printk(" unavailable.\n");
 106                }
 107                break;
 108#endif
 109        default:
 110                printk(" unavailable.\n");
 111                break;
 112        }
 113}
 114
 115void __init check_bugs(void)
 116{
 117        check_wait();
 118}
 119
 120/*
 121 * Probe whether cpu has config register by trying to play with
 122 * alternate cache bit and see whether it matters.
 123 * It's used by cpu_probe to distinguish between R3000A and R3081.
 124 */
 125static inline int cpu_has_confreg(void)
 126{
 127#ifdef CONFIG_CPU_R3000
 128        extern unsigned long r3k_cache_size(unsigned long);
 129        unsigned long size1, size2;
 130        unsigned long cfg = read_c0_conf();
 131
 132        size1 = r3k_cache_size(ST0_ISC);
 133        write_c0_conf(cfg ^ R30XX_CONF_AC);
 134        size2 = r3k_cache_size(ST0_ISC);
 135        write_c0_conf(cfg);
 136        return size1 != size2;
 137#else
 138        return 0;
 139#endif
 140}
 141
 142/*
 143 * Get the FPU Implementation/Revision.
 144 */
 145static inline unsigned long cpu_get_fpu_id(void)
 146{
 147        unsigned long tmp, fpu_id;
 148
 149        tmp = read_c0_status();
 150        __enable_fpu();
 151        fpu_id = read_32bit_cp1_register(CP1_REVISION);
 152        write_c0_status(tmp);
 153        return fpu_id;
 154}
 155
 156/*
 157 * Check the CPU has an FPU the official way.
 158 */
 159static inline int __cpu_has_fpu(void)
 160{
 161        return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
 162}
 163
 164#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
 165                | MIPS_CPU_COUNTER)
 166
 167static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
 168{
 169        switch (c->processor_id & 0xff00) {
 170        case PRID_IMP_R2000:
 171                c->cputype = CPU_R2000;
 172                c->isa_level = MIPS_CPU_ISA_I;
 173                c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
 174                             MIPS_CPU_LLSC;
 175                if (__cpu_has_fpu())
 176                        c->options |= MIPS_CPU_FPU;
 177                c->tlbsize = 64;
 178                break;
 179        case PRID_IMP_R3000:
 180                if ((c->processor_id & 0xff) == PRID_REV_R3000A)
 181                        if (cpu_has_confreg())
 182                                c->cputype = CPU_R3081E;
 183                        else
 184                                c->cputype = CPU_R3000A;
 185                else
 186                        c->cputype = CPU_R3000;
 187                c->isa_level = MIPS_CPU_ISA_I;
 188                c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
 189                             MIPS_CPU_LLSC;
 190                if (__cpu_has_fpu())
 191                        c->options |= MIPS_CPU_FPU;
 192                c->tlbsize = 64;
 193                break;
 194        case PRID_IMP_R4000:
 195                if ((c->processor_id & 0xff) >= PRID_REV_R4400)
 196                        c->cputype = CPU_R4400SC;
 197                else
 198                        c->cputype = CPU_R4000SC;
 199                c->isa_level = MIPS_CPU_ISA_III;
 200                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 201                             MIPS_CPU_WATCH | MIPS_CPU_VCE |
 202                             MIPS_CPU_LLSC;
 203                c->tlbsize = 48;
 204                break;
 205        case PRID_IMP_VR41XX:
 206                switch (c->processor_id & 0xf0) {
 207#ifndef CONFIG_VR4181
 208                case PRID_REV_VR4111:
 209                        c->cputype = CPU_VR4111;
 210                        break;
 211#else
 212                case PRID_REV_VR4181:
 213                        c->cputype = CPU_VR4181;
 214                        break;
 215#endif
 216                case PRID_REV_VR4121:
 217                        c->cputype = CPU_VR4121;
 218                        break;
 219                case PRID_REV_VR4122:
 220                        if ((c->processor_id & 0xf) < 0x3)
 221                                c->cputype = CPU_VR4122;
 222                        else
 223                                c->cputype = CPU_VR4181A;
 224                        break;
 225                case PRID_REV_VR4130:
 226                        if ((c->processor_id & 0xf) < 0x4)
 227                                c->cputype = CPU_VR4131;
 228                        else
 229                                c->cputype = CPU_VR4133;
 230                        break;
 231                default:
 232                        printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
 233                                c->cputype = CPU_VR41XX;
 234                                break;
 235                }
 236                c->isa_level = MIPS_CPU_ISA_III;
 237                c->options = R4K_OPTS;
 238                c->tlbsize = 32;
 239                break;
 240        case PRID_IMP_R4300:
 241                c->cputype = CPU_R4300;
 242                c->isa_level = MIPS_CPU_ISA_III;
 243                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 244                             MIPS_CPU_LLSC;
 245                c->tlbsize = 32;
 246                break;
 247        case PRID_IMP_R4600:
 248                c->cputype = CPU_R4600;
 249                c->isa_level = MIPS_CPU_ISA_III;
 250                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
 251                c->tlbsize = 48;
 252                break;
 253        #if 0
 254        case PRID_IMP_R4650:
 255                /*
 256                 * This processor doesn't have an MMU, so it's not
 257                 * "real easy" to run Linux on it. It is left purely
 258                 * for documentation.  Commented out because it shares
 259                 * it's c0_prid id number with the TX3900.
 260                 */
 261                c->cputype = CPU_R4650;
 262                c->isa_level = MIPS_CPU_ISA_III;
 263                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
 264                c->tlbsize = 48;
 265                break;
 266        #endif
 267        case PRID_IMP_TX39:
 268                c->isa_level = MIPS_CPU_ISA_I;
 269                c->options = MIPS_CPU_TLB;
 270
 271                if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
 272                        c->cputype = CPU_TX3927;
 273                        c->tlbsize = 64;
 274                } else {
 275                        switch (c->processor_id & 0xff) {
 276                        case PRID_REV_TX3912:
 277                                c->cputype = CPU_TX3912;
 278                                c->tlbsize = 32;
 279                                break;
 280                        case PRID_REV_TX3922:
 281                                c->cputype = CPU_TX3922;
 282                                c->tlbsize = 64;
 283                                break;
 284                        default:
 285                                c->cputype = CPU_UNKNOWN;
 286                                break;
 287                        }
 288                }
 289                break;
 290        case PRID_IMP_R4700:
 291                c->cputype = CPU_R4700;
 292                c->isa_level = MIPS_CPU_ISA_III;
 293                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 294                             MIPS_CPU_LLSC;
 295                c->tlbsize = 48;
 296                break;
 297        case PRID_IMP_TX49:
 298                c->cputype = CPU_TX49XX;
 299                c->isa_level = MIPS_CPU_ISA_III;
 300                c->options = R4K_OPTS | MIPS_CPU_LLSC;
 301                if (!(c->processor_id & 0x08))
 302                        c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
 303                c->tlbsize = 48;
 304                break;
 305        case PRID_IMP_R5000:
 306                c->cputype = CPU_R5000;
 307                c->isa_level = MIPS_CPU_ISA_IV;
 308                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 309                             MIPS_CPU_LLSC;
 310                c->tlbsize = 48;
 311                break;
 312        case PRID_IMP_R5432:
 313                c->cputype = CPU_R5432;
 314                c->isa_level = MIPS_CPU_ISA_IV;
 315                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 316                             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
 317                c->tlbsize = 48;
 318                break;
 319        case PRID_IMP_R5500:
 320                c->cputype = CPU_R5500;
 321                c->isa_level = MIPS_CPU_ISA_IV;
 322                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 323                             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
 324                c->tlbsize = 48;
 325                break;
 326        case PRID_IMP_NEVADA:
 327                c->cputype = CPU_NEVADA;
 328                c->isa_level = MIPS_CPU_ISA_IV;
 329                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 330                             MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
 331                c->tlbsize = 48;
 332                break;
 333        case PRID_IMP_R6000:
 334                c->cputype = CPU_R6000;
 335                c->isa_level = MIPS_CPU_ISA_II;
 336                c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
 337                             MIPS_CPU_LLSC;
 338                c->tlbsize = 32;
 339                break;
 340        case PRID_IMP_R6000A:
 341                c->cputype = CPU_R6000A;
 342                c->isa_level = MIPS_CPU_ISA_II;
 343                c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
 344                             MIPS_CPU_LLSC;
 345                c->tlbsize = 32;
 346                break;
 347        case PRID_IMP_RM7000:
 348                c->cputype = CPU_RM7000;
 349                c->isa_level = MIPS_CPU_ISA_IV;
 350                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 351                             MIPS_CPU_LLSC;
 352                /*
 353                 * Undocumented RM7000:  Bit 29 in the info register of
 354                 * the RM7000 v2.0 indicates if the TLB has 48 or 64
 355                 * entries.
 356                 *
 357                 * 29      1 =>    64 entry JTLB
 358                 *         0 =>    48 entry JTLB
 359                 */
 360                c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
 361                break;
 362        case PRID_IMP_RM9000:
 363                c->cputype = CPU_RM9000;
 364                c->isa_level = MIPS_CPU_ISA_IV;
 365                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 366                             MIPS_CPU_LLSC;
 367                /*
 368                 * Bit 29 in the info register of the RM9000
 369                 * indicates if the TLB has 48 or 64 entries.
 370                 *
 371                 * 29      1 =>    64 entry JTLB
 372                 *         0 =>    48 entry JTLB
 373                 */
 374                c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
 375                break;
 376        case PRID_IMP_R8000:
 377                c->cputype = CPU_R8000;
 378                c->isa_level = MIPS_CPU_ISA_IV;
 379                c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 380                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
 381                             MIPS_CPU_LLSC;
 382                c->tlbsize = 384;      /* has weird TLB: 3-way x 128 */
 383                break;
 384        case PRID_IMP_R10000:
 385                c->cputype = CPU_R10000;
 386                c->isa_level = MIPS_CPU_ISA_IV;
 387                c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 388                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
 389                             MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
 390                             MIPS_CPU_LLSC;
 391                c->tlbsize = 64;
 392                break;
 393        case PRID_IMP_R12000:
 394                c->cputype = CPU_R12000;
 395                c->isa_level = MIPS_CPU_ISA_IV;
 396                c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 397                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
 398                             MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
 399                             MIPS_CPU_LLSC;
 400                c->tlbsize = 64;
 401                break;
 402        default:
 403                c->cputype = CPU_UNKNOWN;
 404                break;
 405        }
 406}
 407
 408static inline void decode_config1(struct cpuinfo_mips *c)
 409{
 410        unsigned long config0 = read_c0_config();
 411        unsigned long config1;
 412
 413        if ((config0 & (1 << 31)) == 0)
 414                return;                 /* actually wort a panic() */
 415
 416        /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
 417        c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 418                MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
 419                MIPS_CPU_LLSC;
 420        config1 = read_c0_config1();
 421        if (config1 & (1 << 3))
 422                c->options |= MIPS_CPU_WATCH;
 423        if (config1 & (1 << 2))
 424                c->options |= MIPS_CPU_MIPS16;
 425        if (config1 & (1 << 1))
 426                c->options |= MIPS_CPU_EJTAG;
 427        if (config1 & 1) {
 428                c->options |= MIPS_CPU_FPU;
 429                c->options |= MIPS_CPU_32FPR;
 430        }
 431        c->scache.flags = MIPS_CACHE_NOT_PRESENT;
 432
 433        c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
 434}
 435
 436static inline void cpu_probe_mips(struct cpuinfo_mips *c)
 437{
 438        decode_config1(c);
 439        switch (c->processor_id & 0xff00) {
 440        case PRID_IMP_4KC:
 441                c->cputype = CPU_4KC;
 442                c->isa_level = MIPS_CPU_ISA_M32;
 443                break;
 444        case PRID_IMP_4KEC:
 445                c->cputype = CPU_4KEC;
 446                c->isa_level = MIPS_CPU_ISA_M32;
 447                break;
 448        case PRID_IMP_4KSC:
 449                c->cputype = CPU_4KSC;
 450                c->isa_level = MIPS_CPU_ISA_M32;
 451                break;
 452        case PRID_IMP_5KC:
 453                c->cputype = CPU_5KC;
 454                c->isa_level = MIPS_CPU_ISA_M64;
 455                break;
 456        case PRID_IMP_20KC:
 457                c->cputype = CPU_20KC;
 458                c->isa_level = MIPS_CPU_ISA_M64;
 459                break;
 460        case PRID_IMP_24K:
 461                c->cputype = CPU_24K;
 462                c->isa_level = MIPS_CPU_ISA_M32;
 463                break;
 464        case PRID_IMP_25KF:
 465                c->cputype = CPU_25KF;
 466                c->isa_level = MIPS_CPU_ISA_M64;
 467                /* Probe for L2 cache */
 468                c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
 469                break;
 470        default:
 471                c->cputype = CPU_UNKNOWN;
 472                break;
 473        }
 474}
 475
 476static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
 477{
 478        decode_config1(c);
 479        switch (c->processor_id & 0xff00) {
 480        case PRID_IMP_AU1_REV1:
 481        case PRID_IMP_AU1_REV2:
 482                switch ((c->processor_id >> 24) & 0xff) {
 483                case 0:
 484                        c->cputype = CPU_AU1000;
 485                        break;
 486                case 1:
 487                        c->cputype = CPU_AU1500;
 488                        break;
 489                case 2:
 490                        c->cputype = CPU_AU1100;
 491                        break;
 492                case 3:
 493                        c->cputype = CPU_AU1550;
 494                        break;
 495                default:
 496                        panic("Unknown Au Core!");
 497                        break;
 498                }
 499                c->isa_level = MIPS_CPU_ISA_M32;
 500                break;
 501        default:
 502                c->cputype = CPU_UNKNOWN;
 503                break;
 504        }
 505}
 506
 507static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
 508{
 509        decode_config1(c);
 510        switch (c->processor_id & 0xff00) {
 511        case PRID_IMP_SB1:
 512                c->cputype = CPU_SB1;
 513                c->isa_level = MIPS_CPU_ISA_M64;
 514                c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 515                             MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
 516                             MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
 517                             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
 518#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
 519                /* FPU in pass1 is known to have issues. */
 520                c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
 521#endif
 522                break;
 523        default:
 524                c->cputype = CPU_UNKNOWN;
 525                break;
 526        }
 527}
 528
 529static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
 530{
 531        decode_config1(c);
 532        switch (c->processor_id & 0xff00) {
 533        case PRID_IMP_SR71000:
 534                c->cputype = CPU_SR71000;
 535                c->isa_level = MIPS_CPU_ISA_M64;
 536                c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
 537                                    MIPS_CPU_4KTLB | MIPS_CPU_FPU |
 538                             MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
 539                c->scache.ways = 8;
 540                c->tlbsize = 64;
 541                break;
 542        default:
 543                c->cputype = CPU_UNKNOWN;
 544                break;
 545        }
 546}
 547
 548__init void cpu_probe(void)
 549{
 550        struct cpuinfo_mips *c = &current_cpu_data;
 551
 552        c->processor_id = PRID_IMP_UNKNOWN;
 553        c->fpu_id       = FPIR_IMP_NONE;
 554        c->cputype      = CPU_UNKNOWN;
 555
 556        c->processor_id = read_c0_prid();
 557        switch (c->processor_id & 0xff0000) {
 558
 559        case PRID_COMP_LEGACY:
 560                cpu_probe_legacy(c);
 561                break;
 562        case PRID_COMP_MIPS:
 563                cpu_probe_mips(c);
 564                break;
 565        case PRID_COMP_ALCHEMY:
 566                cpu_probe_alchemy(c);
 567                break;
 568        case PRID_COMP_SIBYTE:
 569                cpu_probe_sibyte(c);
 570                break;
 571
 572        case PRID_COMP_SANDCRAFT:
 573                cpu_probe_sandcraft(c);
 574                break;
 575        default:
 576                c->cputype = CPU_UNKNOWN;
 577        }
 578        if (c->options & MIPS_CPU_FPU)
 579                c->fpu_id = cpu_get_fpu_id();
 580}
 581
 582__init void cpu_report(void)
 583{
 584        struct cpuinfo_mips *c = &current_cpu_data;
 585
 586        printk("CPU revision is: %08x\n", c->processor_id);
 587        if (c->options & MIPS_CPU_FPU)
 588                printk("FPU revision is: %08x\n", c->fpu_id);
 589}
 590
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.