]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/arm/arm/identcpu.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 xscale_steppings[16] = {
73         "step A-0",     "step A-1",     "step B-0",     "step C-0",
74         "step D-0",     "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 i80219_steppings[16] = {
80         "step A-0",     "rev 1",        "rev 2",        "rev 3",
81         "rev 4",        "rev 5",        "rev 6",        "rev 7",
82         "rev 8",        "rev 9",        "rev 10",       "rev 11",
83         "rev 12",       "rev 13",       "rev 14",       "rev 15",
84 };
85
86 static const char * const i80321_steppings[16] = {
87         "step A-0",     "step B-0",     "rev 2",        "rev 3",
88         "rev 4",        "rev 5",        "rev 6",        "rev 7",
89         "rev 8",        "rev 9",        "rev 10",       "rev 11",
90         "rev 12",       "rev 13",       "rev 14",       "rev 15",
91 };
92
93 static const char * const i81342_steppings[16] = {
94         "step A-0",     "rev 1",        "rev 2",        "rev 3",
95         "rev 4",        "rev 5",        "rev 6",        "rev 7",
96         "rev 8",        "rev 9",        "rev 10",       "rev 11",
97         "rev 12",       "rev 13",       "rev 14",       "rev 15",
98 };
99
100 /* Steppings for PXA2[15]0 */
101 static const char * const pxa2x0_steppings[16] = {
102         "step A-0",     "step A-1",     "step B-0",     "step B-1",
103         "step B-2",     "step C-0",     "rev 6",        "rev 7",
104         "rev 8",        "rev 9",        "rev 10",       "rev 11",
105         "rev 12",       "rev 13",       "rev 14",       "rev 15",
106 };
107
108 /* Steppings for PXA255/26x.
109  * rev 5: PXA26x B0, rev 6: PXA255 A0
110  */
111 static const char * const pxa255_steppings[16] = {
112         "rev 0",        "rev 1",        "rev 2",        "step A-0",
113         "rev 4",        "step B-0",     "step A-0",     "rev 7",
114         "rev 8",        "rev 9",        "rev 10",       "rev 11",
115         "rev 12",       "rev 13",       "rev 14",       "rev 15",
116 };
117
118 /* Stepping for PXA27x */
119 static const char * const pxa27x_steppings[16] = {
120         "step A-0",     "step A-1",     "step B-0",     "step B-1",
121         "step C-0",     "rev 5",        "rev 6",        "rev 7",
122         "rev 8",        "rev 9",        "rev 10",       "rev 11",
123         "rev 12",       "rev 13",       "rev 14",       "rev 15",
124 };
125
126 static const char * const ixp425_steppings[16] = {
127         "step 0 (A0)",  "rev 1 (ARMv5TE)", "rev 2",     "rev 3",
128         "rev 4",        "rev 5",        "rev 6",        "rev 7",
129         "rev 8",        "rev 9",        "rev 10",       "rev 11",
130         "rev 12",       "rev 13",       "rev 14",       "rev 15",
131 };
132
133 struct cpuidtab {
134         u_int32_t       cpuid;
135         enum            cpu_class cpu_class;
136         const char      *cpu_name;
137         const char * const *cpu_steppings;
138 };
139
140 const struct cpuidtab cpuids[] = {
141         { CPU_ID_ARM920T,       CPU_CLASS_ARM9TDMI,     "ARM920T",
142           generic_steppings },
143         { CPU_ID_ARM920T_ALT,   CPU_CLASS_ARM9TDMI,     "ARM920T",
144           generic_steppings },
145         { CPU_ID_ARM922T,       CPU_CLASS_ARM9TDMI,     "ARM922T",
146           generic_steppings },
147         { CPU_ID_ARM926EJS,     CPU_CLASS_ARM9EJS,      "ARM926EJ-S",
148           generic_steppings },
149         { CPU_ID_ARM940T,       CPU_CLASS_ARM9TDMI,     "ARM940T",
150           generic_steppings },
151         { CPU_ID_ARM946ES,      CPU_CLASS_ARM9ES,       "ARM946E-S",
152           generic_steppings },
153         { CPU_ID_ARM966ES,      CPU_CLASS_ARM9ES,       "ARM966E-S",
154           generic_steppings },
155         { CPU_ID_ARM966ESR1,    CPU_CLASS_ARM9ES,       "ARM966E-S",
156           generic_steppings },
157         { CPU_ID_FA526,         CPU_CLASS_ARM9TDMI,     "FA526",
158           generic_steppings },
159         { CPU_ID_FA626TE,       CPU_CLASS_ARM9ES,       "FA626TE",
160           generic_steppings },
161
162         { CPU_ID_TI925T,        CPU_CLASS_ARM9TDMI,     "TI ARM925T",
163           generic_steppings },
164
165         { CPU_ID_ARM1020E,      CPU_CLASS_ARM10E,       "ARM1020E",
166           generic_steppings },
167         { CPU_ID_ARM1022ES,     CPU_CLASS_ARM10E,       "ARM1022E-S",
168           generic_steppings },
169         { CPU_ID_ARM1026EJS,    CPU_CLASS_ARM10EJ,      "ARM1026EJ-S",
170           generic_steppings },
171
172         { CPU_ID_CORTEXA7,      CPU_CLASS_CORTEXA,      "Cortex A7",
173           generic_steppings },
174         { CPU_ID_CORTEXA8R1,    CPU_CLASS_CORTEXA,      "Cortex A8-r1",
175           generic_steppings },
176         { CPU_ID_CORTEXA8R2,    CPU_CLASS_CORTEXA,      "Cortex A8-r2",
177           generic_steppings },
178         { CPU_ID_CORTEXA8R3,    CPU_CLASS_CORTEXA,      "Cortex A8-r3",
179           generic_steppings },
180         { CPU_ID_CORTEXA9R1,    CPU_CLASS_CORTEXA,      "Cortex A9-r1",
181           generic_steppings },
182         { CPU_ID_CORTEXA9R2,    CPU_CLASS_CORTEXA,      "Cortex A9-r2",
183           generic_steppings },
184         { CPU_ID_CORTEXA9R3,    CPU_CLASS_CORTEXA,      "Cortex A9-r3",
185           generic_steppings },
186         { CPU_ID_CORTEXA15R0,   CPU_CLASS_CORTEXA,      "Cortex A15-r0",
187           generic_steppings },
188         { CPU_ID_CORTEXA15R1,   CPU_CLASS_CORTEXA,      "Cortex A15-r1",
189           generic_steppings },
190         { CPU_ID_CORTEXA15R2,   CPU_CLASS_CORTEXA,      "Cortex A15-r2",
191           generic_steppings },
192         { CPU_ID_CORTEXA15R3,   CPU_CLASS_CORTEXA,      "Cortex A15-r3",
193           generic_steppings },
194         { CPU_ID_KRAIT,         CPU_CLASS_KRAIT,        "Krait",
195           generic_steppings },
196
197         { CPU_ID_80200,         CPU_CLASS_XSCALE,       "i80200",
198           xscale_steppings },
199
200         { CPU_ID_80321_400,     CPU_CLASS_XSCALE,       "i80321 400MHz",
201           i80321_steppings },
202         { CPU_ID_80321_600,     CPU_CLASS_XSCALE,       "i80321 600MHz",
203           i80321_steppings },
204         { CPU_ID_80321_400_B0,  CPU_CLASS_XSCALE,       "i80321 400MHz",
205           i80321_steppings },
206         { CPU_ID_80321_600_B0,  CPU_CLASS_XSCALE,       "i80321 600MHz",
207           i80321_steppings },
208
209         { CPU_ID_81342,         CPU_CLASS_XSCALE,       "i81342",
210           i81342_steppings },
211
212         { CPU_ID_80219_400,     CPU_CLASS_XSCALE,       "i80219 400MHz",
213           i80219_steppings },
214         { CPU_ID_80219_600,     CPU_CLASS_XSCALE,       "i80219 600MHz",
215           i80219_steppings },
216
217         { CPU_ID_PXA27X,        CPU_CLASS_XSCALE,       "PXA27x",
218           pxa27x_steppings },
219         { CPU_ID_PXA250A,       CPU_CLASS_XSCALE,       "PXA250",
220           pxa2x0_steppings },
221         { CPU_ID_PXA210A,       CPU_CLASS_XSCALE,       "PXA210",
222           pxa2x0_steppings },
223         { CPU_ID_PXA250B,       CPU_CLASS_XSCALE,       "PXA250",
224           pxa2x0_steppings },
225         { CPU_ID_PXA210B,       CPU_CLASS_XSCALE,       "PXA210",
226           pxa2x0_steppings },
227         { CPU_ID_PXA250C,       CPU_CLASS_XSCALE,       "PXA255",
228           pxa255_steppings },
229         { CPU_ID_PXA210C,       CPU_CLASS_XSCALE,       "PXA210",
230           pxa2x0_steppings },
231
232         { CPU_ID_IXP425_533,    CPU_CLASS_XSCALE,       "IXP425 533MHz",
233           ixp425_steppings },
234         { CPU_ID_IXP425_400,    CPU_CLASS_XSCALE,       "IXP425 400MHz",
235           ixp425_steppings },
236         { CPU_ID_IXP425_266,    CPU_CLASS_XSCALE,       "IXP425 266MHz",
237           ixp425_steppings },
238
239         /* XXX ixp435 steppings? */
240         { CPU_ID_IXP435,        CPU_CLASS_XSCALE,       "IXP435",
241           ixp425_steppings },
242
243         { CPU_ID_ARM1136JS,     CPU_CLASS_ARM11J,       "ARM1136J-S",
244           generic_steppings },
245         { CPU_ID_ARM1136JSR1,   CPU_CLASS_ARM11J,       "ARM1136J-S R1",
246           generic_steppings },
247         { CPU_ID_ARM1176JZS,    CPU_CLASS_ARM11J,       "ARM1176JZ-S",
248           generic_steppings },
249
250         { CPU_ID_MV88FR131,     CPU_CLASS_MARVELL,      "Feroceon 88FR131",
251           generic_steppings },
252
253         { CPU_ID_MV88FR571_VD,  CPU_CLASS_MARVELL,      "Feroceon 88FR571-VD",
254           generic_steppings },
255         { CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL,      "Sheeva 88SV581x",
256           generic_steppings },
257         { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL,    "Sheeva 88SV581x",
258           generic_steppings },
259         { CPU_ID_MV88SV584X_V7, CPU_CLASS_MARVELL,      "Sheeva 88SV584x",
260           generic_steppings },
261
262         { 0, CPU_CLASS_NONE, NULL, NULL }
263 };
264
265 struct cpu_classtab {
266         const char      *class_name;
267         const char      *class_option;
268 };
269
270 const struct cpu_classtab cpu_classes[] = {
271         { "unknown",    NULL },                 /* CPU_CLASS_NONE */
272         { "ARM9TDMI",   "CPU_ARM9TDMI" },       /* CPU_CLASS_ARM9TDMI */
273         { "ARM9E-S",    "CPU_ARM9E" },          /* CPU_CLASS_ARM9ES */
274         { "ARM9EJ-S",   "CPU_ARM9E" },          /* CPU_CLASS_ARM9EJS */
275         { "ARM10E",     "CPU_ARM10" },          /* CPU_CLASS_ARM10E */
276         { "ARM10EJ",    "CPU_ARM10" },          /* CPU_CLASS_ARM10EJ */
277         { "Cortex-A",   "CPU_CORTEXA" },        /* CPU_CLASS_CORTEXA */
278         { "Krait",      "CPU_KRAIT" },          /* CPU_CLASS_KRAIT */
279         { "XScale",     "CPU_XSCALE_..." },     /* CPU_CLASS_XSCALE */
280         { "ARM11J",     "CPU_ARM11" },          /* CPU_CLASS_ARM11J */
281         { "Marvell",    "CPU_MARVELL" },        /* CPU_CLASS_MARVELL */
282 };
283
284 /*
285  * Report the type of the specified arm processor. This uses the generic and
286  * arm specific information in the cpu structure to identify the processor.
287  * The remaining fields in the cpu structure are filled in appropriately.
288  */
289
290 static const char * const wtnames[] = {
291         "write-through",
292         "write-back",
293         "write-back",
294         "**unknown 3**",
295         "**unknown 4**",
296         "write-back-locking",           /* XXX XScale-specific? */
297         "write-back-locking-A",
298         "write-back-locking-B",
299         "**unknown 8**",
300         "**unknown 9**",
301         "**unknown 10**",
302         "**unknown 11**",
303         "**unknown 12**",
304         "**unknown 13**",
305         "write-back-locking-C",
306         "**unknown 15**",
307 };
308
309 static void
310 print_enadis(int enadis, char *s)
311 {
312
313         printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
314 }
315
316 extern int ctrl;
317 enum cpu_class cpu_class = CPU_CLASS_NONE;
318
319 u_int cpu_pfr(int num)
320 {
321         u_int feat;
322
323         switch (num) {
324         case 0:
325                 __asm __volatile("mrc p15, 0, %0, c0, c1, 0"
326                     : "=r" (feat));
327                 break;
328         case 1:
329                 __asm __volatile("mrc p15, 0, %0, c0, c1, 1"
330                     : "=r" (feat));
331                 break;
332         default:
333                 panic("Processor Feature Register %d not implemented", num);
334                 break;
335         }
336
337         return (feat);
338 }
339
340 static
341 void identify_armv7(void)
342 {
343         u_int feature;
344
345         printf("Supported features:");
346         /* Get Processor Feature Register 0 */
347         feature = cpu_pfr(0);
348
349         if (feature & ARM_PFR0_ARM_ISA_MASK)
350                 printf(" ARM_ISA");
351
352         if (feature & ARM_PFR0_THUMB2)
353                 printf(" THUMB2");
354         else if (feature & ARM_PFR0_THUMB)
355                 printf(" THUMB");
356
357         if (feature & ARM_PFR0_JAZELLE_MASK)
358                 printf(" JAZELLE");
359
360         if (feature & ARM_PFR0_THUMBEE_MASK)
361                 printf(" THUMBEE");
362
363
364         /* Get Processor Feature Register 1 */
365         feature = cpu_pfr(1);
366
367         if (feature & ARM_PFR1_ARMV4_MASK)
368                 printf(" ARMv4");
369
370         if (feature & ARM_PFR1_SEC_EXT_MASK)
371                 printf(" Security_Ext");
372
373         if (feature & ARM_PFR1_MICROCTRL_MASK)
374                 printf(" M_profile");
375
376         printf("\n");
377 }
378
379 void
380 identify_arm_cpu(void)
381 {
382         u_int cpuid, reg, size, sets, ways;
383         u_int8_t type, linesize;
384         int i;
385
386         cpuid = cpu_id();
387
388         if (cpuid == 0) {
389                 printf("Processor failed probe - no CPU ID\n");
390                 return;
391         }
392
393         for (i = 0; cpuids[i].cpuid != 0; i++)
394                 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
395                         cpu_class = cpuids[i].cpu_class;
396                         printf("CPU: %s %s (%s core)\n",
397                             cpuids[i].cpu_name,
398                             cpuids[i].cpu_steppings[cpuid &
399                             CPU_ID_REVISION_MASK],
400                             cpu_classes[cpu_class].class_name);
401                         break;
402                 }
403         if (cpuids[i].cpuid == 0)
404                 printf("unknown CPU (ID = 0x%x)\n", cpuid);
405
406         printf(" ");
407
408         if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) {
409                 identify_armv7();
410         } else {
411                 if (ctrl & CPU_CONTROL_BEND_ENABLE)
412                         printf(" Big-endian");
413                 else
414                         printf(" Little-endian");
415
416                 switch (cpu_class) {
417                 case CPU_CLASS_ARM9TDMI:
418                 case CPU_CLASS_ARM9ES:
419                 case CPU_CLASS_ARM9EJS:
420                 case CPU_CLASS_ARM10E:
421                 case CPU_CLASS_ARM10EJ:
422                 case CPU_CLASS_XSCALE:
423                 case CPU_CLASS_ARM11J:
424                 case CPU_CLASS_MARVELL:
425                         print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
426                         print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
427 #ifdef CPU_XSCALE_81342
428                         print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2");
429 #endif
430 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
431                         i = sheeva_control_ext(0, 0);
432                         print_enadis(i & MV_WA_ENABLE, "WA");
433                         print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
434                         printf("\n ");
435                         print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
436                         print_enadis(i & MV_L2_ENABLE, "L2");
437                         print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
438                             "L2 prefetch");
439                         printf("\n ");
440 #endif
441                         break;
442                 default:
443                         break;
444                 }
445         }
446
447         print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
448         if (ctrl & CPU_CONTROL_LABT_ENABLE)
449                 printf(" LABT");
450         else
451                 printf(" EABT");
452
453         print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
454         printf("\n");
455
456         if (arm_cache_level) {
457                 printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
458                     arm_cache_loc + 1, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
459                 i = 0;
460                 while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
461                         printf("Cache level %d: \n", i + 1);
462                         if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
463                             type == CACHE_SEP_CACHE) {
464                                 reg = arm_cache_type[2 * i];
465                                 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
466                                 sets = CPUV7_CT_xSIZE_SET(reg) + 1;
467                                 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
468                                 size = (ways * sets * linesize) / 1024;
469
470                                 if (type == CACHE_UNI_CACHE)
471                                         printf(" %dKB/%dB %d-way unified cache", size, linesize,ways);
472                                 else
473                                         printf(" %dKB/%dB %d-way data cache", size, linesize, ways);
474                                 if (reg & CPUV7_CT_CTYPE_WT)
475                                         printf(" WT");
476                                 if (reg & CPUV7_CT_CTYPE_WB)
477                                         printf(" WB");
478                                 if (reg & CPUV7_CT_CTYPE_RA)
479                                         printf(" Read-Alloc");
480                                 if (reg & CPUV7_CT_CTYPE_WA)
481                                         printf(" Write-Alloc");
482                                 printf("\n");
483                         }
484
485                         if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
486                                 reg = arm_cache_type[(2 * i) + 1];
487
488                                 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
489                                 sets = CPUV7_CT_xSIZE_SET(reg) + 1;
490                                 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
491                                 size = (ways * sets * linesize) / 1024;
492
493                                 printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways);
494                                 if (reg & CPUV7_CT_CTYPE_WT)
495                                         printf(" WT");
496                                 if (reg & CPUV7_CT_CTYPE_WB)
497                                         printf(" WB");
498                                 if (reg & CPUV7_CT_CTYPE_RA)
499                                         printf(" Read-Alloc");
500                                 if (reg & CPUV7_CT_CTYPE_WA)
501                                         printf(" Write-Alloc");
502                                 printf("\n");
503                         }
504                         i++;
505                 }
506         } else {
507                 /* Print cache info. */
508                 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
509                         return;
510
511                 if (arm_pcache_unified) {
512                         printf("  %dKB/%dB %d-way %s unified cache\n",
513                             arm_pdcache_size / 1024,
514                             arm_pdcache_line_size, arm_pdcache_ways,
515                             wtnames[arm_pcache_type]);
516                 } else {
517                         printf("  %dKB/%dB %d-way instruction cache\n",
518                             arm_picache_size / 1024,
519                             arm_picache_line_size, arm_picache_ways);
520                         printf("  %dKB/%dB %d-way %s data cache\n",
521                             arm_pdcache_size / 1024,
522                             arm_pdcache_line_size, arm_pdcache_ways,
523                             wtnames[arm_pcache_type]);
524                 }
525         }
526 }