]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/identcpu.c
Merge ath again (addition of wisoc files).
[FreeBSD/FreeBSD.git] / 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