]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/identcpu.c
This commit was generated by cvs2svn to compensate for changes in r162012,
[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_80219_400,     CPU_CLASS_XSCALE,       "i80219 400MHz",
233           xscale_steppings },
234         
235         { CPU_ID_80219_600,     CPU_CLASS_XSCALE,       "i80219 600MHz",
236           xscale_steppings },
237
238         { CPU_ID_PXA250A,       CPU_CLASS_XSCALE,       "PXA250",
239           pxa2x0_steppings },
240         { CPU_ID_PXA210A,       CPU_CLASS_XSCALE,       "PXA210",
241           pxa2x0_steppings },
242         { CPU_ID_PXA250B,       CPU_CLASS_XSCALE,       "PXA250",
243           pxa2x0_steppings },
244         { CPU_ID_PXA210B,       CPU_CLASS_XSCALE,       "PXA210",
245           pxa2x0_steppings },
246         { CPU_ID_PXA250C,       CPU_CLASS_XSCALE,       "PXA250",
247           pxa2x0_steppings },
248         { CPU_ID_PXA210C,       CPU_CLASS_XSCALE,       "PXA210",
249           pxa2x0_steppings },
250
251         { CPU_ID_IXP425_533,    CPU_CLASS_XSCALE,       "IXP425 533MHz",
252           ixp425_steppings },
253         { CPU_ID_IXP425_400,    CPU_CLASS_XSCALE,       "IXP425 400MHz",
254           ixp425_steppings },
255         { CPU_ID_IXP425_266,    CPU_CLASS_XSCALE,       "IXP425 266MHz",
256           ixp425_steppings },
257
258         { 0, CPU_CLASS_NONE, NULL, NULL }
259 };
260
261 struct cpu_classtab {
262         const char      *class_name;
263         const char      *class_option;
264 };
265
266 const struct cpu_classtab cpu_classes[] = {
267         { "unknown",    NULL },                 /* CPU_CLASS_NONE */
268         { "ARM2",       "CPU_ARM2" },           /* CPU_CLASS_ARM2 */
269         { "ARM2as",     "CPU_ARM250" },         /* CPU_CLASS_ARM2AS */
270         { "ARM3",       "CPU_ARM3" },           /* CPU_CLASS_ARM3 */
271         { "ARM6",       "CPU_ARM6" },           /* CPU_CLASS_ARM6 */
272         { "ARM7",       "CPU_ARM7" },           /* CPU_CLASS_ARM7 */
273         { "ARM7TDMI",   "CPU_ARM7TDMI" },       /* CPU_CLASS_ARM7TDMI */
274         { "ARM8",       "CPU_ARM8" },           /* CPU_CLASS_ARM8 */
275         { "ARM9TDMI",   "CPU_ARM9TDMI" },       /* CPU_CLASS_ARM9TDMI */
276         { "ARM9E-S",    NULL },                 /* CPU_CLASS_ARM9ES */
277         { "ARM10E",     "CPU_ARM10" },          /* CPU_CLASS_ARM10E */
278         { "SA-1",       "CPU_SA110" },          /* CPU_CLASS_SA1 */
279         { "XScale",     "CPU_XSCALE_..." },     /* CPU_CLASS_XSCALE */
280 };
281
282 /*
283  * Report the type of the specified arm processor. This uses the generic and
284  * arm specific information in the cpu structure to identify the processor.
285  * The remaining fields in the cpu structure are filled in appropriately.
286  */
287
288 static const char * const wtnames[] = {
289         "write-through",
290         "write-back",
291         "write-back",
292         "**unknown 3**",
293         "**unknown 4**",
294         "write-back-locking",           /* XXX XScale-specific? */
295         "write-back-locking-A",
296         "write-back-locking-B",
297         "**unknown 8**",
298         "**unknown 9**",
299         "**unknown 10**",
300         "**unknown 11**",
301         "**unknown 12**",
302         "**unknown 13**",
303         "**unknown 14**",
304         "**unknown 15**",
305 };
306
307 void setPQL2(int *const size, int *const ways);
308
309 void
310 setPQL2(int *const size, int *const ways)
311 {
312         return;
313 }
314
315
316 extern int ctrl;
317 void
318 identify_arm_cpu(void)
319 {
320         u_int cpuid;
321         enum cpu_class cpu_class = CPU_CLASS_NONE;
322         int i;
323
324         cpuid = cpu_id();
325
326         if (cpuid == 0) {
327                 printf("Processor failed probe - no CPU ID\n");
328                 return;
329         }
330
331         for (i = 0; cpuids[i].cpuid != 0; i++)
332                 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
333                         cpu_class = cpuids[i].cpu_class;
334                         printf("CPU: %s %s (%s core)\n",
335                             cpuids[i].cpu_name,
336                             cpuids[i].cpu_steppings[cpuid &
337                             CPU_ID_REVISION_MASK],
338                             cpu_classes[cpu_class].class_name);
339                         break;
340                 }
341         if (cpuids[i].cpuid == 0)
342                 printf("unknown CPU (ID = 0x%x)\n", cpuid);
343
344         printf(" ");
345         switch (cpu_class) {
346         case CPU_CLASS_ARM6:
347         case CPU_CLASS_ARM7:
348         case CPU_CLASS_ARM7TDMI:
349         case CPU_CLASS_ARM8:
350                 if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
351                         printf(" IDC disabled");
352                 else
353                         printf(" IDC enabled");
354                 break;
355         case CPU_CLASS_ARM9TDMI:
356         case CPU_CLASS_ARM10E:
357         case CPU_CLASS_SA1:
358         case CPU_CLASS_XSCALE:
359                 if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
360                         printf(" DC disabled");
361                 else
362                         printf(" DC enabled");
363                 if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0)
364                         printf(" IC disabled");
365                 else
366                         printf(" IC enabled");
367                 break;
368         default:
369                 break;
370         }
371         if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
372                 printf(" WB disabled");
373         else
374                 printf(" WB enabled");
375
376         if (ctrl & CPU_CONTROL_LABT_ENABLE)
377                 printf(" LABT");
378         else
379                 printf(" EABT");
380
381         if (ctrl & CPU_CONTROL_BPRD_ENABLE)
382                 printf(" branch prediction enabled");
383
384         printf("\n");
385         /* Print cache info. */
386         if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
387                 return;
388         
389         if (arm_pcache_unified) {
390                 printf("  %dKB/%dB %d-way %s unified cache\n",
391                     arm_pdcache_size / 1024,
392                     arm_pdcache_line_size, arm_pdcache_ways,
393                     wtnames[arm_pcache_type]);
394         } else {
395                 printf("  %dKB/%dB %d-way Instruction cache\n",
396                     arm_picache_size / 1024,
397                     arm_picache_line_size, arm_picache_ways);
398                 printf("  %dKB/%dB %d-way %s Data cache\n",
399                     arm_pdcache_size / 1024,
400                     arm_pdcache_line_size, arm_pdcache_ways,
401                     wtnames[arm_pcache_type]);                
402         }
403 }
404