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
360 extern int ctrl;
361 void
362 identify_arm_cpu(void)
363 {
364 u_int cpuid;
365 enum cpu_class cpu_class = CPU_CLASS_NONE;
366 int i;
367
368 cpuid = cpu_id();
369
370 if (cpuid == 0) {
371 printf("Processor failed probe - no CPU ID\n");
372 return;
373 }
374
375 for (i = 0; cpuids[i].cpuid != 0; i++)
376 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
377 cpu_class = cpuids[i].cpu_class;
378 printf("CPU: %s %s (%s core)\n",
379 cpuids[i].cpu_name,
380 cpuids[i].cpu_steppings[cpuid &
381 CPU_ID_REVISION_MASK],
382 cpu_classes[cpu_class].class_name);
383 break;
384 }
385 if (cpuids[i].cpuid == 0)
386 printf("unknown CPU (ID = 0x%x)\n", cpuid);
387
388 printf(" ");
389 switch (cpu_class) {
390 case CPU_CLASS_ARM6:
391 case CPU_CLASS_ARM7:
392 case CPU_CLASS_ARM7TDMI:
393 case CPU_CLASS_ARM8:
394 if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
395 printf(" IDC disabled");
396 else
397 printf(" IDC enabled");
398 break;
399 case CPU_CLASS_ARM9TDMI:
400 case CPU_CLASS_ARM9ES:
401 case CPU_CLASS_ARM9EJS:
402 case CPU_CLASS_ARM10E:
403 case CPU_CLASS_ARM10EJ:
404 case CPU_CLASS_SA1:
405 case CPU_CLASS_XSCALE:
406 case CPU_CLASS_ARM11J:
407 if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
408 printf(" DC disabled");
409 else
410 printf(" DC enabled");
411 if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
412 printf(" IC disabled");
413 else
414 printf(" IC enabled");
415 #ifdef CPU_XSCALE_81342
416 if ((ctrl & CPU_CONTROL_L2_ENABLE) == 0)
417 printf(" L2 disabled");
418 else
419 printf(" L2 enabled");
420 #endif
421 break;
422 default:
423 break;
424 }
425 if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
426 printf(" WB disabled");
427 else
428 printf(" WB enabled");
429
430 if (ctrl & CPU_CONTROL_LABT_ENABLE)
431 printf(" LABT");
432 else
433 printf(" EABT");
434
435 if (ctrl & CPU_CONTROL_BPRD_ENABLE)
436 printf(" branch prediction enabled");
437
438 printf("\n");
439 /* Print cache info. */
440 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
441 return;
442
443 if (arm_pcache_unified) {
444 printf(" %dKB/%dB %d-way %s unified cache\n",
445 arm_pdcache_size / 1024,
446 arm_pdcache_line_size, arm_pdcache_ways,
447 wtnames[arm_pcache_type]);
448 } else {
449 printf(" %dKB/%dB %d-way Instruction cache\n",
450 arm_picache_size / 1024,
451 arm_picache_line_size, arm_picache_ways);
452 printf(" %dKB/%dB %d-way %s Data cache\n",
453 arm_pdcache_size / 1024,
454 arm_pdcache_line_size, arm_pdcache_ways,
455 wtnames[arm_pcache_type]);
456 }
457 }
458
Cache object: 6c647a64e48536c9c53be7cd958ca718
|