identcpu.c revision 266046
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: stable/10/sys/arm/arm/identcpu.c 266046 2014-05-14 16:32:27Z ian $");
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
60char machine[] = "arm";
61
62SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
63	machine, 0, "Machine class");
64
65static 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
72static 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
79static 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
86static 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
93static 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
102static 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
109static 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
116static 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
123static 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 */
131static 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 */
141static 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 */
149static 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
156static 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
163struct 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
170const 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_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
325	  generic_steppings },
326	{ CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
327	  generic_steppings },
328	{ CPU_ID_MV88SV584X_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV584x",
329	  generic_steppings },
330
331	{ 0, CPU_CLASS_NONE, NULL, NULL }
332};
333
334struct cpu_classtab {
335	const char	*class_name;
336	const char	*class_option;
337};
338
339const struct cpu_classtab cpu_classes[] = {
340	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
341	{ "ARM2",	"CPU_ARM2" },		/* CPU_CLASS_ARM2 */
342	{ "ARM2as",	"CPU_ARM250" },		/* CPU_CLASS_ARM2AS */
343	{ "ARM3",	"CPU_ARM3" },		/* CPU_CLASS_ARM3 */
344	{ "ARM6",	"CPU_ARM6" },		/* CPU_CLASS_ARM6 */
345	{ "ARM7",	"CPU_ARM7" },		/* CPU_CLASS_ARM7 */
346	{ "ARM7TDMI",	"CPU_ARM7TDMI" },	/* CPU_CLASS_ARM7TDMI */
347	{ "ARM8",	"CPU_ARM8" },		/* CPU_CLASS_ARM8 */
348	{ "ARM9TDMI",	"CPU_ARM9TDMI" },	/* CPU_CLASS_ARM9TDMI */
349	{ "ARM9E-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9ES */
350	{ "ARM9EJ-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9EJS */
351	{ "ARM10E",	"CPU_ARM10" },		/* CPU_CLASS_ARM10E */
352	{ "ARM10EJ",	"CPU_ARM10" },		/* CPU_CLASS_ARM10EJ */
353	{ "Cortex-A",	"CPU_CORTEXA" },	/* CPU_CLASS_CORTEXA */
354	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
355	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
356	{ "ARM11J",	"CPU_ARM11" },		/* CPU_CLASS_ARM11J */
357	{ "Marvell",	"CPU_MARVELL" },	/* CPU_CLASS_MARVELL */
358};
359
360/*
361 * Report the type of the specified arm processor. This uses the generic and
362 * arm specific information in the cpu structure to identify the processor.
363 * The remaining fields in the cpu structure are filled in appropriately.
364 */
365
366static const char * const wtnames[] = {
367	"write-through",
368	"write-back",
369	"write-back",
370	"**unknown 3**",
371	"**unknown 4**",
372	"write-back-locking",		/* XXX XScale-specific? */
373	"write-back-locking-A",
374	"write-back-locking-B",
375	"**unknown 8**",
376	"**unknown 9**",
377	"**unknown 10**",
378	"**unknown 11**",
379	"**unknown 12**",
380	"**unknown 13**",
381	"write-back-locking-C",
382	"**unknown 15**",
383};
384
385static void
386print_enadis(int enadis, char *s)
387{
388
389	printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
390}
391
392extern int ctrl;
393enum cpu_class cpu_class = CPU_CLASS_NONE;
394
395u_int cpu_pfr(int num)
396{
397	u_int feat;
398
399	switch (num) {
400	case 0:
401		__asm __volatile("mrc p15, 0, %0, c0, c1, 0"
402		    : "=r" (feat));
403		break;
404	case 1:
405		__asm __volatile("mrc p15, 0, %0, c0, c1, 1"
406		    : "=r" (feat));
407		break;
408	default:
409		panic("Processor Feature Register %d not implemented", num);
410		break;
411	}
412
413	return (feat);
414}
415
416static
417void identify_armv7(void)
418{
419	u_int feature;
420
421	printf("Supported features:");
422	/* Get Processor Feature Register 0 */
423	feature = cpu_pfr(0);
424
425	if (feature & ARM_PFR0_ARM_ISA_MASK)
426		printf(" ARM_ISA");
427
428	if (feature & ARM_PFR0_THUMB2)
429		printf(" THUMB2");
430	else if (feature & ARM_PFR0_THUMB)
431		printf(" THUMB");
432
433	if (feature & ARM_PFR0_JAZELLE_MASK)
434		printf(" JAZELLE");
435
436	if (feature & ARM_PFR0_THUMBEE_MASK)
437		printf(" THUMBEE");
438
439
440	/* Get Processor Feature Register 1 */
441	feature = cpu_pfr(1);
442
443	if (feature & ARM_PFR1_ARMV4_MASK)
444		printf(" ARMv4");
445
446	if (feature & ARM_PFR1_SEC_EXT_MASK)
447		printf(" Security_Ext");
448
449	if (feature & ARM_PFR1_MICROCTRL_MASK)
450		printf(" M_profile");
451
452	printf("\n");
453}
454
455void
456identify_arm_cpu(void)
457{
458	u_int cpuid, reg, size, sets, ways;
459	u_int8_t type, linesize;
460	int i;
461
462	cpuid = cpu_id();
463
464	if (cpuid == 0) {
465		printf("Processor failed probe - no CPU ID\n");
466		return;
467	}
468
469	for (i = 0; cpuids[i].cpuid != 0; i++)
470		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
471			cpu_class = cpuids[i].cpu_class;
472			printf("CPU: %s %s (%s core)\n",
473			    cpuids[i].cpu_name,
474			    cpuids[i].cpu_steppings[cpuid &
475			    CPU_ID_REVISION_MASK],
476			    cpu_classes[cpu_class].class_name);
477			break;
478		}
479	if (cpuids[i].cpuid == 0)
480		printf("unknown CPU (ID = 0x%x)\n", cpuid);
481
482	printf(" ");
483
484	if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) {
485		identify_armv7();
486	} else {
487		if (ctrl & CPU_CONTROL_BEND_ENABLE)
488			printf(" Big-endian");
489		else
490			printf(" Little-endian");
491
492		switch (cpu_class) {
493		case CPU_CLASS_ARM6:
494		case CPU_CLASS_ARM7:
495		case CPU_CLASS_ARM7TDMI:
496		case CPU_CLASS_ARM8:
497			print_enadis(ctrl & CPU_CONTROL_IDC_ENABLE, "IDC");
498			break;
499		case CPU_CLASS_ARM9TDMI:
500		case CPU_CLASS_ARM9ES:
501		case CPU_CLASS_ARM9EJS:
502		case CPU_CLASS_ARM10E:
503		case CPU_CLASS_ARM10EJ:
504		case CPU_CLASS_SA1:
505		case CPU_CLASS_XSCALE:
506		case CPU_CLASS_ARM11J:
507		case CPU_CLASS_MARVELL:
508			print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
509			print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
510#ifdef CPU_XSCALE_81342
511			print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2");
512#endif
513#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
514			i = sheeva_control_ext(0, 0);
515			print_enadis(i & MV_WA_ENABLE, "WA");
516			print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
517			printf("\n ");
518			print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
519			print_enadis(i & MV_L2_ENABLE, "L2");
520			print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
521			    "L2 prefetch");
522			printf("\n ");
523#endif
524			break;
525		default:
526			break;
527		}
528	}
529
530	print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
531	if (ctrl & CPU_CONTROL_LABT_ENABLE)
532		printf(" LABT");
533	else
534		printf(" EABT");
535
536	print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
537	printf("\n");
538
539	if (arm_cache_level) {
540		printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
541		    arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
542		i = 0;
543		while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
544			printf("Cache level %d: \n", i + 1);
545			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
546			    type == CACHE_SEP_CACHE) {
547				reg = arm_cache_type[2 * i];
548				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
549				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
550				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
551				size = (ways * sets * linesize) / 1024;
552
553				if (type == CACHE_UNI_CACHE)
554					printf(" %dKB/%dB %d-way unified cache", size, linesize,ways);
555				else
556					printf(" %dKB/%dB %d-way data cache", size, linesize, ways);
557				if (reg & CPUV7_CT_CTYPE_WT)
558					printf(" WT");
559				if (reg & CPUV7_CT_CTYPE_WB)
560					printf(" WB");
561				if (reg & CPUV7_CT_CTYPE_RA)
562					printf(" Read-Alloc");
563				if (reg & CPUV7_CT_CTYPE_WA)
564					printf(" Write-Alloc");
565				printf("\n");
566			}
567
568			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
569				reg = arm_cache_type[(2 * i) + 1];
570
571				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
572				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
573				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
574				size = (ways * sets * linesize) / 1024;
575
576				printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways);
577				if (reg & CPUV7_CT_CTYPE_WT)
578					printf(" WT");
579				if (reg & CPUV7_CT_CTYPE_WB)
580					printf(" WB");
581				if (reg & CPUV7_CT_CTYPE_RA)
582					printf(" Read-Alloc");
583				if (reg & CPUV7_CT_CTYPE_WA)
584					printf(" Write-Alloc");
585				printf("\n");
586			}
587			i++;
588		}
589	} else {
590		/* Print cache info. */
591		if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
592			return;
593
594		if (arm_pcache_unified) {
595			printf("  %dKB/%dB %d-way %s unified cache\n",
596			    arm_pdcache_size / 1024,
597			    arm_pdcache_line_size, arm_pdcache_ways,
598			    wtnames[arm_pcache_type]);
599		} else {
600			printf("  %dKB/%dB %d-way instruction cache\n",
601			    arm_picache_size / 1024,
602			    arm_picache_line_size, arm_picache_ways);
603			printf("  %dKB/%dB %d-way %s data cache\n",
604			    arm_pdcache_size / 1024,
605			    arm_pdcache_line_size, arm_pdcache_ways,
606			    wtnames[arm_pcache_type]);
607		}
608	}
609}
610