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