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