FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/identcpu.c
1 /* $NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $ */
2
3 /*-
4 * Copyright (c) 1995 Mark Brinicombe.
5 * Copyright (c) 1995 Brini.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Brini.
19 * 4. The name of the company nor the name of the author may be used to
20 * endorse or promote products derived from this software without specific
21 * prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * RiscBSD kernel project
36 *
37 * cpu.c
38 *
39 * Probing and configuration for the master CPU
40 *
41 * Created : 10/10/95
42 */
43
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
46 #include <sys/systm.h>
47 #include <sys/param.h>
48 #include <sys/malloc.h>
49 #include <sys/time.h>
50 #include <sys/proc.h>
51 #include <sys/conf.h>
52 #include <sys/kernel.h>
53 #include <sys/sysctl.h>
54 #include <machine/cpu.h>
55
56 #include <machine/cpuconf.h>
57
58 char machine[] = "arm";
59
60 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
61 machine, 0, "Machine class");
62 enum cpu_class {
63 CPU_CLASS_NONE,
64 CPU_CLASS_ARM2,
65 CPU_CLASS_ARM2AS,
66 CPU_CLASS_ARM3,
67 CPU_CLASS_ARM6,
68 CPU_CLASS_ARM7,
69 CPU_CLASS_ARM7TDMI,
70 CPU_CLASS_ARM8,
71 CPU_CLASS_ARM9TDMI,
72 CPU_CLASS_ARM9ES,
73 CPU_CLASS_ARM9EJS,
74 CPU_CLASS_ARM10E,
75 CPU_CLASS_ARM10EJ,
76 CPU_CLASS_SA1,
77 CPU_CLASS_XSCALE,
78 CPU_CLASS_ARM11J
79 };
80
81 static const char * const generic_steppings[16] = {
82 "rev 0", "rev 1", "rev 2", "rev 3",
83 "rev 4", "rev 5", "rev 6", "rev 7",
84 "rev 8", "rev 9", "rev 10", "rev 11",
85 "rev 12", "rev 13", "rev 14", "rev 15",
86 };
87
88 static const char * const sa110_steppings[16] = {
89 "rev 0", "step J", "step K", "step S",
90 "step T", "rev 5", "rev 6", "rev 7",
91 "rev 8", "rev 9", "rev 10", "rev 11",
92 "rev 12", "rev 13", "rev 14", "rev 15",
93 };
94
95 static const char * const sa1100_steppings[16] = {
96 "rev 0", "step B", "step C", "rev 3",
97 "rev 4", "rev 5", "rev 6", "rev 7",
98 "step D", "step E", "rev 10" "step G",
99 "rev 12", "rev 13", "rev 14", "rev 15",
100 };
101
102 static const char * const sa1110_steppings[16] = {
103 "step A-0", "rev 1", "rev 2", "rev 3",
104 "step B-0", "step B-1", "step B-2", "step B-3",
105 "step B-4", "step B-5", "rev 10", "rev 11",
106 "rev 12", "rev 13", "rev 14", "rev 15",
107 };
108
109 static const char * const ixp12x0_steppings[16] = {
110 "(IXP1200 step A)", "(IXP1200 step B)",
111 "rev 2", "(IXP1200 step C)",
112 "(IXP1200 step D)", "(IXP1240/1250 step A)",
113 "(IXP1240 step B)", "(IXP1250 step B)",
114 "rev 8", "rev 9", "rev 10", "rev 11",
115 "rev 12", "rev 13", "rev 14", "rev 15",
116 };
117
118 static const char * const xscale_steppings[16] = {
119 "step A-0", "step A-1", "step B-0", "step C-0",
120 "step D-0", "rev 5", "rev 6", "rev 7",
121 "rev 8", "rev 9", "rev 10", "rev 11",
122 "rev 12", "rev 13", "rev 14", "rev 15",
123 };
124
125 static const char * const i80219_steppings[16] = {
126 "step A-0", "rev 1", "rev 2", "rev 3",
127 "rev 4", "rev 5", "rev 6", "rev 7",
128 "rev 8", "rev 9", "rev 10", "rev 11",
129 "rev 12", "rev 13", "rev 14", "rev 15",
130 };
131
132 static const char * const i80321_steppings[16] = {
133 "step A-0", "step B-0", "rev 2", "rev 3",
134 "rev 4", "rev 5", "rev 6", "rev 7",
135 "rev 8", "rev 9", "rev 10", "rev 11",
136 "rev 12", "rev 13", "rev 14", "rev 15",
137 };
138
139 static const char * const i81342_steppings[16] = {
140 "step A-0", "rev 1", "rev 2", "rev 3",
141 "rev 4", "rev 5", "rev 6", "rev 7",
142 "rev 8", "rev 9", "rev 10", "rev 11",
143 "rev 12", "rev 13", "rev 14", "rev 15",
144 };
145
146 /* Steppings for PXA2[15]0 */
147 static const char * const pxa2x0_steppings[16] = {
148 "step A-0", "step A-1", "step B-0", "step B-1",
149 "step B-2", "step C-0", "rev 6", "rev 7",
150 "rev 8", "rev 9", "rev 10", "rev 11",
151 "rev 12", "rev 13", "rev 14", "rev 15",
152 };
153
154 /* Steppings for PXA255/26x.
155 * rev 5: PXA26x B0, rev 6: PXA255 A0
156 */
157 static const char * const pxa255_steppings[16] = {
158 "rev 0", "rev 1", "rev 2", "step A-0",
159 "rev 4", "step B-0", "step A-0", "rev 7",
160 "rev 8", "rev 9", "rev 10", "rev 11",
161 "rev 12", "rev 13", "rev 14", "rev 15",
162 };
163
164 /* Stepping for PXA27x */
165 static const char * const pxa27x_steppings[16] = {
166 "step A-0", "step A-1", "step B-0", "step B-1",
167 "step C-0", "rev 5", "rev 6", "rev 7",
168 "rev 8", "rev 9", "rev 10", "rev 11",
169 "rev 12", "rev 13", "rev 14", "rev 15",
170 };
171
172 static const char * const ixp425_steppings[16] = {
173 "step 0 (A0)", "rev 1 (ARMv5TE)", "rev 2", "rev 3",
174 "rev 4", "rev 5", "rev 6", "rev 7",
175 "rev 8", "rev 9", "rev 10", "rev 11",
176 "rev 12", "rev 13", "rev 14", "rev 15",
177 };
178
179 struct cpuidtab {
180 u_int32_t cpuid;
181 enum cpu_class cpu_class;
182 const char *cpu_name;
183 const char * const *cpu_steppings;
184 };
185
186 const struct cpuidtab cpuids[] = {
187 { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2",
188 generic_steppings },
189 { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250",
190 generic_steppings },
191
192 { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3",
193 generic_steppings },
194
195 { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600",
196 generic_steppings },
197 { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610",
198 generic_steppings },
199 { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620",
200 generic_steppings },
201
202 { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700",
203 generic_steppings },
204 { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710",
205 generic_steppings },
206 { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500",
207 generic_steppings },
208 { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a",
209 generic_steppings },
210 { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE",
211 generic_steppings },
212 { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T",
213 generic_steppings },
214 { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T",
215 generic_steppings },
216 { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
217 generic_steppings },
218 { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
219 generic_steppings },
220
221 { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810",
222 generic_steppings },
223
224 { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T",
225 generic_steppings },
226 { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T",
227 generic_steppings },
228 { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T",
229 generic_steppings },
230 { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S",
231 generic_steppings },
232 { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T",
233 generic_steppings },
234 { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S",
235 generic_steppings },
236 { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S",
237 generic_steppings },
238 { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S",
239 generic_steppings },
240 { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T",
241 generic_steppings },
242
243 { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E",
244 generic_steppings },
245 { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S",
246 generic_steppings },
247 { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S",
248 generic_steppings },
249
250 { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110",
251 sa110_steppings },
252 { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100",
253 sa1100_steppings },
254 { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110",
255 sa1110_steppings },
256
257 { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200",
258 ixp12x0_steppings },
259
260 { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200",
261 xscale_steppings },
262
263 { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz",
264 i80321_steppings },
265 { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz",
266 i80321_steppings },
267 { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz",
268 i80321_steppings },
269 { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz",
270 i80321_steppings },
271
272 { CPU_ID_81342, CPU_CLASS_XSCALE, "i81342",
273 i81342_steppings },
274
275 { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz",
276 i80219_steppings },
277 { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz",
278 i80219_steppings },
279
280 { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x",
281 pxa27x_steppings },
282 { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250",
283 pxa2x0_steppings },
284 { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210",
285 pxa2x0_steppings },
286 { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250",
287 pxa2x0_steppings },
288 { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210",
289 pxa2x0_steppings },
290 { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255",
291 pxa255_steppings },
292 { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210",
293 pxa2x0_steppings },
294
295 { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz",
296 ixp425_steppings },
297 { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz",
298 ixp425_steppings },
299 { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz",
300 ixp425_steppings },
301
302 { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S",
303 generic_steppings },
304 { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S R1",
305 generic_steppings },
306
307 { 0, CPU_CLASS_NONE, NULL, NULL }
308 };
309
310 struct cpu_classtab {
311 const char *class_name;
312 const char *class_option;
313 };
314
315 const struct cpu_classtab cpu_classes[] = {
316 { "unknown", NULL }, /* CPU_CLASS_NONE */
317 { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */
318 { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */
319 { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */
320 { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */
321 { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */
322 { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */
323 { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */
324 { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */
325 { "ARM9E-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9ES */
326 { "ARM9EJ-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9EJS */
327 { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */
328 { "ARM10EJ", "CPU_ARM10" }, /* CPU_CLASS_ARM10EJ */
329 { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */
330 { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */
331 { "ARM11J", "CPU_ARM11" }, /* CPU_CLASS_ARM11J */
332 };
333
334 /*
335 * Report the type of the specified arm processor. This uses the generic and
336 * arm specific information in the cpu structure to identify the processor.
337 * The remaining fields in the cpu structure are filled in appropriately.
338 */
339
340 static const char * const wtnames[] = {
341 "write-through",
342 "write-back",
343 "write-back",
344 "**unknown 3**",
345 "**unknown 4**",
346 "write-back-locking", /* XXX XScale-specific? */
347 "write-back-locking-A",
348 "write-back-locking-B",
349 "**unknown 8**",
350 "**unknown 9**",
351 "**unknown 10**",
352 "**unknown 11**",
353 "**unknown 12**",
354 "**unknown 13**",
355 "write-back-locking-C",
356 "**unknown 15**",
357 };
358
359 void setPQL2(int *const size, int *const ways);
360
361 void
362 setPQL2(int *const size, int *const ways)
363 {
364 return;
365 }
366
367
368 extern int ctrl;
369 void
370 identify_arm_cpu(void)
371 {
372 u_int cpuid;
373 enum cpu_class cpu_class = CPU_CLASS_NONE;
374 int i;
375
376 cpuid = cpu_id();
377
378 if (cpuid == 0) {
379 printf("Processor failed probe - no CPU ID\n");
380 return;
381 }
382
383 for (i = 0; cpuids[i].cpuid != 0; i++)
384 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
385 cpu_class = cpuids[i].cpu_class;
386 printf("CPU: %s %s (%s core)\n",
387 cpuids[i].cpu_name,
388 cpuids[i].cpu_steppings[cpuid &
389 CPU_ID_REVISION_MASK],
390 cpu_classes[cpu_class].class_name);
391 break;
392 }
393 if (cpuids[i].cpuid == 0)
394 printf("unknown CPU (ID = 0x%x)\n", cpuid);
395
396 printf(" ");
397 switch (cpu_class) {
398 case CPU_CLASS_ARM6:
399 case CPU_CLASS_ARM7:
400 case CPU_CLASS_ARM7TDMI:
401 case CPU_CLASS_ARM8:
402 if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
403 printf(" IDC disabled");
404 else
405 printf(" IDC enabled");
406 break;
407 case CPU_CLASS_ARM9TDMI:
408 case CPU_CLASS_ARM9ES:
409 case CPU_CLASS_ARM9EJS:
410 case CPU_CLASS_ARM10E:
411 case CPU_CLASS_ARM10EJ:
412 case CPU_CLASS_SA1:
413 case CPU_CLASS_XSCALE:
414 case CPU_CLASS_ARM11J:
415 if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
416 printf(" DC disabled");
417 else
418 printf(" DC enabled");
419 if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
420 printf(" IC disabled");
421 else
422 printf(" IC enabled");
423 #ifdef CPU_XSCALE_81342
424 if ((ctrl & CPU_CONTROL_L2_ENABLE) == 0)
425 printf(" L2 disabled");
426 else
427 printf(" L2 enabled");
428 #endif
429 break;
430 default:
431 break;
432 }
433 if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
434 printf(" WB disabled");
435 else
436 printf(" WB enabled");
437
438 if (ctrl & CPU_CONTROL_LABT_ENABLE)
439 printf(" LABT");
440 else
441 printf(" EABT");
442
443 if (ctrl & CPU_CONTROL_BPRD_ENABLE)
444 printf(" branch prediction enabled");
445
446 printf("\n");
447 /* Print cache info. */
448 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
449 return;
450
451 if (arm_pcache_unified) {
452 printf(" %dKB/%dB %d-way %s unified cache\n",
453 arm_pdcache_size / 1024,
454 arm_pdcache_line_size, arm_pdcache_ways,
455 wtnames[arm_pcache_type]);
456 } else {
457 printf(" %dKB/%dB %d-way Instruction cache\n",
458 arm_picache_size / 1024,
459 arm_picache_line_size, arm_picache_ways);
460 printf(" %dKB/%dB %d-way %s Data cache\n",
461 arm_pdcache_size / 1024,
462 arm_pdcache_line_size, arm_pdcache_ways,
463 wtnames[arm_pcache_type]);
464 }
465 }
466
Cache object: a590820b1ec429ba11131f75b7fc1ea1
|