diff options
Diffstat (limited to 'arch/sparc64/kernel/cpu.c')
-rw-r--r-- | arch/sparc64/kernel/cpu.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c new file mode 100644 index 000000000000..48756958116b --- /dev/null +++ b/arch/sparc64/kernel/cpu.c | |||
@@ -0,0 +1,124 @@ | |||
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 (davem@caip.rutgers.edu) | ||
5 | */ | ||
6 | |||
7 | #include <linux/config.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <asm/asi.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/fpumacro.h> | ||
15 | #include <asm/cpudata.h> | ||
16 | |||
17 | DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; | ||
18 | |||
19 | struct cpu_iu_info { | ||
20 | short manuf; | ||
21 | short impl; | ||
22 | char* cpu_name; /* should be enough I hope... */ | ||
23 | }; | ||
24 | |||
25 | struct cpu_fp_info { | ||
26 | short manuf; | ||
27 | short impl; | ||
28 | char fpu_vers; | ||
29 | char* fp_name; | ||
30 | }; | ||
31 | |||
32 | struct cpu_fp_info linux_sparc_fpu[] = { | ||
33 | { 0x17, 0x10, 0, "UltraSparc I integrated FPU"}, | ||
34 | { 0x22, 0x10, 0, "UltraSparc I integrated FPU"}, | ||
35 | { 0x17, 0x11, 0, "UltraSparc II integrated FPU"}, | ||
36 | { 0x17, 0x12, 0, "UltraSparc IIi integrated FPU"}, | ||
37 | { 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"}, | ||
38 | { 0x3e, 0x14, 0, "UltraSparc III integrated FPU"}, | ||
39 | { 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"}, | ||
40 | { 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"}, | ||
41 | { 0x3e, 0x18, 0, "UltraSparc IV integrated FPU"}, | ||
42 | }; | ||
43 | |||
44 | #define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) | ||
45 | |||
46 | struct cpu_iu_info linux_sparc_chips[] = { | ||
47 | { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, | ||
48 | { 0x22, 0x10, "TI UltraSparc I (SpitFire)"}, | ||
49 | { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, | ||
50 | { 0x17, 0x12, "TI UltraSparc IIi (Sabre)"}, | ||
51 | { 0x17, 0x13, "TI UltraSparc IIe (Hummingbird)"}, | ||
52 | { 0x3e, 0x14, "TI UltraSparc III (Cheetah)"}, | ||
53 | { 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"}, | ||
54 | { 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"}, | ||
55 | { 0x3e, 0x18, "TI UltraSparc IV (Jaguar)"}, | ||
56 | }; | ||
57 | |||
58 | #define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) | ||
59 | |||
60 | char *sparc_cpu_type = "cpu-oops"; | ||
61 | char *sparc_fpu_type = "fpu-oops"; | ||
62 | |||
63 | unsigned int fsr_storage; | ||
64 | |||
65 | void __init cpu_probe(void) | ||
66 | { | ||
67 | unsigned long ver, fpu_vers, manuf, impl, fprs; | ||
68 | int i; | ||
69 | |||
70 | fprs = fprs_read(); | ||
71 | fprs_write(FPRS_FEF); | ||
72 | __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" | ||
73 | : "=&r" (ver) | ||
74 | : "r" (&fpu_vers)); | ||
75 | fprs_write(fprs); | ||
76 | |||
77 | manuf = ((ver >> 48) & 0xffff); | ||
78 | impl = ((ver >> 32) & 0xffff); | ||
79 | |||
80 | fpu_vers = ((fpu_vers >> 17) & 0x7); | ||
81 | |||
82 | retry: | ||
83 | for (i = 0; i < NSPARCCHIPS; i++) { | ||
84 | if (linux_sparc_chips[i].manuf == manuf) { | ||
85 | if (linux_sparc_chips[i].impl == impl) { | ||
86 | sparc_cpu_type = | ||
87 | linux_sparc_chips[i].cpu_name; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if (i == NSPARCCHIPS) { | ||
94 | /* Maybe it is a cheetah+ derivative, report it as cheetah+ | ||
95 | * in that case until we learn the real names. | ||
96 | */ | ||
97 | if (manuf == 0x3e && | ||
98 | impl > 0x15) { | ||
99 | impl = 0x15; | ||
100 | goto retry; | ||
101 | } else { | ||
102 | printk("DEBUG: manuf[%lx] impl[%lx]\n", | ||
103 | manuf, impl); | ||
104 | } | ||
105 | sparc_cpu_type = "Unknown CPU"; | ||
106 | } | ||
107 | |||
108 | for (i = 0; i < NSPARCFPU; i++) { | ||
109 | if (linux_sparc_fpu[i].manuf == manuf && | ||
110 | linux_sparc_fpu[i].impl == impl) { | ||
111 | if (linux_sparc_fpu[i].fpu_vers == fpu_vers) { | ||
112 | sparc_fpu_type = | ||
113 | linux_sparc_fpu[i].fp_name; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | if (i == NSPARCFPU) { | ||
120 | printk("DEBUG: manuf[%lx] impl[%lx] fsr.vers[%lx]\n", | ||
121 | manuf, impl, fpu_vers); | ||
122 | sparc_fpu_type = "Unknown FPU"; | ||
123 | } | ||
124 | } | ||