]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/identcpu-v4.c
Remove spurious newline
[FreeBSD/FreeBSD.git] / sys / arm / arm / identcpu-v4.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/param.h>
47 #include <sys/systm.h>
48 #include <sys/conf.h>
49 #include <sys/kernel.h>
50 #include <sys/sysctl.h>
51 #include <machine/cpu.h>
52 #include <machine/endian.h>
53
54 #include <machine/md_var.h>
55
56 char machine[] = "arm";
57
58 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
59         machine, 0, "Machine class");
60
61 static const char * const generic_steppings[16] = {
62         "rev 0",        "rev 1",        "rev 2",        "rev 3",
63         "rev 4",        "rev 5",        "rev 6",        "rev 7",
64         "rev 8",        "rev 9",        "rev 10",       "rev 11",
65         "rev 12",       "rev 13",       "rev 14",       "rev 15",
66 };
67
68 static const char * const xscale_steppings[16] = {
69         "step A-0",     "step A-1",     "step B-0",     "step C-0",
70         "step D-0",     "rev 5",        "rev 6",        "rev 7",
71         "rev 8",        "rev 9",        "rev 10",       "rev 11",
72         "rev 12",       "rev 13",       "rev 14",       "rev 15",
73 };
74
75 static const char * const i80219_steppings[16] = {
76         "step A-0",     "rev 1",        "rev 2",        "rev 3",
77         "rev 4",        "rev 5",        "rev 6",        "rev 7",
78         "rev 8",        "rev 9",        "rev 10",       "rev 11",
79         "rev 12",       "rev 13",       "rev 14",       "rev 15",
80 };
81
82 static const char * const i80321_steppings[16] = {
83         "step A-0",     "step B-0",     "rev 2",        "rev 3",
84         "rev 4",        "rev 5",        "rev 6",        "rev 7",
85         "rev 8",        "rev 9",        "rev 10",       "rev 11",
86         "rev 12",       "rev 13",       "rev 14",       "rev 15",
87 };
88
89 static const char * const i81342_steppings[16] = {
90         "step A-0",     "rev 1",        "rev 2",        "rev 3",
91         "rev 4",        "rev 5",        "rev 6",        "rev 7",
92         "rev 8",        "rev 9",        "rev 10",       "rev 11",
93         "rev 12",       "rev 13",       "rev 14",       "rev 15",
94 };
95
96 /* Steppings for PXA2[15]0 */
97 static const char * const pxa2x0_steppings[16] = {
98         "step A-0",     "step A-1",     "step B-0",     "step B-1",
99         "step B-2",     "step C-0",     "rev 6",        "rev 7",
100         "rev 8",        "rev 9",        "rev 10",       "rev 11",
101         "rev 12",       "rev 13",       "rev 14",       "rev 15",
102 };
103
104 /* Steppings for PXA255/26x.
105  * rev 5: PXA26x B0, rev 6: PXA255 A0
106  */
107 static const char * const pxa255_steppings[16] = {
108         "rev 0",        "rev 1",        "rev 2",        "step A-0",
109         "rev 4",        "step B-0",     "step A-0",     "rev 7",
110         "rev 8",        "rev 9",        "rev 10",       "rev 11",
111         "rev 12",       "rev 13",       "rev 14",       "rev 15",
112 };
113
114 /* Stepping for PXA27x */
115 static const char * const pxa27x_steppings[16] = {
116         "step A-0",     "step A-1",     "step B-0",     "step B-1",
117         "step C-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 struct cpuidtab {
123         u_int32_t       cpuid;
124         enum            cpu_class cpu_class;
125         const char      *cpu_name;
126         const char * const *cpu_steppings;
127 };
128
129 const struct cpuidtab cpuids[] = {
130         { CPU_ID_ARM920T,       CPU_CLASS_ARM9TDMI,     "ARM920T",
131           generic_steppings },
132         { CPU_ID_ARM920T_ALT,   CPU_CLASS_ARM9TDMI,     "ARM920T",
133           generic_steppings },
134         { CPU_ID_ARM922T,       CPU_CLASS_ARM9TDMI,     "ARM922T",
135           generic_steppings },
136         { CPU_ID_ARM926EJS,     CPU_CLASS_ARM9EJS,      "ARM926EJ-S",
137           generic_steppings },
138         { CPU_ID_ARM940T,       CPU_CLASS_ARM9TDMI,     "ARM940T",
139           generic_steppings },
140         { CPU_ID_ARM946ES,      CPU_CLASS_ARM9ES,       "ARM946E-S",
141           generic_steppings },
142         { CPU_ID_ARM966ES,      CPU_CLASS_ARM9ES,       "ARM966E-S",
143           generic_steppings },
144         { CPU_ID_ARM966ESR1,    CPU_CLASS_ARM9ES,       "ARM966E-S",
145           generic_steppings },
146         { CPU_ID_FA526,         CPU_CLASS_ARM9TDMI,     "FA526",
147           generic_steppings },
148         { CPU_ID_FA626TE,       CPU_CLASS_ARM9ES,       "FA626TE",
149           generic_steppings },
150
151         { CPU_ID_TI925T,        CPU_CLASS_ARM9TDMI,     "TI ARM925T",
152           generic_steppings },
153
154         { CPU_ID_ARM1020E,      CPU_CLASS_ARM10E,       "ARM1020E",
155           generic_steppings },
156         { CPU_ID_ARM1022ES,     CPU_CLASS_ARM10E,       "ARM1022E-S",
157           generic_steppings },
158         { CPU_ID_ARM1026EJS,    CPU_CLASS_ARM10EJ,      "ARM1026EJ-S",
159           generic_steppings },
160
161         { CPU_ID_80200,         CPU_CLASS_XSCALE,       "i80200",
162           xscale_steppings },
163
164         { CPU_ID_80321_400,     CPU_CLASS_XSCALE,       "i80321 400MHz",
165           i80321_steppings },
166         { CPU_ID_80321_600,     CPU_CLASS_XSCALE,       "i80321 600MHz",
167           i80321_steppings },
168         { CPU_ID_80321_400_B0,  CPU_CLASS_XSCALE,       "i80321 400MHz",
169           i80321_steppings },
170         { CPU_ID_80321_600_B0,  CPU_CLASS_XSCALE,       "i80321 600MHz",
171           i80321_steppings },
172
173         { CPU_ID_81342,         CPU_CLASS_XSCALE,       "i81342",
174           i81342_steppings },
175
176         { CPU_ID_80219_400,     CPU_CLASS_XSCALE,       "i80219 400MHz",
177           i80219_steppings },
178         { CPU_ID_80219_600,     CPU_CLASS_XSCALE,       "i80219 600MHz",
179           i80219_steppings },
180
181         { CPU_ID_PXA27X,        CPU_CLASS_XSCALE,       "PXA27x",
182           pxa27x_steppings },
183         { CPU_ID_PXA250A,       CPU_CLASS_XSCALE,       "PXA250",
184           pxa2x0_steppings },
185         { CPU_ID_PXA210A,       CPU_CLASS_XSCALE,       "PXA210",
186           pxa2x0_steppings },
187         { CPU_ID_PXA250B,       CPU_CLASS_XSCALE,       "PXA250",
188           pxa2x0_steppings },
189         { CPU_ID_PXA210B,       CPU_CLASS_XSCALE,       "PXA210",
190           pxa2x0_steppings },
191         { CPU_ID_PXA250C,       CPU_CLASS_XSCALE,       "PXA255",
192           pxa255_steppings },
193         { CPU_ID_PXA210C,       CPU_CLASS_XSCALE,       "PXA210",
194           pxa2x0_steppings },
195
196         { CPU_ID_MV88FR131,     CPU_CLASS_MARVELL,      "Feroceon 88FR131",
197           generic_steppings },
198
199         { CPU_ID_MV88FR571_VD,  CPU_CLASS_MARVELL,      "Feroceon 88FR571-VD",
200           generic_steppings },
201
202         { 0, CPU_CLASS_NONE, NULL, NULL }
203 };
204
205 struct cpu_classtab {
206         const char      *class_name;
207         const char      *class_option;
208 };
209
210 const struct cpu_classtab cpu_classes[] = {
211         { "unknown",    NULL },                 /* CPU_CLASS_NONE */
212         { "ARM9TDMI",   "CPU_ARM9TDMI" },       /* CPU_CLASS_ARM9TDMI */
213         { "ARM9E-S",    "CPU_ARM9E" },          /* CPU_CLASS_ARM9ES */
214         { "ARM9EJ-S",   "CPU_ARM9E" },          /* CPU_CLASS_ARM9EJS */
215         { "ARM10E",     "CPU_ARM10" },          /* CPU_CLASS_ARM10E */
216         { "ARM10EJ",    "CPU_ARM10" },          /* CPU_CLASS_ARM10EJ */
217         { "XScale",     "CPU_XSCALE_..." },     /* CPU_CLASS_XSCALE */
218         { "Marvell",    "CPU_MARVELL" },        /* CPU_CLASS_MARVELL */
219 };
220
221 /*
222  * Report the type of the specified arm processor. This uses the generic and
223  * arm specific information in the cpu structure to identify the processor.
224  * The remaining fields in the cpu structure are filled in appropriately.
225  */
226
227 static const char * const wtnames[] = {
228         "write-through",
229         "write-back",
230         "write-back",
231         "**unknown 3**",
232         "**unknown 4**",
233         "write-back-locking",           /* XXX XScale-specific? */
234         "write-back-locking-A",
235         "write-back-locking-B",
236         "**unknown 8**",
237         "**unknown 9**",
238         "**unknown 10**",
239         "**unknown 11**",
240         "**unknown 12**",
241         "**unknown 13**",
242         "write-back-locking-C",
243         "**unknown 15**",
244 };
245
246 static void
247 print_enadis(int enadis, char *s)
248 {
249
250         printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
251 }
252
253 enum cpu_class cpu_class = CPU_CLASS_NONE;
254
255 void
256 identify_arm_cpu(void)
257 {
258         u_int cpuid, ctrl;
259         int i;
260
261         ctrl = cp15_sctlr_get();
262         cpuid = cp15_midr_get();
263
264         if (cpuid == 0) {
265                 printf("Processor failed probe - no CPU ID\n");
266                 return;
267         }
268
269         for (i = 0; cpuids[i].cpuid != 0; i++)
270                 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
271                         cpu_class = cpuids[i].cpu_class;
272                         printf("CPU: %s %s (%s core)\n",
273                             cpuids[i].cpu_name,
274                             cpuids[i].cpu_steppings[cpuid &
275                             CPU_ID_REVISION_MASK],
276                             cpu_classes[cpu_class].class_name);
277                         break;
278                 }
279         if (cpuids[i].cpuid == 0)
280                 printf("unknown CPU (ID = 0x%x)\n", cpuid);
281
282         printf(" ");
283
284         if (ctrl & CPU_CONTROL_BEND_ENABLE)
285                 printf(" Big-endian");
286         else
287                 printf(" Little-endian");
288
289         switch (cpu_class) {
290         case CPU_CLASS_ARM9TDMI:
291         case CPU_CLASS_ARM9ES:
292         case CPU_CLASS_ARM9EJS:
293         case CPU_CLASS_ARM10E:
294         case CPU_CLASS_ARM10EJ:
295         case CPU_CLASS_XSCALE:
296         case CPU_CLASS_MARVELL:
297                 print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
298                 print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
299 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
300                 i = sheeva_control_ext(0, 0);
301                 print_enadis(i & MV_WA_ENABLE, "WA");
302                 print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
303                 printf("\n ");
304                 print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
305                 print_enadis(i & MV_L2_ENABLE, "L2");
306                 print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
307                     "L2 prefetch");
308                 printf("\n ");
309 #endif
310                 break;
311         default:
312                 break;
313         }
314
315         print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
316         if (ctrl & CPU_CONTROL_LABT_ENABLE)
317                 printf(" LABT");
318         else
319                 printf(" EABT");
320
321         print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
322         printf("\n");
323
324         /* Print cache info. */
325         if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
326                 return;
327
328         if (arm_pcache_unified) {
329                 printf("  %dKB/%dB %d-way %s unified cache\n",
330                     arm_pdcache_size / 1024,
331                     arm_pdcache_line_size, arm_pdcache_ways,
332                     wtnames[arm_pcache_type]);
333         } else {
334                 printf("  %dKB/%dB %d-way instruction cache\n",
335                     arm_picache_size / 1024,
336                     arm_picache_line_size, arm_picache_ways);
337                 printf("  %dKB/%dB %d-way %s data cache\n",
338                     arm_pdcache_size / 1024,
339                     arm_pdcache_line_size, arm_pdcache_ways,
340                     wtnames[arm_pcache_type]);
341         }
342 }