0001
0002
0003
0004
0005
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
0067 .cpu_info = {
0068 CPU(0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"),
0069
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
0079 FPU(3, "Weitek WTL3170/2"),
0080
0081 FPU(4, "Lsi Logic/Meiko L64804 or compatible"),
0082 FPU(-1, NULL)
0083 }
0084 },{
0085 1,
0086 .cpu_info = {
0087
0088 CPU(0, "LSI Logic Corporation - L64811"),
0089
0090 CPU(1, "Cypress/ROSS CY7C601"),
0091
0092 CPU(3, "Cypress/ROSS CY7C611"),
0093
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
0109
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
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
0139 FPU(0, "SuperSparc on-chip FPU"),
0140
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
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,
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
0255
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
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
0412
0413 static void *c_start(struct seq_file *m, loff_t *pos)
0414 {
0415
0416
0417
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
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
0555
0556 early_initcall(cpu_type_probe);