identcpu-v6.c revision 139735
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 139735 2005-01-05 21:58:49Z imp $"); 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 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 136static 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 143struct 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 150const 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_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", 191 generic_steppings }, 192 { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", 193 generic_steppings }, 194 { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", 195 generic_steppings }, 196 { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", 197 generic_steppings }, 198 { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", 199 generic_steppings }, 200 { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", 201 generic_steppings }, 202 203 { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", 204 generic_steppings }, 205 { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", 206 generic_steppings }, 207 208 { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", 209 sa110_steppings }, 210 { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", 211 sa1100_steppings }, 212 { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", 213 sa1110_steppings }, 214 215 { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", 216 ixp12x0_steppings }, 217 218 { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", 219 xscale_steppings }, 220 221 { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", 222 i80321_steppings }, 223 { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", 224 i80321_steppings }, 225 { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", 226 i80321_steppings }, 227 { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", 228 i80321_steppings }, 229 230 { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", 231 pxa2x0_steppings }, 232 { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", 233 pxa2x0_steppings }, 234 { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", 235 pxa2x0_steppings }, 236 { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", 237 pxa2x0_steppings }, 238 { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA250", 239 pxa2x0_steppings }, 240 { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", 241 pxa2x0_steppings }, 242 243 { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", 244 ixp425_steppings }, 245 { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", 246 ixp425_steppings }, 247 { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", 248 ixp425_steppings }, 249 250 { 0, CPU_CLASS_NONE, NULL, NULL } 251}; 252 253struct cpu_classtab { 254 const char *class_name; 255 const char *class_option; 256}; 257 258const struct cpu_classtab cpu_classes[] = { 259 { "unknown", NULL }, /* CPU_CLASS_NONE */ 260 { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */ 261 { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */ 262 { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ 263 { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ 264 { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ 265 { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */ 266 { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ 267 { "ARM9TDMI", NULL }, /* CPU_CLASS_ARM9TDMI */ 268 { "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */ 269 { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ 270 { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */ 271 { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ 272}; 273 274/* 275 * Report the type of the specified arm processor. This uses the generic and 276 * arm specific information in the cpu structure to identify the processor. 277 * The remaining fields in the cpu structure are filled in appropriately. 278 */ 279 280static const char * const wtnames[] = { 281 "write-through", 282 "write-back", 283 "write-back", 284 "**unknown 3**", 285 "**unknown 4**", 286 "write-back-locking", /* XXX XScale-specific? */ 287 "write-back-locking-A", 288 "write-back-locking-B", 289 "**unknown 8**", 290 "**unknown 9**", 291 "**unknown 10**", 292 "**unknown 11**", 293 "**unknown 12**", 294 "**unknown 13**", 295 "**unknown 14**", 296 "**unknown 15**", 297}; 298 299extern int ctrl; 300void 301identify_arm_cpu(void) 302{ 303 u_int cpuid; 304 enum cpu_class cpu_class = CPU_CLASS_NONE; 305 int i; 306 307 cpuid = cpu_id(); 308 309 if (cpuid == 0) { 310 printf("Processor failed probe - no CPU ID\n"); 311 return; 312 } 313 314 for (i = 0; cpuids[i].cpuid != 0; i++) 315 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { 316 cpu_class = cpuids[i].cpu_class; 317 printf("%s %s (%s core)\n", 318 cpuids[i].cpu_name, 319 cpuids[i].cpu_steppings[cpuid & 320 CPU_ID_REVISION_MASK], 321 cpu_classes[cpu_class].class_name); 322 break; 323 } 324 if (cpuids[i].cpuid == 0) 325 printf("unknown CPU (ID = 0x%x)\n", cpuid); 326 327 switch (cpu_class) { 328 case CPU_CLASS_ARM6: 329 case CPU_CLASS_ARM7: 330 case CPU_CLASS_ARM7TDMI: 331 case CPU_CLASS_ARM8: 332 if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0) 333 printf(" IDC disabled"); 334 else 335 printf(" IDC enabled"); 336 break; 337 case CPU_CLASS_ARM9TDMI: 338 case CPU_CLASS_ARM10E: 339 case CPU_CLASS_SA1: 340 case CPU_CLASS_XSCALE: 341 if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0) 342 printf(" DC disabled"); 343 else 344 printf(" DC enabled"); 345 if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0) 346 printf(" IC disabled"); 347 else 348 printf(" IC enabled"); 349 break; 350 default: 351 break; 352 } 353 if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) 354 printf(" WB disabled"); 355 else 356 printf(" WB enabled"); 357 358 if (ctrl & CPU_CONTROL_LABT_ENABLE) 359 printf(" LABT"); 360 else 361 printf(" EABT"); 362 363 if (ctrl & CPU_CONTROL_BPRD_ENABLE) 364 printf(" branch prediction enabled"); 365 366 /* Print cache info. */ 367 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) 368 return; 369 370 if (arm_pcache_unified) { 371 printf("%dKB/%dB %d-way %s unified cache\n", 372 arm_pdcache_size / 1024, 373 arm_pdcache_line_size, arm_pdcache_ways, 374 wtnames[arm_pcache_type]); 375 } else { 376 printf("%dKB/%dB %d-way Instruction cache\n", 377 arm_picache_size / 1024, 378 arm_picache_line_size, arm_picache_ways); 379 printf("%dKB/%dB %d-way %s Data cache\n", 380 arm_pdcache_size / 1024, 381 arm_pdcache_line_size, arm_pdcache_ways, 382 wtnames[arm_pcache_type]); 383 } 384 printf("\n"); 385} 386 387