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