identcpu-v4.c revision 129198
1129198Scognet/*	$NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $	*/
2129198Scognet
3129198Scognet/*
4129198Scognet * Copyright (c) 1995 Mark Brinicombe.
5129198Scognet * Copyright (c) 1995 Brini.
6129198Scognet * All rights reserved.
7129198Scognet *
8129198Scognet * Redistribution and use in source and binary forms, with or without
9129198Scognet * modification, are permitted provided that the following conditions
10129198Scognet * are met:
11129198Scognet * 1. Redistributions of source code must retain the above copyright
12129198Scognet *    notice, this list of conditions and the following disclaimer.
13129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
14129198Scognet *    notice, this list of conditions and the following disclaimer in the
15129198Scognet *    documentation and/or other materials provided with the distribution.
16129198Scognet * 3. All advertising materials mentioning features or use of this software
17129198Scognet *    must display the following acknowledgement:
18129198Scognet *	This product includes software developed by Brini.
19129198Scognet * 4. The name of the company nor the name of the author may be used to
20129198Scognet *    endorse or promote products derived from this software without specific
21129198Scognet *    prior written permission.
22129198Scognet *
23129198Scognet * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
24129198Scognet * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25129198Scognet * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26129198Scognet * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33129198Scognet * SUCH DAMAGE.
34129198Scognet *
35129198Scognet * RiscBSD kernel project
36129198Scognet *
37129198Scognet * cpu.c
38129198Scognet *
39129198Scognet * Probing and configuration for the master CPU
40129198Scognet *
41129198Scognet * Created      : 10/10/95
42129198Scognet */
43129198Scognet
44129198Scognet#include <sys/cdefs.h>
45129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/identcpu.c 129198 2004-05-14 11:46:45Z cognet $");
46129198Scognet#include <sys/systm.h>
47129198Scognet#include <sys/param.h>
48129198Scognet#include <sys/malloc.h>
49129198Scognet#include <sys/time.h>
50129198Scognet#include <sys/proc.h>
51129198Scognet#include <sys/conf.h>
52129198Scognet#include <machine/cpu.h>
53129198Scognet
54129198Scognet#include <machine/cpuconf.h>
55129198Scognet
56129198Scognetchar machine[] = "arm";
57129198Scognet
58129198Scognetenum cpu_class {
59129198Scognet	CPU_CLASS_NONE,
60129198Scognet	CPU_CLASS_ARM2,
61129198Scognet	CPU_CLASS_ARM2AS,
62129198Scognet	CPU_CLASS_ARM3,
63129198Scognet	CPU_CLASS_ARM6,
64129198Scognet	CPU_CLASS_ARM7,
65129198Scognet	CPU_CLASS_ARM7TDMI,
66129198Scognet	CPU_CLASS_ARM8,
67129198Scognet	CPU_CLASS_ARM9TDMI,
68129198Scognet	CPU_CLASS_ARM9ES,
69129198Scognet	CPU_CLASS_ARM10E,
70129198Scognet	CPU_CLASS_SA1,
71129198Scognet	CPU_CLASS_XSCALE
72129198Scognet};
73129198Scognet
74129198Scognetstatic const char * const generic_steppings[16] = {
75129198Scognet	"rev 0",	"rev 1",	"rev 2",	"rev 3",
76129198Scognet	"rev 4",	"rev 5",	"rev 6",	"rev 7",
77129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
78129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
79129198Scognet};
80129198Scognet
81129198Scognetstatic const char * const sa110_steppings[16] = {
82129198Scognet	"rev 0",	"step J",	"step K",	"step S",
83129198Scognet	"step T",	"rev 5",	"rev 6",	"rev 7",
84129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
85129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
86129198Scognet};
87129198Scognet
88129198Scognetstatic const char * const sa1100_steppings[16] = {
89129198Scognet	"rev 0",	"step B",	"step C",	"rev 3",
90129198Scognet	"rev 4",	"rev 5",	"rev 6",	"rev 7",
91129198Scognet	"step D",	"step E",	"rev 10"	"step G",
92129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
93129198Scognet};
94129198Scognet
95129198Scognetstatic const char * const sa1110_steppings[16] = {
96129198Scognet	"step A-0",	"rev 1",	"rev 2",	"rev 3",
97129198Scognet	"step B-0",	"step B-1",	"step B-2",	"step B-3",
98129198Scognet	"step B-4",	"step B-5",	"rev 10",	"rev 11",
99129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
100129198Scognet};
101129198Scognet
102129198Scognetstatic const char * const ixp12x0_steppings[16] = {
103129198Scognet	"(IXP1200 step A)",		"(IXP1200 step B)",
104129198Scognet	"rev 2",			"(IXP1200 step C)",
105129198Scognet	"(IXP1200 step D)",		"(IXP1240/1250 step A)",
106129198Scognet	"(IXP1240 step B)",		"(IXP1250 step B)",
107129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
108129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
109129198Scognet};
110129198Scognet
111129198Scognetstatic const char * const xscale_steppings[16] = {
112129198Scognet	"step A-0",	"step A-1",	"step B-0",	"step C-0",
113129198Scognet	"step D-0",	"rev 5",	"rev 6",	"rev 7",
114129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
115129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
116129198Scognet};
117129198Scognet
118129198Scognetstatic const char * const i80321_steppings[16] = {
119129198Scognet	"step A-0",	"step B-0",	"rev 2",	"rev 3",
120129198Scognet	"rev 4",	"rev 5",	"rev 6",	"rev 7",
121129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
122129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
123129198Scognet};
124129198Scognet
125129198Scognetstatic const char * const pxa2x0_steppings[16] = {
126129198Scognet	"step A-0",	"step A-1",	"step B-0",	"step B-1",
127129198Scognet	"step B-2",	"step C-0",	"rev 6",	"rev 7",
128129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
129129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
130129198Scognet};
131129198Scognet
132129198Scognetstatic const char * const ixp425_steppings[16] = {
133129198Scognet	"step 0",	"rev 1",	"rev 2",	"rev 3",
134129198Scognet	"rev 4",	"rev 5",	"rev 6",	"rev 7",
135129198Scognet	"rev 8",	"rev 9",	"rev 10",	"rev 11",
136129198Scognet	"rev 12",	"rev 13",	"rev 14",	"rev 15",
137129198Scognet};
138129198Scognet
139129198Scognetstruct cpuidtab {
140129198Scognet	u_int32_t	cpuid;
141129198Scognet	enum		cpu_class cpu_class;
142129198Scognet	const char	*cpu_name;
143129198Scognet	const char * const *cpu_steppings;
144129198Scognet};
145129198Scognet
146129198Scognetconst struct cpuidtab cpuids[] = {
147129198Scognet	{ CPU_ID_ARM2,		CPU_CLASS_ARM2,		"ARM2",
148129198Scognet	  generic_steppings },
149129198Scognet	{ CPU_ID_ARM250,	CPU_CLASS_ARM2AS,	"ARM250",
150129198Scognet	  generic_steppings },
151129198Scognet
152129198Scognet	{ CPU_ID_ARM3,		CPU_CLASS_ARM3,		"ARM3",
153129198Scognet	  generic_steppings },
154129198Scognet
155129198Scognet	{ CPU_ID_ARM600,	CPU_CLASS_ARM6,		"ARM600",
156129198Scognet	  generic_steppings },
157129198Scognet	{ CPU_ID_ARM610,	CPU_CLASS_ARM6,		"ARM610",
158129198Scognet	  generic_steppings },
159129198Scognet	{ CPU_ID_ARM620,	CPU_CLASS_ARM6,		"ARM620",
160129198Scognet	  generic_steppings },
161129198Scognet
162129198Scognet	{ CPU_ID_ARM700,	CPU_CLASS_ARM7,		"ARM700",
163129198Scognet	  generic_steppings },
164129198Scognet	{ CPU_ID_ARM710,	CPU_CLASS_ARM7,		"ARM710",
165129198Scognet	  generic_steppings },
166129198Scognet	{ CPU_ID_ARM7500,	CPU_CLASS_ARM7,		"ARM7500",
167129198Scognet	  generic_steppings },
168129198Scognet	{ CPU_ID_ARM710A,	CPU_CLASS_ARM7,		"ARM710a",
169129198Scognet	  generic_steppings },
170129198Scognet	{ CPU_ID_ARM7500FE,	CPU_CLASS_ARM7,		"ARM7500FE",
171129198Scognet	  generic_steppings },
172129198Scognet	{ CPU_ID_ARM710T,	CPU_CLASS_ARM7TDMI,	"ARM710T",
173129198Scognet	  generic_steppings },
174129198Scognet	{ CPU_ID_ARM720T,	CPU_CLASS_ARM7TDMI,	"ARM720T",
175129198Scognet	  generic_steppings },
176129198Scognet	{ CPU_ID_ARM740T8K,	CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
177129198Scognet	  generic_steppings },
178129198Scognet	{ CPU_ID_ARM740T4K,	CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
179129198Scognet	  generic_steppings },
180129198Scognet
181129198Scognet	{ CPU_ID_ARM810,	CPU_CLASS_ARM8,		"ARM810",
182129198Scognet	  generic_steppings },
183129198Scognet
184129198Scognet	{ CPU_ID_ARM920T,	CPU_CLASS_ARM9TDMI,	"ARM920T",
185129198Scognet	  generic_steppings },
186129198Scognet	{ CPU_ID_ARM922T,	CPU_CLASS_ARM9TDMI,	"ARM922T",
187129198Scognet	  generic_steppings },
188129198Scognet	{ CPU_ID_ARM940T,	CPU_CLASS_ARM9TDMI,	"ARM940T",
189129198Scognet	  generic_steppings },
190129198Scognet	{ CPU_ID_ARM946ES,	CPU_CLASS_ARM9ES,	"ARM946E-S",
191129198Scognet	  generic_steppings },
192129198Scognet	{ CPU_ID_ARM966ES,	CPU_CLASS_ARM9ES,	"ARM966E-S",
193129198Scognet	  generic_steppings },
194129198Scognet	{ CPU_ID_ARM966ESR1,	CPU_CLASS_ARM9ES,	"ARM966E-S",
195129198Scognet	  generic_steppings },
196129198Scognet	{ CPU_ID_TI925T,	CPU_CLASS_ARM9TDMI,	"TI ARM925T",
197129198Scognet	  generic_steppings },
198129198Scognet
199129198Scognet	{ CPU_ID_ARM1020E,	CPU_CLASS_ARM10E,	"ARM1020E",
200129198Scognet	  generic_steppings },
201129198Scognet	{ CPU_ID_ARM1022ES,	CPU_CLASS_ARM10E,	"ARM1022E-S",
202129198Scognet	  generic_steppings },
203129198Scognet
204129198Scognet	{ CPU_ID_SA110,		CPU_CLASS_SA1,		"SA-110",
205129198Scognet	  sa110_steppings },
206129198Scognet	{ CPU_ID_SA1100,	CPU_CLASS_SA1,		"SA-1100",
207129198Scognet	  sa1100_steppings },
208129198Scognet	{ CPU_ID_SA1110,	CPU_CLASS_SA1,		"SA-1110",
209129198Scognet	  sa1110_steppings },
210129198Scognet
211129198Scognet	{ CPU_ID_IXP1200,	CPU_CLASS_SA1,		"IXP1200",
212129198Scognet	  ixp12x0_steppings },
213129198Scognet
214129198Scognet	{ CPU_ID_80200,		CPU_CLASS_XSCALE,	"i80200",
215129198Scognet	  xscale_steppings },
216129198Scognet
217129198Scognet	{ CPU_ID_80321_400,	CPU_CLASS_XSCALE,	"i80321 400MHz",
218129198Scognet	  i80321_steppings },
219129198Scognet	{ CPU_ID_80321_600,	CPU_CLASS_XSCALE,	"i80321 600MHz",
220129198Scognet	  i80321_steppings },
221129198Scognet	{ CPU_ID_80321_400_B0,	CPU_CLASS_XSCALE,	"i80321 400MHz",
222129198Scognet	  i80321_steppings },
223129198Scognet	{ CPU_ID_80321_600_B0,	CPU_CLASS_XSCALE,	"i80321 600MHz",
224129198Scognet	  i80321_steppings },
225129198Scognet
226129198Scognet	{ CPU_ID_PXA250A,	CPU_CLASS_XSCALE,	"PXA250",
227129198Scognet	  pxa2x0_steppings },
228129198Scognet	{ CPU_ID_PXA210A,	CPU_CLASS_XSCALE,	"PXA210",
229129198Scognet	  pxa2x0_steppings },
230129198Scognet	{ CPU_ID_PXA250B,	CPU_CLASS_XSCALE,	"PXA250",
231129198Scognet	  pxa2x0_steppings },
232129198Scognet	{ CPU_ID_PXA210B,	CPU_CLASS_XSCALE,	"PXA210",
233129198Scognet	  pxa2x0_steppings },
234129198Scognet	{ CPU_ID_PXA250C, 	CPU_CLASS_XSCALE,	"PXA250",
235129198Scognet	  pxa2x0_steppings },
236129198Scognet	{ CPU_ID_PXA210C, 	CPU_CLASS_XSCALE,	"PXA210",
237129198Scognet	  pxa2x0_steppings },
238129198Scognet
239129198Scognet	{ CPU_ID_IXP425_533,	CPU_CLASS_XSCALE,	"IXP425 533MHz",
240129198Scognet	  ixp425_steppings },
241129198Scognet	{ CPU_ID_IXP425_400,	CPU_CLASS_XSCALE,	"IXP425 400MHz",
242129198Scognet	  ixp425_steppings },
243129198Scognet	{ CPU_ID_IXP425_266,	CPU_CLASS_XSCALE,	"IXP425 266MHz",
244129198Scognet	  ixp425_steppings },
245129198Scognet
246129198Scognet	{ 0, CPU_CLASS_NONE, NULL, NULL }
247129198Scognet};
248129198Scognet
249129198Scognetstruct cpu_classtab {
250129198Scognet	const char	*class_name;
251129198Scognet	const char	*class_option;
252129198Scognet};
253129198Scognet
254129198Scognetconst struct cpu_classtab cpu_classes[] = {
255129198Scognet	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
256129198Scognet	{ "ARM2",	"CPU_ARM2" },		/* CPU_CLASS_ARM2 */
257129198Scognet	{ "ARM2as",	"CPU_ARM250" },		/* CPU_CLASS_ARM2AS */
258129198Scognet	{ "ARM3",	"CPU_ARM3" },		/* CPU_CLASS_ARM3 */
259129198Scognet	{ "ARM6",	"CPU_ARM6" },		/* CPU_CLASS_ARM6 */
260129198Scognet	{ "ARM7",	"CPU_ARM7" },		/* CPU_CLASS_ARM7 */
261129198Scognet	{ "ARM7TDMI",	"CPU_ARM7TDMI" },	/* CPU_CLASS_ARM7TDMI */
262129198Scognet	{ "ARM8",	"CPU_ARM8" },		/* CPU_CLASS_ARM8 */
263129198Scognet	{ "ARM9TDMI",	NULL },			/* CPU_CLASS_ARM9TDMI */
264129198Scognet	{ "ARM9E-S",	NULL },			/* CPU_CLASS_ARM9ES */
265129198Scognet	{ "ARM10E",	"CPU_ARM10" },		/* CPU_CLASS_ARM10E */
266129198Scognet	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
267129198Scognet	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
268129198Scognet};
269129198Scognet
270129198Scognet/*
271129198Scognet * Report the type of the specified arm processor. This uses the generic and
272129198Scognet * arm specific information in the cpu structure to identify the processor.
273129198Scognet * The remaining fields in the cpu structure are filled in appropriately.
274129198Scognet */
275129198Scognet
276129198Scognet#if 0
277129198Scognetstatic const char * const wtnames[] = {
278129198Scognet	"write-through",
279129198Scognet	"write-back",
280129198Scognet	"write-back",
281129198Scognet	"**unknown 3**",
282129198Scognet	"**unknown 4**",
283129198Scognet	"write-back-locking",		/* XXX XScale-specific? */
284129198Scognet	"write-back-locking-A",
285129198Scognet	"write-back-locking-B",
286129198Scognet	"**unknown 8**",
287129198Scognet	"**unknown 9**",
288129198Scognet	"**unknown 10**",
289129198Scognet	"**unknown 11**",
290129198Scognet	"**unknown 12**",
291129198Scognet	"**unknown 13**",
292129198Scognet	"**unknown 14**",
293129198Scognet	"**unknown 15**",
294129198Scognet};
295129198Scognet#endif
296129198Scognet
297129198Scognetextern int ctrl;
298129198Scognetvoid
299129198Scognetidentify_arm_cpu(void)
300129198Scognet{
301129198Scognet	u_int cpuid;
302129198Scognet	enum cpu_class cpu_class = CPU_CLASS_NONE;
303129198Scognet	int i;
304129198Scognet
305129198Scognet	cpuid = cpu_id();
306129198Scognet
307129198Scognet	if (cpuid == 0) {
308129198Scognet		printf("Processor failed probe - no CPU ID\n");
309129198Scognet		return;
310129198Scognet	}
311129198Scognet
312129198Scognet	for (i = 0; cpuids[i].cpuid != 0; i++)
313129198Scognet		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
314129198Scognet			cpu_class = cpuids[i].cpu_class;
315129198Scognet			printf("%s %s (%s core)\n",
316129198Scognet			    cpuids[i].cpu_name,
317129198Scognet			    cpuids[i].cpu_steppings[cpuid &
318129198Scognet			    CPU_ID_REVISION_MASK],
319129198Scognet			    cpu_classes[cpu_class].class_name);
320129198Scognet			break;
321129198Scognet		}
322129198Scognet	if (cpuids[i].cpuid == 0)
323129198Scognet		printf("unknown CPU (ID = 0x%x)\n", cpuid);
324129198Scognet
325129198Scognet	switch (cpu_class) {
326129198Scognet	case CPU_CLASS_ARM6:
327129198Scognet	case CPU_CLASS_ARM7:
328129198Scognet	case CPU_CLASS_ARM7TDMI:
329129198Scognet	case CPU_CLASS_ARM8:
330129198Scognet		if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
331129198Scognet			printf(" IDC disabled");
332129198Scognet		else
333129198Scognet			printf(" IDC enabled");
334129198Scognet		break;
335129198Scognet	case CPU_CLASS_ARM9TDMI:
336129198Scognet	case CPU_CLASS_ARM10E:
337129198Scognet	case CPU_CLASS_SA1:
338129198Scognet	case CPU_CLASS_XSCALE:
339129198Scognet		if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
340129198Scognet			printf(" DC disabled");
341129198Scognet		else
342129198Scognet			printf(" DC enabled");
343129198Scognet		if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
344129198Scognet			printf(" IC disabled");
345129198Scognet		else
346129198Scognet			printf(" IC enabled");
347129198Scognet		break;
348129198Scognet	default:
349129198Scognet		break;
350129198Scognet	}
351129198Scognet	if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
352129198Scognet		printf(" WB disabled");
353129198Scognet	else
354129198Scognet		printf(" WB enabled");
355129198Scognet
356129198Scognet	if (ctrl & CPU_CONTROL_LABT_ENABLE)
357129198Scognet		printf(" LABT");
358129198Scognet	else
359129198Scognet		printf(" EABT");
360129198Scognet
361129198Scognet	if (ctrl & CPU_CONTROL_BPRD_ENABLE)
362129198Scognet		printf(" branch prediction enabled");
363129198Scognet
364129198Scognet	printf("\n");
365129198Scognet}
366129198Scognet
367