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