Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
1da177e4 LT |
7 | #include <linux/kernel.h> |
8 | #include <linux/init.h> | |
9 | #include <linux/smp.h> | |
10 | #include <linux/threads.h> | |
11 | #include <asm/oplib.h> | |
12 | #include <asm/page.h> | |
13 | #include <asm/head.h> | |
14 | #include <asm/psr.h> | |
15 | #include <asm/mbus.h> | |
16 | #include <asm/cpudata.h> | |
17 | ||
53ae3419 SR |
18 | #include "kernel.h" |
19 | ||
1da177e4 LT |
20 | DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; |
21 | ||
2bf05fa0 | 22 | struct cpu_info { |
8a563f01 | 23 | int psr_vers; |
2bf05fa0 | 24 | const char *name; |
1da177e4 LT |
25 | }; |
26 | ||
2bf05fa0 | 27 | struct fpu_info { |
8a563f01 | 28 | int fp_vers; |
2bf05fa0 | 29 | const char *name; |
1da177e4 LT |
30 | }; |
31 | ||
2bf05fa0 SR |
32 | #define NOCPU 8 |
33 | #define NOFPU 8 | |
34 | ||
35 | struct manufacturer_info { | |
36 | int psr_impl; | |
37 | struct cpu_info cpu_info[NOCPU]; | |
38 | struct fpu_info fpu_info[NOFPU]; | |
1da177e4 LT |
39 | }; |
40 | ||
2bf05fa0 SR |
41 | #define CPU(ver, _name) \ |
42 | { .psr_vers = ver, .name = _name } | |
43 | ||
44 | #define FPU(ver, _name) \ | |
45 | { .fp_vers = ver, .name = _name } | |
1da177e4 | 46 | |
2bf05fa0 SR |
47 | static const struct manufacturer_info __initconst manufacturer_info[] = { |
48 | { | |
49 | 0, | |
8a563f01 | 50 | /* Sun4/100, 4/200, SLC */ |
2bf05fa0 SR |
51 | .cpu_info = { |
52 | CPU(0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"), | |
53 | /* borned STP1012PGA */ | |
54 | CPU(4, "Fujitsu MB86904"), | |
55 | CPU(5, "Fujitsu TurboSparc MB86907"), | |
56 | CPU(-1, NULL) | |
57 | }, | |
58 | .fpu_info = { | |
59 | FPU(0, "Fujitsu MB86910 or Weitek WTL1164/5"), | |
60 | FPU(1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"), | |
61 | FPU(2, "LSI Logic L64802 or Texas Instruments ACT8847"), | |
62 | /* SparcStation SLC, SparcStation1 */ | |
63 | FPU(3, "Weitek WTL3170/2"), | |
64 | /* SPARCstation-5 */ | |
65 | FPU(4, "Lsi Logic/Meiko L64804 or compatible"), | |
66 | FPU(-1, NULL) | |
67 | } | |
68 | },{ | |
69 | 1, | |
70 | .cpu_info = { | |
71 | /* SparcStation2, SparcServer 490 & 690 */ | |
72 | CPU(0, "LSI Logic Corporation - L64811"), | |
73 | /* SparcStation2 */ | |
74 | CPU(1, "Cypress/ROSS CY7C601"), | |
75 | /* Embedded controller */ | |
76 | CPU(3, "Cypress/ROSS CY7C611"), | |
77 | /* Ross Technologies HyperSparc */ | |
78 | CPU(0xf, "ROSS HyperSparc RT620"), | |
79 | CPU(0xe, "ROSS HyperSparc RT625 or RT626"), | |
80 | CPU(-1, NULL) | |
81 | }, | |
82 | .fpu_info = { | |
83 | FPU(0, "ROSS HyperSparc combined IU/FPU"), | |
84 | FPU(1, "Lsi Logic L64814"), | |
85 | FPU(2, "Texas Instruments TMS390-C602A"), | |
86 | FPU(3, "Cypress CY7C602 FPU"), | |
87 | FPU(-1, NULL) | |
88 | } | |
89 | },{ | |
90 | 2, | |
91 | .cpu_info = { | |
92 | /* ECL Implementation, CRAY S-MP Supercomputer... AIEEE! */ | |
93 | /* Someone please write the code to support this beast! ;) */ | |
94 | CPU(0, "Bipolar Integrated Technology - B5010"), | |
95 | CPU(-1, NULL) | |
96 | }, | |
97 | .fpu_info = { | |
98 | FPU(-1, NULL) | |
99 | } | |
100 | },{ | |
101 | 3, | |
102 | .cpu_info = { | |
103 | CPU(0, "LSI Logic Corporation - unknown-type"), | |
104 | CPU(-1, NULL) | |
105 | }, | |
106 | .fpu_info = { | |
107 | FPU(-1, NULL) | |
108 | } | |
109 | },{ | |
110 | 4, | |
111 | .cpu_info = { | |
112 | CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), | |
113 | /* SparcClassic -- borned STP1010TAB-50*/ | |
114 | CPU(1, "Texas Instruments, Inc. - MicroSparc"), | |
115 | CPU(2, "Texas Instruments, Inc. - MicroSparc II"), | |
116 | CPU(3, "Texas Instruments, Inc. - SuperSparc 51"), | |
117 | CPU(4, "Texas Instruments, Inc. - SuperSparc 61"), | |
118 | CPU(5, "Texas Instruments, Inc. - unknown"), | |
119 | CPU(-1, NULL) | |
120 | }, | |
121 | .fpu_info = { | |
122 | /* SuperSparc 50 module */ | |
123 | FPU(0, "SuperSparc on-chip FPU"), | |
124 | /* SparcClassic */ | |
125 | FPU(4, "TI MicroSparc on chip FPU"), | |
126 | FPU(-1, NULL) | |
127 | } | |
128 | },{ | |
129 | 5, | |
130 | .cpu_info = { | |
131 | CPU(0, "Matsushita - MN10501"), | |
132 | CPU(-1, NULL) | |
133 | }, | |
134 | .fpu_info = { | |
135 | FPU(0, "Matsushita MN10501"), | |
136 | FPU(-1, NULL) | |
137 | } | |
138 | },{ | |
139 | 6, | |
140 | .cpu_info = { | |
141 | CPU(0, "Philips Corporation - unknown"), | |
142 | CPU(-1, NULL) | |
143 | }, | |
144 | .fpu_info = { | |
145 | FPU(-1, NULL) | |
146 | } | |
147 | },{ | |
148 | 7, | |
149 | .cpu_info = { | |
150 | CPU(0, "Harvest VLSI Design Center, Inc. - unknown"), | |
151 | CPU(-1, NULL) | |
152 | }, | |
153 | .fpu_info = { | |
154 | FPU(-1, NULL) | |
155 | } | |
156 | },{ | |
157 | 8, | |
158 | .cpu_info = { | |
159 | CPU(0, "Systems and Processes Engineering Corporation (SPEC)"), | |
160 | CPU(-1, NULL) | |
161 | }, | |
162 | .fpu_info = { | |
163 | FPU(-1, NULL) | |
164 | } | |
165 | },{ | |
166 | 9, | |
167 | .cpu_info = { | |
168 | /* Gallium arsenide 200MHz, BOOOOGOOOOMIPS!!! */ | |
169 | CPU(0, "Fujitsu or Weitek Power-UP"), | |
170 | CPU(1, "Fujitsu or Weitek Power-UP"), | |
171 | CPU(2, "Fujitsu or Weitek Power-UP"), | |
172 | CPU(3, "Fujitsu or Weitek Power-UP"), | |
173 | CPU(-1, NULL) | |
174 | }, | |
175 | .fpu_info = { | |
176 | FPU(3, "Fujitsu or Weitek on-chip FPU"), | |
177 | FPU(-1, NULL) | |
178 | } | |
179 | }}; | |
1da177e4 | 180 | |
2bf05fa0 SR |
181 | /* In order to get the fpu type correct, you need to take the IDPROM's |
182 | * machine type value into consideration too. I will fix this. | |
183 | */ | |
1da177e4 | 184 | |
53ae3419 SR |
185 | const char *sparc_cpu_type; |
186 | const char *sparc_fpu_type; | |
1da177e4 LT |
187 | |
188 | unsigned int fsr_storage; | |
189 | ||
2bf05fa0 | 190 | static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) |
1da177e4 | 191 | { |
2bf05fa0 SR |
192 | sparc_cpu_type = NULL; |
193 | sparc_fpu_type = NULL; | |
194 | if (psr_impl < ARRAY_SIZE(manufacturer_info)) | |
195 | { | |
196 | const struct cpu_info *cpu; | |
197 | const struct fpu_info *fpu; | |
198 | ||
199 | cpu = &manufacturer_info[psr_impl].cpu_info[0]; | |
200 | while (cpu->psr_vers != -1) | |
201 | { | |
202 | if (cpu->psr_vers == psr_vers) { | |
203 | sparc_cpu_type = cpu->name; | |
204 | sparc_fpu_type = "No FPU"; | |
205 | break; | |
206 | } | |
207 | cpu++; | |
208 | } | |
209 | fpu = &manufacturer_info[psr_impl].fpu_info[0]; | |
210 | while (fpu->fp_vers != -1) | |
211 | { | |
212 | if (fpu->fp_vers == fpu_vers) { | |
213 | sparc_fpu_type = fpu->name; | |
1da177e4 LT |
214 | break; |
215 | } | |
2bf05fa0 SR |
216 | fpu++; |
217 | } | |
1da177e4 | 218 | } |
2bf05fa0 | 219 | if (sparc_cpu_type == NULL) |
6c6bd8b6 SR |
220 | { |
221 | printk(KERN_ERR "CPU: Unknown chip, impl[0x%x] vers[0x%x]\n", | |
8a563f01 | 222 | psr_impl, psr_vers); |
6c6bd8b6 SR |
223 | sparc_cpu_type = "Unknown CPU"; |
224 | } | |
2bf05fa0 SR |
225 | if (sparc_fpu_type == NULL) |
226 | { | |
6c6bd8b6 | 227 | printk(KERN_ERR "FPU: Unknown chip, impl[0x%x] vers[0x%x]\n", |
8a563f01 | 228 | psr_impl, fpu_vers); |
6c6bd8b6 | 229 | sparc_fpu_type = "Unknown FPU"; |
1da177e4 LT |
230 | } |
231 | } | |
2bf05fa0 SR |
232 | |
233 | void __cpuinit cpu_probe(void) | |
234 | { | |
235 | int psr_impl, psr_vers, fpu_vers; | |
236 | int psr; | |
237 | ||
238 | psr_impl = ((get_psr() >> 28) & 0xf); | |
239 | psr_vers = ((get_psr() >> 24) & 0xf); | |
240 | ||
241 | psr = get_psr(); | |
242 | put_psr(psr | PSR_EF); | |
243 | fpu_vers = ((get_fsr() >> 17) & 0x7); | |
244 | put_psr(psr); | |
245 | ||
246 | set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers); | |
247 | } |