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