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