root/arch/sparc/kernel/cpu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_cpu_and_fpu
  2. show_cpuinfo
  3. show_cpuinfo
  4. c_start
  5. c_next
  6. c_stop
  7. cpu_type_probe
  8. sun4v_cpu_probe
  9. cpu_type_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* cpu.c: Dinky routines to look for the kind of Sparc cpu
   3  *        we are on.
   4  *
   5  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
   6  */
   7 
   8 #include <linux/seq_file.h>
   9 #include <linux/kernel.h>
  10 #include <linux/export.h>
  11 #include <linux/init.h>
  12 #include <linux/smp.h>
  13 #include <linux/threads.h>
  14 
  15 #include <asm/spitfire.h>
  16 #include <asm/pgtable.h>
  17 #include <asm/oplib.h>
  18 #include <asm/setup.h>
  19 #include <asm/page.h>
  20 #include <asm/head.h>
  21 #include <asm/psr.h>
  22 #include <asm/mbus.h>
  23 #include <asm/cpudata.h>
  24 
  25 #include "kernel.h"
  26 #include "entry.h"
  27 
  28 DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
  29 EXPORT_PER_CPU_SYMBOL(__cpu_data);
  30 
  31 int ncpus_probed;
  32 unsigned int fsr_storage;
  33 
  34 struct cpu_info {
  35         int psr_vers;
  36         const char *name;
  37         const char *pmu_name;
  38 };
  39 
  40 struct fpu_info {
  41         int fp_vers;
  42         const char *name;
  43 };
  44 
  45 #define NOCPU 8
  46 #define NOFPU 8
  47 
  48 struct manufacturer_info {
  49         int psr_impl;
  50         struct cpu_info cpu_info[NOCPU];
  51         struct fpu_info fpu_info[NOFPU];
  52 };
  53 
  54 #define CPU(ver, _name) \
  55 { .psr_vers = ver, .name = _name }
  56 
  57 #define CPU_PMU(ver, _name, _pmu_name)  \
  58 { .psr_vers = ver, .name = _name, .pmu_name = _pmu_name }
  59 
  60 #define FPU(ver, _name) \
  61 { .fp_vers = ver, .name = _name }
  62 
  63 static const struct manufacturer_info __initconst manufacturer_info[] = {
  64 {
  65         0,
  66         /* Sun4/100, 4/200, SLC */
  67         .cpu_info = {
  68                 CPU(0, "Fujitsu  MB86900/1A or LSI L64831 SparcKIT-40"),
  69                 /* borned STP1012PGA */
  70                 CPU(4,  "Fujitsu  MB86904"),
  71                 CPU(5, "Fujitsu TurboSparc MB86907"),
  72                 CPU(-1, NULL)
  73         },
  74         .fpu_info = {
  75                 FPU(0, "Fujitsu MB86910 or Weitek WTL1164/5"),
  76                 FPU(1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"),
  77                 FPU(2, "LSI Logic L64802 or Texas Instruments ACT8847"),
  78                 /* SparcStation SLC, SparcStation1 */
  79                 FPU(3, "Weitek WTL3170/2"),
  80                 /* SPARCstation-5 */
  81                 FPU(4, "Lsi Logic/Meiko L64804 or compatible"),
  82                 FPU(-1, NULL)
  83         }
  84 },{
  85         1,
  86         .cpu_info = {
  87                 /* SparcStation2, SparcServer 490 & 690 */
  88                 CPU(0, "LSI Logic Corporation - L64811"),
  89                 /* SparcStation2 */
  90                 CPU(1, "Cypress/ROSS CY7C601"),
  91                 /* Embedded controller */
  92                 CPU(3, "Cypress/ROSS CY7C611"),
  93                 /* Ross Technologies HyperSparc */
  94                 CPU(0xf, "ROSS HyperSparc RT620"),
  95                 CPU(0xe, "ROSS HyperSparc RT625 or RT626"),
  96                 CPU(-1, NULL)
  97         },
  98         .fpu_info = {
  99                 FPU(0, "ROSS HyperSparc combined IU/FPU"),
 100                 FPU(1, "Lsi Logic L64814"),
 101                 FPU(2, "Texas Instruments TMS390-C602A"),
 102                 FPU(3, "Cypress CY7C602 FPU"),
 103                 FPU(-1, NULL)
 104         }
 105 },{
 106         2,
 107         .cpu_info = {
 108                 /* ECL Implementation, CRAY S-MP Supercomputer... AIEEE! */
 109                 /* Someone please write the code to support this beast! ;) */
 110                 CPU(0, "Bipolar Integrated Technology - B5010"),
 111                 CPU(-1, NULL)
 112         },
 113         .fpu_info = {
 114                 FPU(-1, NULL)
 115         }
 116 },{
 117         3,
 118         .cpu_info = {
 119                 CPU(0, "LSI Logic Corporation - unknown-type"),
 120                 CPU(-1, NULL)
 121         },
 122         .fpu_info = {
 123                 FPU(-1, NULL)
 124         }
 125 },{
 126         PSR_IMPL_TI,
 127         .cpu_info = {
 128                 CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
 129                 /* SparcClassic  --  borned STP1010TAB-50*/
 130                 CPU(1, "Texas Instruments, Inc. - MicroSparc"),
 131                 CPU(2, "Texas Instruments, Inc. - MicroSparc II"),
 132                 CPU(3, "Texas Instruments, Inc. - SuperSparc 51"),
 133                 CPU(4, "Texas Instruments, Inc. - SuperSparc 61"),
 134                 CPU(5, "Texas Instruments, Inc. - unknown"),
 135                 CPU(-1, NULL)
 136         },
 137         .fpu_info = {
 138                 /* SuperSparc 50 module */
 139                 FPU(0, "SuperSparc on-chip FPU"),
 140                 /* SparcClassic */
 141                 FPU(4, "TI MicroSparc on chip FPU"),
 142                 FPU(-1, NULL)
 143         }
 144 },{
 145         5,
 146         .cpu_info = {
 147                 CPU(0, "Matsushita - MN10501"),
 148                 CPU(-1, NULL)
 149         },
 150         .fpu_info = {
 151                 FPU(0, "Matsushita MN10501"),
 152                 FPU(-1, NULL)
 153         }
 154 },{
 155         6,
 156         .cpu_info = {
 157                 CPU(0, "Philips Corporation - unknown"),
 158                 CPU(-1, NULL)
 159         },
 160         .fpu_info = {
 161                 FPU(-1, NULL)
 162         }
 163 },{
 164         7,
 165         .cpu_info = {
 166                 CPU(0, "Harvest VLSI Design Center, Inc. - unknown"),
 167                 CPU(-1, NULL)
 168         },
 169         .fpu_info = {
 170                 FPU(-1, NULL)
 171         }
 172 },{
 173         8,
 174         .cpu_info = {
 175                 CPU(0, "Systems and Processes Engineering Corporation (SPEC)"),
 176                 CPU(-1, NULL)
 177         },
 178         .fpu_info = {
 179                 FPU(-1, NULL)
 180         }
 181 },{
 182         9,
 183         .cpu_info = {
 184                 /* Gallium arsenide 200MHz, BOOOOGOOOOMIPS!!! */
 185                 CPU(0, "Fujitsu or Weitek Power-UP"),
 186                 CPU(1, "Fujitsu or Weitek Power-UP"),
 187                 CPU(2, "Fujitsu or Weitek Power-UP"),
 188                 CPU(3, "Fujitsu or Weitek Power-UP"),
 189                 CPU(-1, NULL)
 190         },
 191         .fpu_info = {
 192                 FPU(3, "Fujitsu or Weitek on-chip FPU"),
 193                 FPU(-1, NULL)
 194         }
 195 },{
 196         PSR_IMPL_LEON,          /* Aeroflex Gaisler */
 197         .cpu_info = {
 198                 CPU(3, "LEON"),
 199                 CPU(-1, NULL)
 200         },
 201         .fpu_info = {
 202                 FPU(2, "GRFPU"),
 203                 FPU(3, "GRFPU-Lite"),
 204                 FPU(-1, NULL)
 205         }
 206 },{
 207         0x17,
 208         .cpu_info = {
 209                 CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
 210                 CPU_PMU(0x11, "TI UltraSparc II  (BlackBird)", "ultra12"),
 211                 CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"),
 212                 CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"),
 213                 CPU(-1, NULL)
 214         },
 215         .fpu_info = {
 216                 FPU(0x10, "UltraSparc I integrated FPU"),
 217                 FPU(0x11, "UltraSparc II integrated FPU"),
 218                 FPU(0x12, "UltraSparc IIi integrated FPU"),
 219                 FPU(0x13, "UltraSparc IIe integrated FPU"),
 220                 FPU(-1, NULL)
 221         }
 222 },{
 223         0x22,
 224         .cpu_info = {
 225                 CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
 226                 CPU(-1, NULL)
 227         },
 228         .fpu_info = {
 229                 FPU(0x10, "UltraSparc I integrated FPU"),
 230                 FPU(-1, NULL)
 231         }
 232 },{
 233         0x3e,
 234         .cpu_info = {
 235                 CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"),
 236                 CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"),
 237                 CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"),
 238                 CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"),
 239                 CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"),
 240                 CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"),
 241                 CPU(-1, NULL)
 242         },
 243         .fpu_info = {
 244                 FPU(0x14, "UltraSparc III integrated FPU"),
 245                 FPU(0x15, "UltraSparc III+ integrated FPU"),
 246                 FPU(0x16, "UltraSparc IIIi integrated FPU"),
 247                 FPU(0x18, "UltraSparc IV integrated FPU"),
 248                 FPU(0x19, "UltraSparc IV+ integrated FPU"),
 249                 FPU(0x22, "UltraSparc IIIi+ integrated FPU"),
 250                 FPU(-1, NULL)
 251         }
 252 }};
 253 
 254 /* In order to get the fpu type correct, you need to take the IDPROM's
 255  * machine type value into consideration too.  I will fix this.
 256  */
 257 
 258 static const char *sparc_cpu_type;
 259 static const char *sparc_fpu_type;
 260 const char *sparc_pmu_type;
 261 
 262 
 263 static void __init set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
 264 {
 265         const struct manufacturer_info *manuf;
 266         int i;
 267 
 268         sparc_cpu_type = NULL;
 269         sparc_fpu_type = NULL;
 270         sparc_pmu_type = NULL;
 271         manuf = NULL;
 272 
 273         for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++)
 274         {
 275                 if (psr_impl == manufacturer_info[i].psr_impl) {
 276                         manuf = &manufacturer_info[i];
 277                         break;
 278                 }
 279         }
 280         if (manuf != NULL)
 281         {
 282                 const struct cpu_info *cpu;
 283                 const struct fpu_info *fpu;
 284 
 285                 cpu = &manuf->cpu_info[0];
 286                 while (cpu->psr_vers != -1)
 287                 {
 288                         if (cpu->psr_vers == psr_vers) {
 289                                 sparc_cpu_type = cpu->name;
 290                                 sparc_pmu_type = cpu->pmu_name;
 291                                 sparc_fpu_type = "No FPU";
 292                                 break;
 293                         }
 294                         cpu++;
 295                 }
 296                 fpu =  &manuf->fpu_info[0];
 297                 while (fpu->fp_vers != -1)
 298                 {
 299                         if (fpu->fp_vers == fpu_vers) {
 300                                 sparc_fpu_type = fpu->name;
 301                                 break;
 302                         }
 303                         fpu++;
 304                 }
 305         }
 306         if (sparc_cpu_type == NULL)
 307         {
 308                 printk(KERN_ERR "CPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
 309                        psr_impl, psr_vers);
 310                 sparc_cpu_type = "Unknown CPU";
 311         }
 312         if (sparc_fpu_type == NULL)
 313         {
 314                 printk(KERN_ERR "FPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
 315                        psr_impl, fpu_vers);
 316                 sparc_fpu_type = "Unknown FPU";
 317         }
 318         if (sparc_pmu_type == NULL)
 319                 sparc_pmu_type = "Unknown PMU";
 320 }
 321 
 322 #ifdef CONFIG_SPARC32
 323 static int show_cpuinfo(struct seq_file *m, void *__unused)
 324 {
 325         seq_printf(m,
 326                    "cpu\t\t: %s\n"
 327                    "fpu\t\t: %s\n"
 328                    "promlib\t\t: Version %d Revision %d\n"
 329                    "prom\t\t: %d.%d\n"
 330                    "type\t\t: %s\n"
 331                    "ncpus probed\t: %d\n"
 332                    "ncpus active\t: %d\n"
 333 #ifndef CONFIG_SMP
 334                    "CPU0Bogo\t: %lu.%02lu\n"
 335                    "CPU0ClkTck\t: %ld\n"
 336 #endif
 337                    ,
 338                    sparc_cpu_type,
 339                    sparc_fpu_type ,
 340                    romvec->pv_romvers,
 341                    prom_rev,
 342                    romvec->pv_printrev >> 16,
 343                    romvec->pv_printrev & 0xffff,
 344                    &cputypval[0],
 345                    ncpus_probed,
 346                    num_online_cpus()
 347 #ifndef CONFIG_SMP
 348                    , cpu_data(0).udelay_val/(500000/HZ),
 349                    (cpu_data(0).udelay_val/(5000/HZ)) % 100,
 350                    cpu_data(0).clock_tick
 351 #endif
 352                 );
 353 
 354 #ifdef CONFIG_SMP
 355         smp_bogo(m);
 356 #endif
 357         mmu_info(m);
 358 #ifdef CONFIG_SMP
 359         smp_info(m);
 360 #endif
 361         return 0;
 362 }
 363 #endif /* CONFIG_SPARC32 */
 364 
 365 #ifdef CONFIG_SPARC64
 366 unsigned int dcache_parity_tl1_occurred;
 367 unsigned int icache_parity_tl1_occurred;
 368 
 369 
 370 static int show_cpuinfo(struct seq_file *m, void *__unused)
 371 {
 372         seq_printf(m,
 373                    "cpu\t\t: %s\n"
 374                    "fpu\t\t: %s\n"
 375                    "pmu\t\t: %s\n"
 376                    "prom\t\t: %s\n"
 377                    "type\t\t: %s\n"
 378                    "ncpus probed\t: %d\n"
 379                    "ncpus active\t: %d\n"
 380                    "D$ parity tl1\t: %u\n"
 381                    "I$ parity tl1\t: %u\n"
 382 #ifndef CONFIG_SMP
 383                    "Cpu0ClkTck\t: %016lx\n"
 384 #endif
 385                    ,
 386                    sparc_cpu_type,
 387                    sparc_fpu_type,
 388                    sparc_pmu_type,
 389                    prom_version,
 390                    ((tlb_type == hypervisor) ?
 391                     "sun4v" :
 392                     "sun4u"),
 393                    ncpus_probed,
 394                    num_online_cpus(),
 395                    dcache_parity_tl1_occurred,
 396                    icache_parity_tl1_occurred
 397 #ifndef CONFIG_SMP
 398                    , cpu_data(0).clock_tick
 399 #endif
 400                 );
 401         cpucap_info(m);
 402 #ifdef CONFIG_SMP
 403         smp_bogo(m);
 404 #endif
 405         mmu_info(m);
 406 #ifdef CONFIG_SMP
 407         smp_info(m);
 408 #endif
 409         return 0;
 410 }
 411 #endif /* CONFIG_SPARC64 */
 412 
 413 static void *c_start(struct seq_file *m, loff_t *pos)
 414 {
 415         /* The pointer we are returning is arbitrary,
 416          * it just has to be non-NULL and not IS_ERR
 417          * in the success case.
 418          */
 419         return *pos == 0 ? &c_start : NULL;
 420 }
 421 
 422 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 423 {
 424         ++*pos;
 425         return c_start(m, pos);
 426 }
 427 
 428 static void c_stop(struct seq_file *m, void *v)
 429 {
 430 }
 431 
 432 const struct seq_operations cpuinfo_op = {
 433         .start =c_start,
 434         .next = c_next,
 435         .stop = c_stop,
 436         .show = show_cpuinfo,
 437 };
 438 
 439 #ifdef CONFIG_SPARC32
 440 static int __init cpu_type_probe(void)
 441 {
 442         int psr_impl, psr_vers, fpu_vers;
 443         int psr;
 444 
 445         psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK);
 446         psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK);
 447 
 448         psr = get_psr();
 449         put_psr(psr | PSR_EF);
 450 
 451         if (psr_impl == PSR_IMPL_LEON)
 452                 fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
 453         else
 454                 fpu_vers = ((get_fsr() >> 17) & 0x7);
 455 
 456         put_psr(psr);
 457 
 458         set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
 459 
 460         return 0;
 461 }
 462 #endif /* CONFIG_SPARC32 */
 463 
 464 #ifdef CONFIG_SPARC64
 465 static void __init sun4v_cpu_probe(void)
 466 {
 467         switch (sun4v_chip_type) {
 468         case SUN4V_CHIP_NIAGARA1:
 469                 sparc_cpu_type = "UltraSparc T1 (Niagara)";
 470                 sparc_fpu_type = "UltraSparc T1 integrated FPU";
 471                 sparc_pmu_type = "niagara";
 472                 break;
 473 
 474         case SUN4V_CHIP_NIAGARA2:
 475                 sparc_cpu_type = "UltraSparc T2 (Niagara2)";
 476                 sparc_fpu_type = "UltraSparc T2 integrated FPU";
 477                 sparc_pmu_type = "niagara2";
 478                 break;
 479 
 480         case SUN4V_CHIP_NIAGARA3:
 481                 sparc_cpu_type = "UltraSparc T3 (Niagara3)";
 482                 sparc_fpu_type = "UltraSparc T3 integrated FPU";
 483                 sparc_pmu_type = "niagara3";
 484                 break;
 485 
 486         case SUN4V_CHIP_NIAGARA4:
 487                 sparc_cpu_type = "UltraSparc T4 (Niagara4)";
 488                 sparc_fpu_type = "UltraSparc T4 integrated FPU";
 489                 sparc_pmu_type = "niagara4";
 490                 break;
 491 
 492         case SUN4V_CHIP_NIAGARA5:
 493                 sparc_cpu_type = "UltraSparc T5 (Niagara5)";
 494                 sparc_fpu_type = "UltraSparc T5 integrated FPU";
 495                 sparc_pmu_type = "niagara5";
 496                 break;
 497 
 498         case SUN4V_CHIP_SPARC_M6:
 499                 sparc_cpu_type = "SPARC-M6";
 500                 sparc_fpu_type = "SPARC-M6 integrated FPU";
 501                 sparc_pmu_type = "sparc-m6";
 502                 break;
 503 
 504         case SUN4V_CHIP_SPARC_M7:
 505                 sparc_cpu_type = "SPARC-M7";
 506                 sparc_fpu_type = "SPARC-M7 integrated FPU";
 507                 sparc_pmu_type = "sparc-m7";
 508                 break;
 509 
 510         case SUN4V_CHIP_SPARC_M8:
 511                 sparc_cpu_type = "SPARC-M8";
 512                 sparc_fpu_type = "SPARC-M8 integrated FPU";
 513                 sparc_pmu_type = "sparc-m8";
 514                 break;
 515 
 516         case SUN4V_CHIP_SPARC_SN:
 517                 sparc_cpu_type = "SPARC-SN";
 518                 sparc_fpu_type = "SPARC-SN integrated FPU";
 519                 sparc_pmu_type = "sparc-sn";
 520                 break;
 521 
 522         case SUN4V_CHIP_SPARC64X:
 523                 sparc_cpu_type = "SPARC64-X";
 524                 sparc_fpu_type = "SPARC64-X integrated FPU";
 525                 sparc_pmu_type = "sparc64-x";
 526                 break;
 527 
 528         default:
 529                 printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
 530                        prom_cpu_compatible);
 531                 sparc_cpu_type = "Unknown SUN4V CPU";
 532                 sparc_fpu_type = "Unknown SUN4V FPU";
 533                 sparc_pmu_type = "Unknown SUN4V PMU";
 534                 break;
 535         }
 536 }
 537 
 538 static int __init cpu_type_probe(void)
 539 {
 540         if (tlb_type == hypervisor) {
 541                 sun4v_cpu_probe();
 542         } else {
 543                 unsigned long ver;
 544                 int manuf, impl;
 545 
 546                 __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
 547 
 548                 manuf = ((ver >> 48) & 0xffff);
 549                 impl = ((ver >> 32) & 0xffff);
 550                 set_cpu_and_fpu(manuf, impl, impl);
 551         }
 552         return 0;
 553 }
 554 #endif /* CONFIG_SPARC64 */
 555 
 556 early_initcall(cpu_type_probe);

/* [<][>][^][v][top][bottom][index][help] */