]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/arm/arm/identcpu.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 #include <machine/endian.h>
56
57 #include <machine/cpuconf.h>
58 #include <machine/md_var.h>
59
60 char machine[] = "arm";
61
62 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
63         machine, 0, "Machine class");
64
65 static const char * const generic_steppings[16] = {
66         "rev 0",        "rev 1",        "rev 2",        "rev 3",
67         "rev 4",        "rev 5",        "rev 6",        "rev 7",
68         "rev 8",        "rev 9",        "rev 10",       "rev 11",
69         "rev 12",       "rev 13",       "rev 14",       "rev 15",
70 };
71
72 static const char * const sa110_steppings[16] = {
73         "rev 0",        "step J",       "step K",       "step S",
74         "step T",       "rev 5",        "rev 6",        "rev 7",
75         "rev 8",        "rev 9",        "rev 10",       "rev 11",
76         "rev 12",       "rev 13",       "rev 14",       "rev 15",
77 };
78
79 static const char * const sa1100_steppings[16] = {
80         "rev 0",        "step B",       "step C",       "rev 3",
81         "rev 4",        "rev 5",        "rev 6",        "rev 7",
82         "step D",       "step E",       "rev 10"        "step G",
83         "rev 12",       "rev 13",       "rev 14",       "rev 15",
84 };
85
86 static const char * const sa1110_steppings[16] = {
87         "step A-0",     "rev 1",        "rev 2",        "rev 3",
88         "step B-0",     "step B-1",     "step B-2",     "step B-3",
89         "step B-4",     "step B-5",     "rev 10",       "rev 11",
90         "rev 12",       "rev 13",       "rev 14",       "rev 15",
91 };
92
93 static const char * const ixp12x0_steppings[16] = {
94         "(IXP1200 step A)",             "(IXP1200 step B)",
95         "rev 2",                        "(IXP1200 step C)",
96         "(IXP1200 step D)",             "(IXP1240/1250 step A)",
97         "(IXP1240 step B)",             "(IXP1250 step B)",
98         "rev 8",        "rev 9",        "rev 10",       "rev 11",
99         "rev 12",       "rev 13",       "rev 14",       "rev 15",
100 };
101
102 static const char * const xscale_steppings[16] = {
103         "step A-0",     "step A-1",     "step B-0",     "step C-0",
104         "step D-0",     "rev 5",        "rev 6",        "rev 7",
105         "rev 8",        "rev 9",        "rev 10",       "rev 11",
106         "rev 12",       "rev 13",       "rev 14",       "rev 15",
107 };
108
109 static const char * const i80219_steppings[16] = {
110         "step A-0",     "rev 1",        "rev 2",        "rev 3",
111         "rev 4",        "rev 5",        "rev 6",        "rev 7",
112         "rev 8",        "rev 9",        "rev 10",       "rev 11",
113         "rev 12",       "rev 13",       "rev 14",       "rev 15",
114 };
115
116 static const char * const i80321_steppings[16] = {
117         "step A-0",     "step B-0",     "rev 2",        "rev 3",
118         "rev 4",        "rev 5",        "rev 6",        "rev 7",
119         "rev 8",        "rev 9",        "rev 10",       "rev 11",
120         "rev 12",       "rev 13",       "rev 14",       "rev 15",
121 };
122
123 static const char * const i81342_steppings[16] = {
124         "step A-0",     "rev 1",        "rev 2",        "rev 3",
125         "rev 4",        "rev 5",        "rev 6",        "rev 7",
126         "rev 8",        "rev 9",        "rev 10",       "rev 11",
127         "rev 12",       "rev 13",       "rev 14",       "rev 15",
128 };
129
130 /* Steppings for PXA2[15]0 */
131 static const char * const pxa2x0_steppings[16] = {
132         "step A-0",     "step A-1",     "step B-0",     "step B-1",
133         "step B-2",     "step C-0",     "rev 6",        "rev 7",
134         "rev 8",        "rev 9",        "rev 10",       "rev 11",
135         "rev 12",       "rev 13",       "rev 14",       "rev 15",
136 };
137
138 /* Steppings for PXA255/26x.
139  * rev 5: PXA26x B0, rev 6: PXA255 A0
140  */
141 static const char * const pxa255_steppings[16] = {
142         "rev 0",        "rev 1",        "rev 2",        "step A-0",
143         "rev 4",        "step B-0",     "step A-0",     "rev 7",
144         "rev 8",        "rev 9",        "rev 10",       "rev 11",
145         "rev 12",       "rev 13",       "rev 14",       "rev 15",
146 };
147
148 /* Stepping for PXA27x */
149 static const char * const pxa27x_steppings[16] = {
150         "step A-0",     "step A-1",     "step B-0",     "step B-1",
151         "step C-0",     "rev 5",        "rev 6",        "rev 7",
152         "rev 8",        "rev 9",        "rev 10",       "rev 11",
153         "rev 12",       "rev 13",       "rev 14",       "rev 15",
154 };
155
156 static const char * const ixp425_steppings[16] = {
157         "step 0 (A0)",  "rev 1 (ARMv5TE)", "rev 2",     "rev 3",
158         "rev 4",        "rev 5",        "rev 6",        "rev 7",
159         "rev 8",        "rev 9",        "rev 10",       "rev 11",
160         "rev 12",       "rev 13",       "rev 14",       "rev 15",
161 };
162
163 struct cpuidtab {
164         u_int32_t       cpuid;
165         enum            cpu_class cpu_class;
166         const char      *cpu_name;
167         const char * const *cpu_steppings;
168 };
169
170 const struct cpuidtab cpuids[] = {
171         { CPU_ID_ARM2,          CPU_CLASS_ARM2,         "ARM2",
172           generic_steppings },
173         { CPU_ID_ARM250,        CPU_CLASS_ARM2AS,       "ARM250",
174           generic_steppings },
175
176         { CPU_ID_ARM3,          CPU_CLASS_ARM3,         "ARM3",
177           generic_steppings },
178
179         { CPU_ID_ARM600,        CPU_CLASS_ARM6,         "ARM600",
180           generic_steppings },
181         { CPU_ID_ARM610,        CPU_CLASS_ARM6,         "ARM610",
182           generic_steppings },
183         { CPU_ID_ARM620,        CPU_CLASS_ARM6,         "ARM620",
184           generic_steppings },
185
186         { CPU_ID_ARM700,        CPU_CLASS_ARM7,         "ARM700",
187           generic_steppings },
188         { CPU_ID_ARM710,        CPU_CLASS_ARM7,         "ARM710",
189           generic_steppings },
190         { CPU_ID_ARM7500,       CPU_CLASS_ARM7,         "ARM7500",
191           generic_steppings },
192         { CPU_ID_ARM710A,       CPU_CLASS_ARM7,         "ARM710a",
193           generic_steppings },
194         { CPU_ID_ARM7500FE,     CPU_CLASS_ARM7,         "ARM7500FE",
195           generic_steppings },
196         { CPU_ID_ARM710T,       CPU_CLASS_ARM7TDMI,     "ARM710T",
197           generic_steppings },
198         { CPU_ID_ARM720T,       CPU_CLASS_ARM7TDMI,     "ARM720T",
199           generic_steppings },
200         { CPU_ID_ARM740T8K,     CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
201           generic_steppings },
202         { CPU_ID_ARM740T4K,     CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
203           generic_steppings },
204
205         { CPU_ID_ARM810,        CPU_CLASS_ARM8,         "ARM810",
206           generic_steppings },
207
208         { CPU_ID_ARM920T,       CPU_CLASS_ARM9TDMI,     "ARM920T",
209           generic_steppings },
210         { CPU_ID_ARM920T_ALT,   CPU_CLASS_ARM9TDMI,     "ARM920T",
211           generic_steppings },
212         { CPU_ID_ARM922T,       CPU_CLASS_ARM9TDMI,     "ARM922T",
213           generic_steppings },
214         { CPU_ID_ARM926EJS,     CPU_CLASS_ARM9EJS,      "ARM926EJ-S",
215           generic_steppings },
216         { CPU_ID_ARM940T,       CPU_CLASS_ARM9TDMI,     "ARM940T",
217           generic_steppings },
218         { CPU_ID_ARM946ES,      CPU_CLASS_ARM9ES,       "ARM946E-S",
219           generic_steppings },
220         { CPU_ID_ARM966ES,      CPU_CLASS_ARM9ES,       "ARM966E-S",
221           generic_steppings },
222         { CPU_ID_ARM966ESR1,    CPU_CLASS_ARM9ES,       "ARM966E-S",
223           generic_steppings },
224         { CPU_ID_FA526,         CPU_CLASS_ARM9TDMI,     "FA526",
225           generic_steppings },
226         { CPU_ID_FA626TE,       CPU_CLASS_ARM9ES,       "FA626TE",
227           generic_steppings },
228
229         { CPU_ID_TI925T,        CPU_CLASS_ARM9TDMI,     "TI ARM925T",
230           generic_steppings },
231
232         { CPU_ID_ARM1020E,      CPU_CLASS_ARM10E,       "ARM1020E",
233           generic_steppings },
234         { CPU_ID_ARM1022ES,     CPU_CLASS_ARM10E,       "ARM1022E-S",
235           generic_steppings },
236         { CPU_ID_ARM1026EJS,    CPU_CLASS_ARM10EJ,      "ARM1026EJ-S",
237           generic_steppings },
238
239         { CPU_ID_CORTEXA7,      CPU_CLASS_CORTEXA,      "Cortex A7",
240           generic_steppings },
241         { CPU_ID_CORTEXA8R1,    CPU_CLASS_CORTEXA,      "Cortex A8-r1",
242           generic_steppings },
243         { CPU_ID_CORTEXA8R2,    CPU_CLASS_CORTEXA,      "Cortex A8-r2",
244           generic_steppings },
245         { CPU_ID_CORTEXA8R3,    CPU_CLASS_CORTEXA,      "Cortex A8-r3",
246           generic_steppings },
247         { CPU_ID_CORTEXA9R1,    CPU_CLASS_CORTEXA,      "Cortex A9-r1",
248           generic_steppings },
249         { CPU_ID_CORTEXA9R2,    CPU_CLASS_CORTEXA,      "Cortex A9-r2",
250           generic_steppings },
251         { CPU_ID_CORTEXA9R3,    CPU_CLASS_CORTEXA,      "Cortex A9-r3",
252           generic_steppings },
253         { CPU_ID_CORTEXA15,     CPU_CLASS_CORTEXA,      "Cortex A15",
254           generic_steppings },
255
256         { CPU_ID_SA110,         CPU_CLASS_SA1,          "SA-110",
257           sa110_steppings },
258         { CPU_ID_SA1100,        CPU_CLASS_SA1,          "SA-1100",
259           sa1100_steppings },
260         { CPU_ID_SA1110,        CPU_CLASS_SA1,          "SA-1110",
261           sa1110_steppings },
262
263         { CPU_ID_IXP1200,       CPU_CLASS_SA1,          "IXP1200",
264           ixp12x0_steppings },
265
266         { CPU_ID_80200,         CPU_CLASS_XSCALE,       "i80200",
267           xscale_steppings },
268
269         { CPU_ID_80321_400,     CPU_CLASS_XSCALE,       "i80321 400MHz",
270           i80321_steppings },
271         { CPU_ID_80321_600,     CPU_CLASS_XSCALE,       "i80321 600MHz",
272           i80321_steppings },
273         { CPU_ID_80321_400_B0,  CPU_CLASS_XSCALE,       "i80321 400MHz",
274           i80321_steppings },
275         { CPU_ID_80321_600_B0,  CPU_CLASS_XSCALE,       "i80321 600MHz",
276           i80321_steppings },
277
278         { CPU_ID_81342,         CPU_CLASS_XSCALE,       "i81342",
279           i81342_steppings },
280
281         { CPU_ID_80219_400,     CPU_CLASS_XSCALE,       "i80219 400MHz",
282           i80219_steppings },
283         { CPU_ID_80219_600,     CPU_CLASS_XSCALE,       "i80219 600MHz",
284           i80219_steppings },
285
286         { CPU_ID_PXA27X,        CPU_CLASS_XSCALE,       "PXA27x",
287           pxa27x_steppings },
288         { CPU_ID_PXA250A,       CPU_CLASS_XSCALE,       "PXA250",
289           pxa2x0_steppings },
290         { CPU_ID_PXA210A,       CPU_CLASS_XSCALE,       "PXA210",
291           pxa2x0_steppings },
292         { CPU_ID_PXA250B,       CPU_CLASS_XSCALE,       "PXA250",
293           pxa2x0_steppings },
294         { CPU_ID_PXA210B,       CPU_CLASS_XSCALE,       "PXA210",
295           pxa2x0_steppings },
296         { CPU_ID_PXA250C,       CPU_CLASS_XSCALE,       "PXA255",
297           pxa255_steppings },
298         { CPU_ID_PXA210C,       CPU_CLASS_XSCALE,       "PXA210",
299           pxa2x0_steppings },
300
301         { CPU_ID_IXP425_533,    CPU_CLASS_XSCALE,       "IXP425 533MHz",
302           ixp425_steppings },
303         { CPU_ID_IXP425_400,    CPU_CLASS_XSCALE,       "IXP425 400MHz",
304           ixp425_steppings },
305         { CPU_ID_IXP425_266,    CPU_CLASS_XSCALE,       "IXP425 266MHz",
306           ixp425_steppings },
307
308         /* XXX ixp435 steppings? */
309         { CPU_ID_IXP435,        CPU_CLASS_XSCALE,       "IXP435",
310           ixp425_steppings },
311
312         { CPU_ID_ARM1136JS,     CPU_CLASS_ARM11J,       "ARM1136J-S",
313           generic_steppings },
314         { CPU_ID_ARM1136JSR1,   CPU_CLASS_ARM11J,       "ARM1136J-S R1",
315           generic_steppings },
316         { CPU_ID_ARM1176JZS,    CPU_CLASS_ARM11J,       "ARM1176JZ-S",
317           generic_steppings },
318
319         { CPU_ID_MV88FR131,     CPU_CLASS_MARVELL,      "Feroceon 88FR131",
320           generic_steppings },
321
322         { CPU_ID_MV88FR571_VD,  CPU_CLASS_MARVELL,      "Feroceon 88FR571-VD",
323           generic_steppings },
324         { CPU_ID_MV88SV581X_V6, CPU_CLASS_MARVELL,      "Sheeva 88SV581x",
325           generic_steppings },
326         { CPU_ID_ARM_88SV581X_V6, CPU_CLASS_MARVELL,    "Sheeva 88SV581x",
327           generic_steppings },
328         { CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL,      "Sheeva 88SV581x",
329           generic_steppings },
330         { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL,    "Sheeva 88SV581x",
331           generic_steppings },
332         { CPU_ID_MV88SV584X_V6, CPU_CLASS_MARVELL,      "Sheeva 88SV584x",
333           generic_steppings },
334         { CPU_ID_ARM_88SV584X_V6, CPU_CLASS_MARVELL,    "Sheeva 88SV584x",
335           generic_steppings },
336         { CPU_ID_MV88SV584X_V7, CPU_CLASS_MARVELL,      "Sheeva 88SV584x",
337           generic_steppings },
338
339         { 0, CPU_CLASS_NONE, NULL, NULL }
340 };
341
342 struct cpu_classtab {
343         const char      *class_name;
344         const char      *class_option;
345 };
346
347 const struct cpu_classtab cpu_classes[] = {
348         { "unknown",    NULL },                 /* CPU_CLASS_NONE */
349         { "ARM2",       "CPU_ARM2" },           /* CPU_CLASS_ARM2 */
350         { "ARM2as",     "CPU_ARM250" },         /* CPU_CLASS_ARM2AS */
351         { "ARM3",       "CPU_ARM3" },           /* CPU_CLASS_ARM3 */
352         { "ARM6",       "CPU_ARM6" },           /* CPU_CLASS_ARM6 */
353         { "ARM7",       "CPU_ARM7" },           /* CPU_CLASS_ARM7 */
354         { "ARM7TDMI",   "CPU_ARM7TDMI" },       /* CPU_CLASS_ARM7TDMI */
355         { "ARM8",       "CPU_ARM8" },           /* CPU_CLASS_ARM8 */
356         { "ARM9TDMI",   "CPU_ARM9TDMI" },       /* CPU_CLASS_ARM9TDMI */
357         { "ARM9E-S",    "CPU_ARM9E" },          /* CPU_CLASS_ARM9ES */
358         { "ARM9EJ-S",   "CPU_ARM9E" },          /* CPU_CLASS_ARM9EJS */
359         { "ARM10E",     "CPU_ARM10" },          /* CPU_CLASS_ARM10E */
360         { "ARM10EJ",    "CPU_ARM10" },          /* CPU_CLASS_ARM10EJ */
361         { "Cortex-A",   "CPU_CORTEXA" },        /* CPU_CLASS_CORTEXA */
362         { "SA-1",       "CPU_SA110" },          /* CPU_CLASS_SA1 */
363         { "XScale",     "CPU_XSCALE_..." },     /* CPU_CLASS_XSCALE */
364         { "ARM11J",     "CPU_ARM11" },          /* CPU_CLASS_ARM11J */
365         { "Marvell",    "CPU_MARVELL" },        /* CPU_CLASS_MARVELL */
366 };
367
368 /*
369  * Report the type of the specified arm processor. This uses the generic and
370  * arm specific information in the cpu structure to identify the processor.
371  * The remaining fields in the cpu structure are filled in appropriately.
372  */
373
374 static const char * const wtnames[] = {
375         "write-through",
376         "write-back",
377         "write-back",
378         "**unknown 3**",
379         "**unknown 4**",
380         "write-back-locking",           /* XXX XScale-specific? */
381         "write-back-locking-A",
382         "write-back-locking-B",
383         "**unknown 8**",
384         "**unknown 9**",
385         "**unknown 10**",
386         "**unknown 11**",
387         "**unknown 12**",
388         "**unknown 13**",
389         "write-back-locking-C",
390         "**unknown 15**",
391 };
392
393 static void
394 print_enadis(int enadis, char *s)
395 {
396
397         printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
398 }
399
400 extern int ctrl;
401 enum cpu_class cpu_class = CPU_CLASS_NONE;
402
403 u_int cpu_pfr(int num)
404 {
405         u_int feat;
406
407         switch (num) {
408         case 0:
409                 __asm __volatile("mrc p15, 0, %0, c0, c1, 0"
410                     : "=r" (feat));
411                 break;
412         case 1:
413                 __asm __volatile("mrc p15, 0, %0, c0, c1, 1"
414                     : "=r" (feat));
415                 break;
416         default:
417                 panic("Processor Feature Register %d not implemented", num);
418                 break;
419         }
420
421         return (feat);
422 }
423
424 static
425 void identify_armv7(void)
426 {
427         u_int feature;
428
429         printf("Supported features:");
430         /* Get Processor Feature Register 0 */
431         feature = cpu_pfr(0);
432
433         if (feature & ARM_PFR0_ARM_ISA_MASK)
434                 printf(" ARM_ISA");
435
436         if (feature & ARM_PFR0_THUMB2)
437                 printf(" THUMB2");
438         else if (feature & ARM_PFR0_THUMB)
439                 printf(" THUMB");
440
441         if (feature & ARM_PFR0_JAZELLE_MASK)
442                 printf(" JAZELLE");
443
444         if (feature & ARM_PFR0_THUMBEE_MASK)
445                 printf(" THUMBEE");
446
447
448         /* Get Processor Feature Register 1 */
449         feature = cpu_pfr(1);
450
451         if (feature & ARM_PFR1_ARMV4_MASK)
452                 printf(" ARMv4");
453
454         if (feature & ARM_PFR1_SEC_EXT_MASK)
455                 printf(" Security_Ext");
456
457         if (feature & ARM_PFR1_MICROCTRL_MASK)
458                 printf(" M_profile");
459
460         printf("\n");
461 }
462
463 void
464 identify_arm_cpu(void)
465 {
466         u_int cpuid, reg, size, sets, ways;
467         u_int8_t type, linesize;
468         int i;
469
470         cpuid = cpu_id();
471
472         if (cpuid == 0) {
473                 printf("Processor failed probe - no CPU ID\n");
474                 return;
475         }
476
477         for (i = 0; cpuids[i].cpuid != 0; i++)
478                 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
479                         cpu_class = cpuids[i].cpu_class;
480                         printf("CPU: %s %s (%s core)\n",
481                             cpuids[i].cpu_name,
482                             cpuids[i].cpu_steppings[cpuid &
483                             CPU_ID_REVISION_MASK],
484                             cpu_classes[cpu_class].class_name);
485                         break;
486                 }
487         if (cpuids[i].cpuid == 0)
488                 printf("unknown CPU (ID = 0x%x)\n", cpuid);
489
490         printf(" ");
491
492         if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) {
493                 identify_armv7();
494         } else {
495                 if (ctrl & CPU_CONTROL_BEND_ENABLE)
496                         printf(" Big-endian");
497                 else
498                         printf(" Little-endian");
499
500                 switch (cpu_class) {
501                 case CPU_CLASS_ARM6:
502                 case CPU_CLASS_ARM7:
503                 case CPU_CLASS_ARM7TDMI:
504                 case CPU_CLASS_ARM8:
505                         print_enadis(ctrl & CPU_CONTROL_IDC_ENABLE, "IDC");
506                         break;
507                 case CPU_CLASS_ARM9TDMI:
508                 case CPU_CLASS_ARM9ES:
509                 case CPU_CLASS_ARM9EJS:
510                 case CPU_CLASS_ARM10E:
511                 case CPU_CLASS_ARM10EJ:
512                 case CPU_CLASS_SA1:
513                 case CPU_CLASS_XSCALE:
514                 case CPU_CLASS_ARM11J:
515                 case CPU_CLASS_MARVELL:
516                         print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
517                         print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
518 #ifdef CPU_XSCALE_81342
519                         print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2");
520 #endif
521 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
522                         i = sheeva_control_ext(0, 0);
523                         print_enadis(i & MV_WA_ENABLE, "WA");
524                         print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
525                         printf("\n ");
526                         print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
527                         print_enadis(i & MV_L2_ENABLE, "L2");
528                         print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
529                             "L2 prefetch");
530                         printf("\n ");
531 #endif
532                         break;
533                 default:
534                         break;
535                 }
536         }
537
538         print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
539         if (ctrl & CPU_CONTROL_LABT_ENABLE)
540                 printf(" LABT");
541         else
542                 printf(" EABT");
543
544         print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
545         printf("\n");
546
547         if (arm_cache_level) {
548                 printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
549                     arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
550                 i = 0;
551                 while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
552                         printf("Cache level %d: \n", i + 1);
553                         if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
554                             type == CACHE_SEP_CACHE) {
555                                 reg = arm_cache_type[2 * i];
556                                 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
557                                 sets = CPUV7_CT_xSIZE_SET(reg) + 1;
558                                 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
559                                 size = (ways * sets * linesize) / 1024;
560
561                                 if (type == CACHE_UNI_CACHE)
562                                         printf(" %dKB/%dB %d-way unified cache", size, linesize,ways);
563                                 else
564                                         printf(" %dKB/%dB %d-way data cache", size, linesize, ways);
565                                 if (reg & CPUV7_CT_CTYPE_WT)
566                                         printf(" WT");
567                                 if (reg & CPUV7_CT_CTYPE_WB)
568                                         printf(" WB");
569                                 if (reg & CPUV7_CT_CTYPE_RA)
570                                         printf(" Read-Alloc");
571                                 if (reg & CPUV7_CT_CTYPE_WA)
572                                         printf(" Write-Alloc");
573                                 printf("\n");
574                         }
575
576                         if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
577                                 reg = arm_cache_type[(2 * i) + 1];
578
579                                 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
580                                 sets = CPUV7_CT_xSIZE_SET(reg) + 1;
581                                 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
582                                 size = (ways * sets * linesize) / 1024;
583
584                                 printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways);
585                                 if (reg & CPUV7_CT_CTYPE_WT)
586                                         printf(" WT");
587                                 if (reg & CPUV7_CT_CTYPE_WB)
588                                         printf(" WB");
589                                 if (reg & CPUV7_CT_CTYPE_RA)
590                                         printf(" Read-Alloc");
591                                 if (reg & CPUV7_CT_CTYPE_WA)
592                                         printf(" Write-Alloc");
593                                 printf("\n");
594                         }
595                         i++;
596                 }
597         } else {
598                 /* Print cache info. */
599                 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
600                         return;
601
602                 if (arm_pcache_unified) {
603                         printf("  %dKB/%dB %d-way %s unified cache\n",
604                             arm_pdcache_size / 1024,
605                             arm_pdcache_line_size, arm_pdcache_ways,
606                             wtnames[arm_pcache_type]);
607                 } else {
608                         printf("  %dKB/%dB %d-way instruction cache\n",
609                             arm_picache_size / 1024,
610                             arm_picache_line_size, arm_picache_ways);
611                         printf("  %dKB/%dB %d-way %s data cache\n",
612                             arm_pdcache_size / 1024,
613                             arm_pdcache_line_size, arm_pdcache_ways,
614                             wtnames[arm_pcache_type]);
615                 }
616         }
617 }