identcpu.c revision 266046
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: stable/10/sys/arm/arm/identcpu.c 266046 2014-05-14 16:32:27Z ian $"); 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#include <machine/endian.h> 56 57#include <machine/cpuconf.h> 58#include <machine/md_var.h> 59 60char machine[] = "arm"; 61 62SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, 63 machine, 0, "Machine class"); 64 65static const char * const generic_steppings[16] = { 66 "rev 0", "rev 1", "rev 2", "rev 3", 67 "rev 4", "rev 5", "rev 6", "rev 7", 68 "rev 8", "rev 9", "rev 10", "rev 11", 69 "rev 12", "rev 13", "rev 14", "rev 15", 70}; 71 72static const char * const sa110_steppings[16] = { 73 "rev 0", "step J", "step K", "step S", 74 "step T", "rev 5", "rev 6", "rev 7", 75 "rev 8", "rev 9", "rev 10", "rev 11", 76 "rev 12", "rev 13", "rev 14", "rev 15", 77}; 78 79static const char * const sa1100_steppings[16] = { 80 "rev 0", "step B", "step C", "rev 3", 81 "rev 4", "rev 5", "rev 6", "rev 7", 82 "step D", "step E", "rev 10" "step G", 83 "rev 12", "rev 13", "rev 14", "rev 15", 84}; 85 86static const char * const sa1110_steppings[16] = { 87 "step A-0", "rev 1", "rev 2", "rev 3", 88 "step B-0", "step B-1", "step B-2", "step B-3", 89 "step B-4", "step B-5", "rev 10", "rev 11", 90 "rev 12", "rev 13", "rev 14", "rev 15", 91}; 92 93static const char * const ixp12x0_steppings[16] = { 94 "(IXP1200 step A)", "(IXP1200 step B)", 95 "rev 2", "(IXP1200 step C)", 96 "(IXP1200 step D)", "(IXP1240/1250 step A)", 97 "(IXP1240 step B)", "(IXP1250 step B)", 98 "rev 8", "rev 9", "rev 10", "rev 11", 99 "rev 12", "rev 13", "rev 14", "rev 15", 100}; 101 102static const char * const xscale_steppings[16] = { 103 "step A-0", "step A-1", "step B-0", "step C-0", 104 "step D-0", "rev 5", "rev 6", "rev 7", 105 "rev 8", "rev 9", "rev 10", "rev 11", 106 "rev 12", "rev 13", "rev 14", "rev 15", 107}; 108 109static const char * const i80219_steppings[16] = { 110 "step A-0", "rev 1", "rev 2", "rev 3", 111 "rev 4", "rev 5", "rev 6", "rev 7", 112 "rev 8", "rev 9", "rev 10", "rev 11", 113 "rev 12", "rev 13", "rev 14", "rev 15", 114}; 115 116static const char * const i80321_steppings[16] = { 117 "step A-0", "step B-0", "rev 2", "rev 3", 118 "rev 4", "rev 5", "rev 6", "rev 7", 119 "rev 8", "rev 9", "rev 10", "rev 11", 120 "rev 12", "rev 13", "rev 14", "rev 15", 121}; 122 123static const char * const i81342_steppings[16] = { 124 "step A-0", "rev 1", "rev 2", "rev 3", 125 "rev 4", "rev 5", "rev 6", "rev 7", 126 "rev 8", "rev 9", "rev 10", "rev 11", 127 "rev 12", "rev 13", "rev 14", "rev 15", 128}; 129 130/* Steppings for PXA2[15]0 */ 131static const char * const pxa2x0_steppings[16] = { 132 "step A-0", "step A-1", "step B-0", "step B-1", 133 "step B-2", "step C-0", "rev 6", "rev 7", 134 "rev 8", "rev 9", "rev 10", "rev 11", 135 "rev 12", "rev 13", "rev 14", "rev 15", 136}; 137 138/* Steppings for PXA255/26x. 139 * rev 5: PXA26x B0, rev 6: PXA255 A0 140 */ 141static const char * const pxa255_steppings[16] = { 142 "rev 0", "rev 1", "rev 2", "step A-0", 143 "rev 4", "step B-0", "step A-0", "rev 7", 144 "rev 8", "rev 9", "rev 10", "rev 11", 145 "rev 12", "rev 13", "rev 14", "rev 15", 146}; 147 148/* Stepping for PXA27x */ 149static const char * const pxa27x_steppings[16] = { 150 "step A-0", "step A-1", "step B-0", "step B-1", 151 "step C-0", "rev 5", "rev 6", "rev 7", 152 "rev 8", "rev 9", "rev 10", "rev 11", 153 "rev 12", "rev 13", "rev 14", "rev 15", 154}; 155 156static const char * const ixp425_steppings[16] = { 157 "step 0 (A0)", "rev 1 (ARMv5TE)", "rev 2", "rev 3", 158 "rev 4", "rev 5", "rev 6", "rev 7", 159 "rev 8", "rev 9", "rev 10", "rev 11", 160 "rev 12", "rev 13", "rev 14", "rev 15", 161}; 162 163struct cpuidtab { 164 u_int32_t cpuid; 165 enum cpu_class cpu_class; 166 const char *cpu_name; 167 const char * const *cpu_steppings; 168}; 169 170const struct cpuidtab cpuids[] = { 171 { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2", 172 generic_steppings }, 173 { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250", 174 generic_steppings }, 175 176 { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3", 177 generic_steppings }, 178 179 { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600", 180 generic_steppings }, 181 { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610", 182 generic_steppings }, 183 { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620", 184 generic_steppings }, 185 186 { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700", 187 generic_steppings }, 188 { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710", 189 generic_steppings }, 190 { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500", 191 generic_steppings }, 192 { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a", 193 generic_steppings }, 194 { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE", 195 generic_steppings }, 196 { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T", 197 generic_steppings }, 198 { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T", 199 generic_steppings }, 200 { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)", 201 generic_steppings }, 202 { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)", 203 generic_steppings }, 204 205 { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810", 206 generic_steppings }, 207 208 { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", 209 generic_steppings }, 210 { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T", 211 generic_steppings }, 212 { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", 213 generic_steppings }, 214 { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S", 215 generic_steppings }, 216 { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", 217 generic_steppings }, 218 { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", 219 generic_steppings }, 220 { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", 221 generic_steppings }, 222 { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", 223 generic_steppings }, 224 { CPU_ID_FA526, CPU_CLASS_ARM9TDMI, "FA526", 225 generic_steppings }, 226 { CPU_ID_FA626TE, CPU_CLASS_ARM9ES, "FA626TE", 227 generic_steppings }, 228 229 { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", 230 generic_steppings }, 231 232 { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", 233 generic_steppings }, 234 { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", 235 generic_steppings }, 236 { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S", 237 generic_steppings }, 238 239 { CPU_ID_CORTEXA7, CPU_CLASS_CORTEXA, "Cortex A7", 240 generic_steppings }, 241 { CPU_ID_CORTEXA8R1, CPU_CLASS_CORTEXA, "Cortex A8-r1", 242 generic_steppings }, 243 { CPU_ID_CORTEXA8R2, CPU_CLASS_CORTEXA, "Cortex A8-r2", 244 generic_steppings }, 245 { CPU_ID_CORTEXA8R3, CPU_CLASS_CORTEXA, "Cortex A8-r3", 246 generic_steppings }, 247 { CPU_ID_CORTEXA9R1, CPU_CLASS_CORTEXA, "Cortex A9-r1", 248 generic_steppings }, 249 { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEXA, "Cortex A9-r2", 250 generic_steppings }, 251 { CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEXA, "Cortex A9-r3", 252 generic_steppings }, 253 { CPU_ID_CORTEXA15, CPU_CLASS_CORTEXA, "Cortex A15", 254 generic_steppings }, 255 256 { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", 257 sa110_steppings }, 258 { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", 259 sa1100_steppings }, 260 { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", 261 sa1110_steppings }, 262 263 { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", 264 ixp12x0_steppings }, 265 266 { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", 267 xscale_steppings }, 268 269 { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", 270 i80321_steppings }, 271 { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", 272 i80321_steppings }, 273 { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", 274 i80321_steppings }, 275 { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", 276 i80321_steppings }, 277 278 { CPU_ID_81342, CPU_CLASS_XSCALE, "i81342", 279 i81342_steppings }, 280 281 { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz", 282 i80219_steppings }, 283 { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz", 284 i80219_steppings }, 285 286 { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x", 287 pxa27x_steppings }, 288 { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", 289 pxa2x0_steppings }, 290 { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", 291 pxa2x0_steppings }, 292 { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", 293 pxa2x0_steppings }, 294 { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", 295 pxa2x0_steppings }, 296 { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255", 297 pxa255_steppings }, 298 { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", 299 pxa2x0_steppings }, 300 301 { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", 302 ixp425_steppings }, 303 { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", 304 ixp425_steppings }, 305 { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", 306 ixp425_steppings }, 307 308 /* XXX ixp435 steppings? */ 309 { CPU_ID_IXP435, CPU_CLASS_XSCALE, "IXP435", 310 ixp425_steppings }, 311 312 { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S", 313 generic_steppings }, 314 { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S R1", 315 generic_steppings }, 316 { CPU_ID_ARM1176JZS, CPU_CLASS_ARM11J, "ARM1176JZ-S", 317 generic_steppings }, 318 319 { CPU_ID_MV88FR131, CPU_CLASS_MARVELL, "Feroceon 88FR131", 320 generic_steppings }, 321 322 { CPU_ID_MV88FR571_VD, CPU_CLASS_MARVELL, "Feroceon 88FR571-VD", 323 generic_steppings }, 324 { CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", 325 generic_steppings }, 326 { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", 327 generic_steppings }, 328 { CPU_ID_MV88SV584X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV584x", 329 generic_steppings }, 330 331 { 0, CPU_CLASS_NONE, NULL, NULL } 332}; 333 334struct cpu_classtab { 335 const char *class_name; 336 const char *class_option; 337}; 338 339const struct cpu_classtab cpu_classes[] = { 340 { "unknown", NULL }, /* CPU_CLASS_NONE */ 341 { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */ 342 { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */ 343 { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ 344 { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ 345 { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ 346 { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */ 347 { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ 348 { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */ 349 { "ARM9E-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9ES */ 350 { "ARM9EJ-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9EJS */ 351 { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ 352 { "ARM10EJ", "CPU_ARM10" }, /* CPU_CLASS_ARM10EJ */ 353 { "Cortex-A", "CPU_CORTEXA" }, /* CPU_CLASS_CORTEXA */ 354 { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */ 355 { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ 356 { "ARM11J", "CPU_ARM11" }, /* CPU_CLASS_ARM11J */ 357 { "Marvell", "CPU_MARVELL" }, /* CPU_CLASS_MARVELL */ 358}; 359 360/* 361 * Report the type of the specified arm processor. This uses the generic and 362 * arm specific information in the cpu structure to identify the processor. 363 * The remaining fields in the cpu structure are filled in appropriately. 364 */ 365 366static const char * const wtnames[] = { 367 "write-through", 368 "write-back", 369 "write-back", 370 "**unknown 3**", 371 "**unknown 4**", 372 "write-back-locking", /* XXX XScale-specific? */ 373 "write-back-locking-A", 374 "write-back-locking-B", 375 "**unknown 8**", 376 "**unknown 9**", 377 "**unknown 10**", 378 "**unknown 11**", 379 "**unknown 12**", 380 "**unknown 13**", 381 "write-back-locking-C", 382 "**unknown 15**", 383}; 384 385static void 386print_enadis(int enadis, char *s) 387{ 388 389 printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en"); 390} 391 392extern int ctrl; 393enum cpu_class cpu_class = CPU_CLASS_NONE; 394 395u_int cpu_pfr(int num) 396{ 397 u_int feat; 398 399 switch (num) { 400 case 0: 401 __asm __volatile("mrc p15, 0, %0, c0, c1, 0" 402 : "=r" (feat)); 403 break; 404 case 1: 405 __asm __volatile("mrc p15, 0, %0, c0, c1, 1" 406 : "=r" (feat)); 407 break; 408 default: 409 panic("Processor Feature Register %d not implemented", num); 410 break; 411 } 412 413 return (feat); 414} 415 416static 417void identify_armv7(void) 418{ 419 u_int feature; 420 421 printf("Supported features:"); 422 /* Get Processor Feature Register 0 */ 423 feature = cpu_pfr(0); 424 425 if (feature & ARM_PFR0_ARM_ISA_MASK) 426 printf(" ARM_ISA"); 427 428 if (feature & ARM_PFR0_THUMB2) 429 printf(" THUMB2"); 430 else if (feature & ARM_PFR0_THUMB) 431 printf(" THUMB"); 432 433 if (feature & ARM_PFR0_JAZELLE_MASK) 434 printf(" JAZELLE"); 435 436 if (feature & ARM_PFR0_THUMBEE_MASK) 437 printf(" THUMBEE"); 438 439 440 /* Get Processor Feature Register 1 */ 441 feature = cpu_pfr(1); 442 443 if (feature & ARM_PFR1_ARMV4_MASK) 444 printf(" ARMv4"); 445 446 if (feature & ARM_PFR1_SEC_EXT_MASK) 447 printf(" Security_Ext"); 448 449 if (feature & ARM_PFR1_MICROCTRL_MASK) 450 printf(" M_profile"); 451 452 printf("\n"); 453} 454 455void 456identify_arm_cpu(void) 457{ 458 u_int cpuid, reg, size, sets, ways; 459 u_int8_t type, linesize; 460 int i; 461 462 cpuid = cpu_id(); 463 464 if (cpuid == 0) { 465 printf("Processor failed probe - no CPU ID\n"); 466 return; 467 } 468 469 for (i = 0; cpuids[i].cpuid != 0; i++) 470 if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { 471 cpu_class = cpuids[i].cpu_class; 472 printf("CPU: %s %s (%s core)\n", 473 cpuids[i].cpu_name, 474 cpuids[i].cpu_steppings[cpuid & 475 CPU_ID_REVISION_MASK], 476 cpu_classes[cpu_class].class_name); 477 break; 478 } 479 if (cpuids[i].cpuid == 0) 480 printf("unknown CPU (ID = 0x%x)\n", cpuid); 481 482 printf(" "); 483 484 if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) { 485 identify_armv7(); 486 } else { 487 if (ctrl & CPU_CONTROL_BEND_ENABLE) 488 printf(" Big-endian"); 489 else 490 printf(" Little-endian"); 491 492 switch (cpu_class) { 493 case CPU_CLASS_ARM6: 494 case CPU_CLASS_ARM7: 495 case CPU_CLASS_ARM7TDMI: 496 case CPU_CLASS_ARM8: 497 print_enadis(ctrl & CPU_CONTROL_IDC_ENABLE, "IDC"); 498 break; 499 case CPU_CLASS_ARM9TDMI: 500 case CPU_CLASS_ARM9ES: 501 case CPU_CLASS_ARM9EJS: 502 case CPU_CLASS_ARM10E: 503 case CPU_CLASS_ARM10EJ: 504 case CPU_CLASS_SA1: 505 case CPU_CLASS_XSCALE: 506 case CPU_CLASS_ARM11J: 507 case CPU_CLASS_MARVELL: 508 print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC"); 509 print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC"); 510#ifdef CPU_XSCALE_81342 511 print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2"); 512#endif 513#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) 514 i = sheeva_control_ext(0, 0); 515 print_enadis(i & MV_WA_ENABLE, "WA"); 516 print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming"); 517 printf("\n "); 518 print_enadis((i & MV_BTB_DISABLE) == 0, "BTB"); 519 print_enadis(i & MV_L2_ENABLE, "L2"); 520 print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0, 521 "L2 prefetch"); 522 printf("\n "); 523#endif 524 break; 525 default: 526 break; 527 } 528 } 529 530 print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB"); 531 if (ctrl & CPU_CONTROL_LABT_ENABLE) 532 printf(" LABT"); 533 else 534 printf(" EABT"); 535 536 print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction"); 537 printf("\n"); 538 539 if (arm_cache_level) { 540 printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1, 541 arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1); 542 i = 0; 543 while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) { 544 printf("Cache level %d: \n", i + 1); 545 if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 546 type == CACHE_SEP_CACHE) { 547 reg = arm_cache_type[2 * i]; 548 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; 549 sets = CPUV7_CT_xSIZE_SET(reg) + 1; 550 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); 551 size = (ways * sets * linesize) / 1024; 552 553 if (type == CACHE_UNI_CACHE) 554 printf(" %dKB/%dB %d-way unified cache", size, linesize,ways); 555 else 556 printf(" %dKB/%dB %d-way data cache", size, linesize, ways); 557 if (reg & CPUV7_CT_CTYPE_WT) 558 printf(" WT"); 559 if (reg & CPUV7_CT_CTYPE_WB) 560 printf(" WB"); 561 if (reg & CPUV7_CT_CTYPE_RA) 562 printf(" Read-Alloc"); 563 if (reg & CPUV7_CT_CTYPE_WA) 564 printf(" Write-Alloc"); 565 printf("\n"); 566 } 567 568 if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 569 reg = arm_cache_type[(2 * i) + 1]; 570 571 ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; 572 sets = CPUV7_CT_xSIZE_SET(reg) + 1; 573 linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); 574 size = (ways * sets * linesize) / 1024; 575 576 printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways); 577 if (reg & CPUV7_CT_CTYPE_WT) 578 printf(" WT"); 579 if (reg & CPUV7_CT_CTYPE_WB) 580 printf(" WB"); 581 if (reg & CPUV7_CT_CTYPE_RA) 582 printf(" Read-Alloc"); 583 if (reg & CPUV7_CT_CTYPE_WA) 584 printf(" Write-Alloc"); 585 printf("\n"); 586 } 587 i++; 588 } 589 } else { 590 /* Print cache info. */ 591 if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) 592 return; 593 594 if (arm_pcache_unified) { 595 printf(" %dKB/%dB %d-way %s unified cache\n", 596 arm_pdcache_size / 1024, 597 arm_pdcache_line_size, arm_pdcache_ways, 598 wtnames[arm_pcache_type]); 599 } else { 600 printf(" %dKB/%dB %d-way instruction cache\n", 601 arm_picache_size / 1024, 602 arm_picache_line_size, arm_picache_ways); 603 printf(" %dKB/%dB %d-way %s data cache\n", 604 arm_pdcache_size / 1024, 605 arm_pdcache_line_size, arm_pdcache_ways, 606 wtnames[arm_pcache_type]); 607 } 608 } 609} 610