identcpu-v6.c revision 171625
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: head/sys/arm/arm/identcpu.c 171625 2007-07-27 14:49:11Z cognet $");
46#include <sys/systm.h>
47#include <sys/param.h>
48#include <sys/malloc.h>
49#include <sys/time.h>
50#include <sys/proc.h>
51#include <sys/conf.h>
52#include <sys/kernel.h>
53#include <sys/sysctl.h>
54#include <machine/cpu.h>
55
56#include <machine/cpuconf.h>
57
58char machine[] = "arm";
59
60SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
61        machine, 0, "Machine class");
62enum cpu_class {
63	CPU_CLASS_NONE,
64	CPU_CLASS_ARM2,
65	CPU_CLASS_ARM2AS,
66	CPU_CLASS_ARM3,
67	CPU_CLASS_ARM6,
68	CPU_CLASS_ARM7,
69	CPU_CLASS_ARM7TDMI,
70	CPU_CLASS_ARM8,
71	CPU_CLASS_ARM9TDMI,
72	CPU_CLASS_ARM9ES,
73	CPU_CLASS_ARM10E,
74	CPU_CLASS_SA1,
75	CPU_CLASS_XSCALE
76};
77
78static const char * const generic_steppings[16] = {
79	"rev 0",	"rev 1",	"rev 2",	"rev 3",
80	"rev 4",	"rev 5",	"rev 6",	"rev 7",
81	"rev 8",	"rev 9",	"rev 10",	"rev 11",
82	"rev 12",	"rev 13",	"rev 14",	"rev 15",
83};
84
85static const char * const sa110_steppings[16] = {
86	"rev 0",	"step J",	"step K",	"step S",
87	"step T",	"rev 5",	"rev 6",	"rev 7",
88	"rev 8",	"rev 9",	"rev 10",	"rev 11",
89	"rev 12",	"rev 13",	"rev 14",	"rev 15",
90};
91
92static const char * const sa1100_steppings[16] = {
93	"rev 0",	"step B",	"step C",	"rev 3",
94	"rev 4",	"rev 5",	"rev 6",	"rev 7",
95	"step D",	"step E",	"rev 10"	"step G",
96	"rev 12",	"rev 13",	"rev 14",	"rev 15",
97};
98
99static const char * const sa1110_steppings[16] = {
100	"step A-0",	"rev 1",	"rev 2",	"rev 3",
101	"step B-0",	"step B-1",	"step B-2",	"step B-3",
102	"step B-4",	"step B-5",	"rev 10",	"rev 11",
103	"rev 12",	"rev 13",	"rev 14",	"rev 15",
104};
105
106static const char * const ixp12x0_steppings[16] = {
107	"(IXP1200 step A)",		"(IXP1200 step B)",
108	"rev 2",			"(IXP1200 step C)",
109	"(IXP1200 step D)",		"(IXP1240/1250 step A)",
110	"(IXP1240 step B)",		"(IXP1250 step B)",
111	"rev 8",	"rev 9",	"rev 10",	"rev 11",
112	"rev 12",	"rev 13",	"rev 14",	"rev 15",
113};
114
115static const char * const xscale_steppings[16] = {
116	"step A-0",	"step A-1",	"step B-0",	"step C-0",
117	"step D-0",	"rev 5",	"rev 6",	"rev 7",
118	"rev 8",	"rev 9",	"rev 10",	"rev 11",
119	"rev 12",	"rev 13",	"rev 14",	"rev 15",
120};
121
122static const char * const i80321_steppings[16] = {
123	"step A-0",	"step B-0",	"rev 2",	"rev 3",
124	"rev 4",	"rev 5",	"rev 6",	"rev 7",
125	"rev 8",	"rev 9",	"rev 10",	"rev 11",
126	"rev 12",	"rev 13",	"rev 14",	"rev 15",
127};
128
129static const char * const i81342_steppings[16] = {
130	"step A-0",	"rev 1",	"rev 2",	"rev 3",
131	"rev 4",	"rev 5",	"rev 6",	"rev 7",
132	"rev 8",	"rev 9",	"rev 10",	"rev 11",
133	"rev 12",	"rev 13",	"rev 14",	"rev 15",
134};
135
136static const char * const pxa2x0_steppings[16] = {
137	"step A-0",	"step A-1",	"step B-0",	"step B-1",
138	"step B-2",	"step C-0",	"rev 6",	"rev 7",
139	"rev 8",	"rev 9",	"rev 10",	"rev 11",
140	"rev 12",	"rev 13",	"rev 14",	"rev 15",
141};
142
143static const char * const ixp425_steppings[16] = {
144	"step 0 (A0)",	"rev 1 (ARMv5TE)", "rev 2",	"rev 3",
145	"rev 4",	"rev 5",	"rev 6",	"rev 7",
146	"rev 8",	"rev 9",	"rev 10",	"rev 11",
147	"rev 12",	"rev 13",	"rev 14",	"rev 15",
148};
149
150struct cpuidtab {
151	u_int32_t	cpuid;
152	enum		cpu_class cpu_class;
153	const char	*cpu_name;
154	const char * const *cpu_steppings;
155};
156
157const struct cpuidtab cpuids[] = {
158	{ CPU_ID_ARM2,		CPU_CLASS_ARM2,		"ARM2",
159	  generic_steppings },
160	{ CPU_ID_ARM250,	CPU_CLASS_ARM2AS,	"ARM250",
161	  generic_steppings },
162
163	{ CPU_ID_ARM3,		CPU_CLASS_ARM3,		"ARM3",
164	  generic_steppings },
165
166	{ CPU_ID_ARM600,	CPU_CLASS_ARM6,		"ARM600",
167	  generic_steppings },
168	{ CPU_ID_ARM610,	CPU_CLASS_ARM6,		"ARM610",
169	  generic_steppings },
170	{ CPU_ID_ARM620,	CPU_CLASS_ARM6,		"ARM620",
171	  generic_steppings },
172
173	{ CPU_ID_ARM700,	CPU_CLASS_ARM7,		"ARM700",
174	  generic_steppings },
175	{ CPU_ID_ARM710,	CPU_CLASS_ARM7,		"ARM710",
176	  generic_steppings },
177	{ CPU_ID_ARM7500,	CPU_CLASS_ARM7,		"ARM7500",
178	  generic_steppings },
179	{ CPU_ID_ARM710A,	CPU_CLASS_ARM7,		"ARM710a",
180	  generic_steppings },
181	{ CPU_ID_ARM7500FE,	CPU_CLASS_ARM7,		"ARM7500FE",
182	  generic_steppings },
183	{ CPU_ID_ARM710T,	CPU_CLASS_ARM7TDMI,	"ARM710T",
184	  generic_steppings },
185	{ CPU_ID_ARM720T,	CPU_CLASS_ARM7TDMI,	"ARM720T",
186	  generic_steppings },
187	{ CPU_ID_ARM740T8K,	CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
188	  generic_steppings },
189	{ CPU_ID_ARM740T4K,	CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
190	  generic_steppings },
191
192	{ CPU_ID_ARM810,	CPU_CLASS_ARM8,		"ARM810",
193	  generic_steppings },
194
195	{ CPU_ID_ARM920T,	CPU_CLASS_ARM9TDMI,	"ARM920T",
196	  generic_steppings },
197	{ CPU_ID_ARM920T_ALT,	CPU_CLASS_ARM9TDMI,	"ARM920T",
198	  generic_steppings },
199	{ CPU_ID_ARM922T,	CPU_CLASS_ARM9TDMI,	"ARM922T",
200	  generic_steppings },
201	{ CPU_ID_ARM940T,	CPU_CLASS_ARM9TDMI,	"ARM940T",
202	  generic_steppings },
203	{ CPU_ID_ARM946ES,	CPU_CLASS_ARM9ES,	"ARM946E-S",
204	  generic_steppings },
205	{ CPU_ID_ARM966ES,	CPU_CLASS_ARM9ES,	"ARM966E-S",
206	  generic_steppings },
207	{ CPU_ID_ARM966ESR1,	CPU_CLASS_ARM9ES,	"ARM966E-S",
208	  generic_steppings },
209	{ CPU_ID_TI925T,	CPU_CLASS_ARM9TDMI,	"TI ARM925T",
210	  generic_steppings },
211
212	{ CPU_ID_ARM1020E,	CPU_CLASS_ARM10E,	"ARM1020E",
213	  generic_steppings },
214	{ CPU_ID_ARM1022ES,	CPU_CLASS_ARM10E,	"ARM1022E-S",
215	  generic_steppings },
216
217	{ CPU_ID_SA110,		CPU_CLASS_SA1,		"SA-110",
218	  sa110_steppings },
219	{ CPU_ID_SA1100,	CPU_CLASS_SA1,		"SA-1100",
220	  sa1100_steppings },
221	{ CPU_ID_SA1110,	CPU_CLASS_SA1,		"SA-1110",
222	  sa1110_steppings },
223
224	{ CPU_ID_IXP1200,	CPU_CLASS_SA1,		"IXP1200",
225	  ixp12x0_steppings },
226
227	{ CPU_ID_80200,		CPU_CLASS_XSCALE,	"i80200",
228	  xscale_steppings },
229
230	{ CPU_ID_80321_400,	CPU_CLASS_XSCALE,	"i80321 400MHz",
231	  i80321_steppings },
232	{ CPU_ID_80321_600,	CPU_CLASS_XSCALE,	"i80321 600MHz",
233	  i80321_steppings },
234	{ CPU_ID_80321_400_B0,	CPU_CLASS_XSCALE,	"i80321 400MHz",
235	  i80321_steppings },
236	{ CPU_ID_80321_600_B0,	CPU_CLASS_XSCALE,	"i80321 600MHz",
237	  i80321_steppings },
238
239	{ CPU_ID_81342,		CPU_CLASS_XSCALE,	"i81342",
240	  i81342_steppings },
241
242	{ CPU_ID_80219_400,	CPU_CLASS_XSCALE,	"i80219 400MHz",
243	  xscale_steppings },
244
245	{ CPU_ID_80219_600,	CPU_CLASS_XSCALE,	"i80219 600MHz",
246	  xscale_steppings },
247
248	{ CPU_ID_PXA250A,	CPU_CLASS_XSCALE,	"PXA250",
249	  pxa2x0_steppings },
250	{ CPU_ID_PXA210A,	CPU_CLASS_XSCALE,	"PXA210",
251	  pxa2x0_steppings },
252	{ CPU_ID_PXA250B,	CPU_CLASS_XSCALE,	"PXA250",
253	  pxa2x0_steppings },
254	{ CPU_ID_PXA210B,	CPU_CLASS_XSCALE,	"PXA210",
255	  pxa2x0_steppings },
256	{ CPU_ID_PXA250C, 	CPU_CLASS_XSCALE,	"PXA250",
257	  pxa2x0_steppings },
258	{ CPU_ID_PXA210C, 	CPU_CLASS_XSCALE,	"PXA210",
259	  pxa2x0_steppings },
260
261	{ CPU_ID_IXP425_533,	CPU_CLASS_XSCALE,	"IXP425 533MHz",
262	  ixp425_steppings },
263	{ CPU_ID_IXP425_400,	CPU_CLASS_XSCALE,	"IXP425 400MHz",
264	  ixp425_steppings },
265	{ CPU_ID_IXP425_266,	CPU_CLASS_XSCALE,	"IXP425 266MHz",
266	  ixp425_steppings },
267
268	{ 0, CPU_CLASS_NONE, NULL, NULL }
269};
270
271struct cpu_classtab {
272	const char	*class_name;
273	const char	*class_option;
274};
275
276const struct cpu_classtab cpu_classes[] = {
277	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
278	{ "ARM2",	"CPU_ARM2" },		/* CPU_CLASS_ARM2 */
279	{ "ARM2as",	"CPU_ARM250" },		/* CPU_CLASS_ARM2AS */
280	{ "ARM3",	"CPU_ARM3" },		/* CPU_CLASS_ARM3 */
281	{ "ARM6",	"CPU_ARM6" },		/* CPU_CLASS_ARM6 */
282	{ "ARM7",	"CPU_ARM7" },		/* CPU_CLASS_ARM7 */
283	{ "ARM7TDMI",	"CPU_ARM7TDMI" },	/* CPU_CLASS_ARM7TDMI */
284	{ "ARM8",	"CPU_ARM8" },		/* CPU_CLASS_ARM8 */
285	{ "ARM9TDMI",	"CPU_ARM9TDMI" },	/* CPU_CLASS_ARM9TDMI */
286	{ "ARM9E-S",	NULL },			/* CPU_CLASS_ARM9ES */
287	{ "ARM10E",	"CPU_ARM10" },		/* CPU_CLASS_ARM10E */
288	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
289	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
290};
291
292/*
293 * Report the type of the specified arm processor. This uses the generic and
294 * arm specific information in the cpu structure to identify the processor.
295 * The remaining fields in the cpu structure are filled in appropriately.
296 */
297
298static const char * const wtnames[] = {
299	"write-through",
300	"write-back",
301	"write-back",
302	"**unknown 3**",
303	"**unknown 4**",
304	"write-back-locking",		/* XXX XScale-specific? */
305	"write-back-locking-A",
306	"write-back-locking-B",
307	"**unknown 8**",
308	"**unknown 9**",
309	"**unknown 10**",
310	"**unknown 11**",
311	"**unknown 12**",
312	"**unknown 13**",
313	"**unknown 14**",
314	"**unknown 15**",
315};
316
317void setPQL2(int *const size, int *const ways);
318
319void
320setPQL2(int *const size, int *const ways)
321{
322	return;
323}
324
325
326extern int ctrl;
327void
328identify_arm_cpu(void)
329{
330	u_int cpuid;
331	enum cpu_class cpu_class = CPU_CLASS_NONE;
332	int i;
333
334	cpuid = cpu_id();
335
336	if (cpuid == 0) {
337		printf("Processor failed probe - no CPU ID\n");
338		return;
339	}
340
341	for (i = 0; cpuids[i].cpuid != 0; i++)
342		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
343			cpu_class = cpuids[i].cpu_class;
344			printf("CPU: %s %s (%s core)\n",
345			    cpuids[i].cpu_name,
346			    cpuids[i].cpu_steppings[cpuid &
347			    CPU_ID_REVISION_MASK],
348			    cpu_classes[cpu_class].class_name);
349			break;
350		}
351	if (cpuids[i].cpuid == 0)
352		printf("unknown CPU (ID = 0x%x)\n", cpuid);
353
354	printf(" ");
355	switch (cpu_class) {
356	case CPU_CLASS_ARM6:
357	case CPU_CLASS_ARM7:
358	case CPU_CLASS_ARM7TDMI:
359	case CPU_CLASS_ARM8:
360		if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
361			printf(" IDC disabled");
362		else
363			printf(" IDC enabled");
364		break;
365	case CPU_CLASS_ARM9TDMI:
366	case CPU_CLASS_ARM10E:
367	case CPU_CLASS_SA1:
368	case CPU_CLASS_XSCALE:
369		if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
370			printf(" DC disabled");
371		else
372			printf(" DC enabled");
373		if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
374			printf(" IC disabled");
375		else
376			printf(" IC enabled");
377#ifdef CPU_XSCALE_81342
378		if ((ctrl & CPU_CONTROL_L2_ENABLE) == 0)
379			printf(" L2 disabled");
380		else
381			printf(" L2 enabled");
382#endif
383		break;
384	default:
385		break;
386	}
387	if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
388		printf(" WB disabled");
389	else
390		printf(" WB enabled");
391
392	if (ctrl & CPU_CONTROL_LABT_ENABLE)
393		printf(" LABT");
394	else
395		printf(" EABT");
396
397	if (ctrl & CPU_CONTROL_BPRD_ENABLE)
398		printf(" branch prediction enabled");
399
400	printf("\n");
401	/* Print cache info. */
402	if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
403		return;
404
405	if (arm_pcache_unified) {
406 		printf("  %dKB/%dB %d-way %s unified cache\n",
407		    arm_pdcache_size / 1024,
408		    arm_pdcache_line_size, arm_pdcache_ways,
409		    wtnames[arm_pcache_type]);
410	} else {
411		printf("  %dKB/%dB %d-way Instruction cache\n",
412		    arm_picache_size / 1024,
413		    arm_picache_line_size, arm_picache_ways);
414		printf("  %dKB/%dB %d-way %s Data cache\n",
415		    arm_pdcache_size / 1024,
416		    arm_pdcache_line_size, arm_pdcache_ways,
417		    wtnames[arm_pcache_type]);
418	}
419}
420
421