Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* cpu.c: Dinky routines to look for the kind of Sparc cpu
0003  *        we are on.
0004  *
0005  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
0006  */
0007 
0008 #include <linux/seq_file.h>
0009 #include <linux/kernel.h>
0010 #include <linux/export.h>
0011 #include <linux/init.h>
0012 #include <linux/smp.h>
0013 #include <linux/threads.h>
0014 #include <linux/pgtable.h>
0015 
0016 #include <asm/spitfire.h>
0017 #include <asm/oplib.h>
0018 #include <asm/setup.h>
0019 #include <asm/page.h>
0020 #include <asm/head.h>
0021 #include <asm/psr.h>
0022 #include <asm/mbus.h>
0023 #include <asm/cpudata.h>
0024 
0025 #include "kernel.h"
0026 #include "entry.h"
0027 
0028 DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
0029 EXPORT_PER_CPU_SYMBOL(__cpu_data);
0030 
0031 int ncpus_probed;
0032 unsigned int fsr_storage;
0033 
0034 struct cpu_info {
0035     int psr_vers;
0036     const char *name;
0037     const char *pmu_name;
0038 };
0039 
0040 struct fpu_info {
0041     int fp_vers;
0042     const char *name;
0043 };
0044 
0045 #define NOCPU 8
0046 #define NOFPU 8
0047 
0048 struct manufacturer_info {
0049     int psr_impl;
0050     struct cpu_info cpu_info[NOCPU];
0051     struct fpu_info fpu_info[NOFPU];
0052 };
0053 
0054 #define CPU(ver, _name) \
0055 { .psr_vers = ver, .name = _name }
0056 
0057 #define CPU_PMU(ver, _name, _pmu_name)  \
0058 { .psr_vers = ver, .name = _name, .pmu_name = _pmu_name }
0059 
0060 #define FPU(ver, _name) \
0061 { .fp_vers = ver, .name = _name }
0062 
0063 static const struct manufacturer_info __initconst manufacturer_info[] = {
0064 {
0065     0,
0066     /* Sun4/100, 4/200, SLC */
0067     .cpu_info = {
0068         CPU(0, "Fujitsu  MB86900/1A or LSI L64831 SparcKIT-40"),
0069         /* borned STP1012PGA */
0070         CPU(4,  "Fujitsu  MB86904"),
0071         CPU(5, "Fujitsu TurboSparc MB86907"),
0072         CPU(-1, NULL)
0073     },
0074     .fpu_info = {
0075         FPU(0, "Fujitsu MB86910 or Weitek WTL1164/5"),
0076         FPU(1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"),
0077         FPU(2, "LSI Logic L64802 or Texas Instruments ACT8847"),
0078         /* SparcStation SLC, SparcStation1 */
0079         FPU(3, "Weitek WTL3170/2"),
0080         /* SPARCstation-5 */
0081         FPU(4, "Lsi Logic/Meiko L64804 or compatible"),
0082         FPU(-1, NULL)
0083     }
0084 },{
0085     1,
0086     .cpu_info = {
0087         /* SparcStation2, SparcServer 490 & 690 */
0088         CPU(0, "LSI Logic Corporation - L64811"),
0089         /* SparcStation2 */
0090         CPU(1, "Cypress/ROSS CY7C601"),
0091         /* Embedded controller */
0092         CPU(3, "Cypress/ROSS CY7C611"),
0093         /* Ross Technologies HyperSparc */
0094         CPU(0xf, "ROSS HyperSparc RT620"),
0095         CPU(0xe, "ROSS HyperSparc RT625 or RT626"),
0096         CPU(-1, NULL)
0097     },
0098     .fpu_info = {
0099         FPU(0, "ROSS HyperSparc combined IU/FPU"),
0100         FPU(1, "Lsi Logic L64814"),
0101         FPU(2, "Texas Instruments TMS390-C602A"),
0102         FPU(3, "Cypress CY7C602 FPU"),
0103         FPU(-1, NULL)
0104     }
0105 },{
0106     2,
0107     .cpu_info = {
0108         /* ECL Implementation, CRAY S-MP Supercomputer... AIEEE! */
0109         /* Someone please write the code to support this beast! ;) */
0110         CPU(0, "Bipolar Integrated Technology - B5010"),
0111         CPU(-1, NULL)
0112     },
0113     .fpu_info = {
0114         FPU(-1, NULL)
0115     }
0116 },{
0117     3,
0118     .cpu_info = {
0119         CPU(0, "LSI Logic Corporation - unknown-type"),
0120         CPU(-1, NULL)
0121     },
0122     .fpu_info = {
0123         FPU(-1, NULL)
0124     }
0125 },{
0126     PSR_IMPL_TI,
0127     .cpu_info = {
0128         CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
0129         /* SparcClassic  --  borned STP1010TAB-50*/
0130         CPU(1, "Texas Instruments, Inc. - MicroSparc"),
0131         CPU(2, "Texas Instruments, Inc. - MicroSparc II"),
0132         CPU(3, "Texas Instruments, Inc. - SuperSparc 51"),
0133         CPU(4, "Texas Instruments, Inc. - SuperSparc 61"),
0134         CPU(5, "Texas Instruments, Inc. - unknown"),
0135         CPU(-1, NULL)
0136     },
0137     .fpu_info = {
0138         /* SuperSparc 50 module */
0139         FPU(0, "SuperSparc on-chip FPU"),
0140         /* SparcClassic */
0141         FPU(4, "TI MicroSparc on chip FPU"),
0142         FPU(-1, NULL)
0143     }
0144 },{
0145     5,
0146     .cpu_info = {
0147         CPU(0, "Matsushita - MN10501"),
0148         CPU(-1, NULL)
0149     },
0150     .fpu_info = {
0151         FPU(0, "Matsushita MN10501"),
0152         FPU(-1, NULL)
0153     }
0154 },{
0155     6,
0156     .cpu_info = {
0157         CPU(0, "Philips Corporation - unknown"),
0158         CPU(-1, NULL)
0159     },
0160     .fpu_info = {
0161         FPU(-1, NULL)
0162     }
0163 },{
0164     7,
0165     .cpu_info = {
0166         CPU(0, "Harvest VLSI Design Center, Inc. - unknown"),
0167         CPU(-1, NULL)
0168     },
0169     .fpu_info = {
0170         FPU(-1, NULL)
0171     }
0172 },{
0173     8,
0174     .cpu_info = {
0175         CPU(0, "Systems and Processes Engineering Corporation (SPEC)"),
0176         CPU(-1, NULL)
0177     },
0178     .fpu_info = {
0179         FPU(-1, NULL)
0180     }
0181 },{
0182     9,
0183     .cpu_info = {
0184         /* Gallium arsenide 200MHz, BOOOOGOOOOMIPS!!! */
0185         CPU(0, "Fujitsu or Weitek Power-UP"),
0186         CPU(1, "Fujitsu or Weitek Power-UP"),
0187         CPU(2, "Fujitsu or Weitek Power-UP"),
0188         CPU(3, "Fujitsu or Weitek Power-UP"),
0189         CPU(-1, NULL)
0190     },
0191     .fpu_info = {
0192         FPU(3, "Fujitsu or Weitek on-chip FPU"),
0193         FPU(-1, NULL)
0194     }
0195 },{
0196     PSR_IMPL_LEON,      /* Aeroflex Gaisler */
0197     .cpu_info = {
0198         CPU(3, "LEON"),
0199         CPU(-1, NULL)
0200     },
0201     .fpu_info = {
0202         FPU(2, "GRFPU"),
0203         FPU(3, "GRFPU-Lite"),
0204         FPU(-1, NULL)
0205     }
0206 },{
0207     0x17,
0208     .cpu_info = {
0209         CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
0210         CPU_PMU(0x11, "TI UltraSparc II  (BlackBird)", "ultra12"),
0211         CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"),
0212         CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"),
0213         CPU(-1, NULL)
0214     },
0215     .fpu_info = {
0216         FPU(0x10, "UltraSparc I integrated FPU"),
0217         FPU(0x11, "UltraSparc II integrated FPU"),
0218         FPU(0x12, "UltraSparc IIi integrated FPU"),
0219         FPU(0x13, "UltraSparc IIe integrated FPU"),
0220         FPU(-1, NULL)
0221     }
0222 },{
0223     0x22,
0224     .cpu_info = {
0225         CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
0226         CPU(-1, NULL)
0227     },
0228     .fpu_info = {
0229         FPU(0x10, "UltraSparc I integrated FPU"),
0230         FPU(-1, NULL)
0231     }
0232 },{
0233     0x3e,
0234     .cpu_info = {
0235         CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"),
0236         CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"),
0237         CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"),
0238         CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"),
0239         CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"),
0240         CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"),
0241         CPU(-1, NULL)
0242     },
0243     .fpu_info = {
0244         FPU(0x14, "UltraSparc III integrated FPU"),
0245         FPU(0x15, "UltraSparc III+ integrated FPU"),
0246         FPU(0x16, "UltraSparc IIIi integrated FPU"),
0247         FPU(0x18, "UltraSparc IV integrated FPU"),
0248         FPU(0x19, "UltraSparc IV+ integrated FPU"),
0249         FPU(0x22, "UltraSparc IIIi+ integrated FPU"),
0250         FPU(-1, NULL)
0251     }
0252 }};
0253 
0254 /* In order to get the fpu type correct, you need to take the IDPROM's
0255  * machine type value into consideration too.  I will fix this.
0256  */
0257 
0258 static const char *sparc_cpu_type;
0259 static const char *sparc_fpu_type;
0260 const char *sparc_pmu_type;
0261 
0262 
0263 static void __init set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
0264 {
0265     const struct manufacturer_info *manuf;
0266     int i;
0267 
0268     sparc_cpu_type = NULL;
0269     sparc_fpu_type = NULL;
0270     sparc_pmu_type = NULL;
0271     manuf = NULL;
0272 
0273     for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++)
0274     {
0275         if (psr_impl == manufacturer_info[i].psr_impl) {
0276             manuf = &manufacturer_info[i];
0277             break;
0278         }
0279     }
0280     if (manuf != NULL)
0281     {
0282         const struct cpu_info *cpu;
0283         const struct fpu_info *fpu;
0284 
0285         cpu = &manuf->cpu_info[0];
0286         while (cpu->psr_vers != -1)
0287         {
0288             if (cpu->psr_vers == psr_vers) {
0289                 sparc_cpu_type = cpu->name;
0290                 sparc_pmu_type = cpu->pmu_name;
0291                 sparc_fpu_type = "No FPU";
0292                 break;
0293             }
0294             cpu++;
0295         }
0296         fpu =  &manuf->fpu_info[0];
0297         while (fpu->fp_vers != -1)
0298         {
0299             if (fpu->fp_vers == fpu_vers) {
0300                 sparc_fpu_type = fpu->name;
0301                 break;
0302             }
0303             fpu++;
0304         }
0305     }
0306     if (sparc_cpu_type == NULL)
0307     {
0308         printk(KERN_ERR "CPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
0309                psr_impl, psr_vers);
0310         sparc_cpu_type = "Unknown CPU";
0311     }
0312     if (sparc_fpu_type == NULL)
0313     {
0314         printk(KERN_ERR "FPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
0315                psr_impl, fpu_vers);
0316         sparc_fpu_type = "Unknown FPU";
0317     }
0318     if (sparc_pmu_type == NULL)
0319         sparc_pmu_type = "Unknown PMU";
0320 }
0321 
0322 #ifdef CONFIG_SPARC32
0323 static int show_cpuinfo(struct seq_file *m, void *__unused)
0324 {
0325     seq_printf(m,
0326            "cpu\t\t: %s\n"
0327            "fpu\t\t: %s\n"
0328            "promlib\t\t: Version %d Revision %d\n"
0329            "prom\t\t: %d.%d\n"
0330            "type\t\t: %s\n"
0331            "ncpus probed\t: %d\n"
0332            "ncpus active\t: %d\n"
0333 #ifndef CONFIG_SMP
0334            "CPU0Bogo\t: %lu.%02lu\n"
0335            "CPU0ClkTck\t: %ld\n"
0336 #endif
0337            ,
0338            sparc_cpu_type,
0339            sparc_fpu_type ,
0340            romvec->pv_romvers,
0341            prom_rev,
0342            romvec->pv_printrev >> 16,
0343            romvec->pv_printrev & 0xffff,
0344            &cputypval[0],
0345            ncpus_probed,
0346            num_online_cpus()
0347 #ifndef CONFIG_SMP
0348            , cpu_data(0).udelay_val/(500000/HZ),
0349            (cpu_data(0).udelay_val/(5000/HZ)) % 100,
0350            cpu_data(0).clock_tick
0351 #endif
0352         );
0353 
0354 #ifdef CONFIG_SMP
0355     smp_bogo(m);
0356 #endif
0357     mmu_info(m);
0358 #ifdef CONFIG_SMP
0359     smp_info(m);
0360 #endif
0361     return 0;
0362 }
0363 #endif /* CONFIG_SPARC32 */
0364 
0365 #ifdef CONFIG_SPARC64
0366 unsigned int dcache_parity_tl1_occurred;
0367 unsigned int icache_parity_tl1_occurred;
0368 
0369 
0370 static int show_cpuinfo(struct seq_file *m, void *__unused)
0371 {
0372     seq_printf(m,
0373            "cpu\t\t: %s\n"
0374            "fpu\t\t: %s\n"
0375            "pmu\t\t: %s\n"
0376            "prom\t\t: %s\n"
0377            "type\t\t: %s\n"
0378            "ncpus probed\t: %d\n"
0379            "ncpus active\t: %d\n"
0380            "D$ parity tl1\t: %u\n"
0381            "I$ parity tl1\t: %u\n"
0382 #ifndef CONFIG_SMP
0383            "Cpu0ClkTck\t: %016lx\n"
0384 #endif
0385            ,
0386            sparc_cpu_type,
0387            sparc_fpu_type,
0388            sparc_pmu_type,
0389            prom_version,
0390            ((tlb_type == hypervisor) ?
0391             "sun4v" :
0392             "sun4u"),
0393            ncpus_probed,
0394            num_online_cpus(),
0395            dcache_parity_tl1_occurred,
0396            icache_parity_tl1_occurred
0397 #ifndef CONFIG_SMP
0398            , cpu_data(0).clock_tick
0399 #endif
0400         );
0401     cpucap_info(m);
0402 #ifdef CONFIG_SMP
0403     smp_bogo(m);
0404 #endif
0405     mmu_info(m);
0406 #ifdef CONFIG_SMP
0407     smp_info(m);
0408 #endif
0409     return 0;
0410 }
0411 #endif /* CONFIG_SPARC64 */
0412 
0413 static void *c_start(struct seq_file *m, loff_t *pos)
0414 {
0415     /* The pointer we are returning is arbitrary,
0416      * it just has to be non-NULL and not IS_ERR
0417      * in the success case.
0418      */
0419     return *pos == 0 ? &c_start : NULL;
0420 }
0421 
0422 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
0423 {
0424     ++*pos;
0425     return c_start(m, pos);
0426 }
0427 
0428 static void c_stop(struct seq_file *m, void *v)
0429 {
0430 }
0431 
0432 const struct seq_operations cpuinfo_op = {
0433     .start =c_start,
0434     .next = c_next,
0435     .stop = c_stop,
0436     .show = show_cpuinfo,
0437 };
0438 
0439 #ifdef CONFIG_SPARC32
0440 static int __init cpu_type_probe(void)
0441 {
0442     int psr_impl, psr_vers, fpu_vers;
0443     int psr;
0444 
0445     psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK);
0446     psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK);
0447 
0448     psr = get_psr();
0449     put_psr(psr | PSR_EF);
0450 
0451     if (psr_impl == PSR_IMPL_LEON)
0452         fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
0453     else
0454         fpu_vers = ((get_fsr() >> 17) & 0x7);
0455 
0456     put_psr(psr);
0457 
0458     set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
0459 
0460     return 0;
0461 }
0462 #endif /* CONFIG_SPARC32 */
0463 
0464 #ifdef CONFIG_SPARC64
0465 static void __init sun4v_cpu_probe(void)
0466 {
0467     switch (sun4v_chip_type) {
0468     case SUN4V_CHIP_NIAGARA1:
0469         sparc_cpu_type = "UltraSparc T1 (Niagara)";
0470         sparc_fpu_type = "UltraSparc T1 integrated FPU";
0471         sparc_pmu_type = "niagara";
0472         break;
0473 
0474     case SUN4V_CHIP_NIAGARA2:
0475         sparc_cpu_type = "UltraSparc T2 (Niagara2)";
0476         sparc_fpu_type = "UltraSparc T2 integrated FPU";
0477         sparc_pmu_type = "niagara2";
0478         break;
0479 
0480     case SUN4V_CHIP_NIAGARA3:
0481         sparc_cpu_type = "UltraSparc T3 (Niagara3)";
0482         sparc_fpu_type = "UltraSparc T3 integrated FPU";
0483         sparc_pmu_type = "niagara3";
0484         break;
0485 
0486     case SUN4V_CHIP_NIAGARA4:
0487         sparc_cpu_type = "UltraSparc T4 (Niagara4)";
0488         sparc_fpu_type = "UltraSparc T4 integrated FPU";
0489         sparc_pmu_type = "niagara4";
0490         break;
0491 
0492     case SUN4V_CHIP_NIAGARA5:
0493         sparc_cpu_type = "UltraSparc T5 (Niagara5)";
0494         sparc_fpu_type = "UltraSparc T5 integrated FPU";
0495         sparc_pmu_type = "niagara5";
0496         break;
0497 
0498     case SUN4V_CHIP_SPARC_M6:
0499         sparc_cpu_type = "SPARC-M6";
0500         sparc_fpu_type = "SPARC-M6 integrated FPU";
0501         sparc_pmu_type = "sparc-m6";
0502         break;
0503 
0504     case SUN4V_CHIP_SPARC_M7:
0505         sparc_cpu_type = "SPARC-M7";
0506         sparc_fpu_type = "SPARC-M7 integrated FPU";
0507         sparc_pmu_type = "sparc-m7";
0508         break;
0509 
0510     case SUN4V_CHIP_SPARC_M8:
0511         sparc_cpu_type = "SPARC-M8";
0512         sparc_fpu_type = "SPARC-M8 integrated FPU";
0513         sparc_pmu_type = "sparc-m8";
0514         break;
0515 
0516     case SUN4V_CHIP_SPARC_SN:
0517         sparc_cpu_type = "SPARC-SN";
0518         sparc_fpu_type = "SPARC-SN integrated FPU";
0519         sparc_pmu_type = "sparc-sn";
0520         break;
0521 
0522     case SUN4V_CHIP_SPARC64X:
0523         sparc_cpu_type = "SPARC64-X";
0524         sparc_fpu_type = "SPARC64-X integrated FPU";
0525         sparc_pmu_type = "sparc64-x";
0526         break;
0527 
0528     default:
0529         printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
0530                prom_cpu_compatible);
0531         sparc_cpu_type = "Unknown SUN4V CPU";
0532         sparc_fpu_type = "Unknown SUN4V FPU";
0533         sparc_pmu_type = "Unknown SUN4V PMU";
0534         break;
0535     }
0536 }
0537 
0538 static int __init cpu_type_probe(void)
0539 {
0540     if (tlb_type == hypervisor) {
0541         sun4v_cpu_probe();
0542     } else {
0543         unsigned long ver;
0544         int manuf, impl;
0545 
0546         __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
0547 
0548         manuf = ((ver >> 48) & 0xffff);
0549         impl = ((ver >> 32) & 0xffff);
0550         set_cpu_and_fpu(manuf, impl, impl);
0551     }
0552     return 0;
0553 }
0554 #endif /* CONFIG_SPARC64 */
0555 
0556 early_initcall(cpu_type_probe);