identcpu.c (285311) | identcpu.c (292954) |
---|---|
1/*- 2 * Copyright (c) 2014 Andrew Turner 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Semihalf 7 * under sponsorship of the FreeBSD Foundation. 8 * --- 16 unchanged lines hidden (view full) --- 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2014 Andrew Turner 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Semihalf 7 * under sponsorship of the FreeBSD Foundation. 8 * --- 16 unchanged lines hidden (view full) --- 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/arm64/arm64/identcpu.c 285311 2015-07-09 11:32:29Z zbb $"); | 33__FBSDID("$FreeBSD: head/sys/arm64/arm64/identcpu.c 292954 2015-12-30 17:36:34Z andrew $"); |
34 35#include <sys/param.h> 36#include <sys/pcpu.h> 37#include <sys/sysctl.h> 38#include <sys/systm.h> 39 | 34 35#include <sys/param.h> 36#include <sys/pcpu.h> 37#include <sys/sysctl.h> 38#include <sys/systm.h> 39 |
40#include <machine/atomic.h> |
|
40#include <machine/cpu.h> 41#include <machine/cpufunc.h> 42 | 41#include <machine/cpu.h> 42#include <machine/cpufunc.h> 43 |
44static int ident_lock; 45 |
|
43char machine[] = "arm64"; 44 45SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, 46 "Machine class"); 47 48/* 49 * Per-CPU affinity as provided in MPIDR_EL1 50 * Indexed by CPU number in logical order selected by the system. 51 * Relevant fields can be extracted using CPU_AFFn macros, 52 * Aff3.Aff2.Aff1.Aff0 construct a unique CPU address in the system. 53 * 54 * Fields used by us: 55 * Aff1 - Cluster number 56 * Aff0 - CPU number in Aff1 cluster 57 */ 58uint64_t __cpu_affinity[MAXCPU]; | 46char machine[] = "arm64"; 47 48SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, 49 "Machine class"); 50 51/* 52 * Per-CPU affinity as provided in MPIDR_EL1 53 * Indexed by CPU number in logical order selected by the system. 54 * Relevant fields can be extracted using CPU_AFFn macros, 55 * Aff3.Aff2.Aff1.Aff0 construct a unique CPU address in the system. 56 * 57 * Fields used by us: 58 * Aff1 - Cluster number 59 * Aff0 - CPU number in Aff1 cluster 60 */ 61uint64_t __cpu_affinity[MAXCPU]; |
62static u_int cpu_aff_levels; |
|
59 60struct cpu_desc { 61 u_int cpu_impl; 62 u_int cpu_part_num; 63 u_int cpu_variant; 64 u_int cpu_revision; 65 const char *cpu_impl_name; 66 const char *cpu_part_name; | 63 64struct cpu_desc { 65 u_int cpu_impl; 66 u_int cpu_part_num; 67 u_int cpu_variant; 68 u_int cpu_revision; 69 const char *cpu_impl_name; 70 const char *cpu_part_name; |
71 72 uint64_t mpidr; 73 uint64_t id_aa64afr0; 74 uint64_t id_aa64afr1; 75 uint64_t id_aa64dfr0; 76 uint64_t id_aa64dfr1; 77 uint64_t id_aa64isar0; 78 uint64_t id_aa64isar1; 79 uint64_t id_aa64mmfr0; 80 uint64_t id_aa64mmfr1; 81 uint64_t id_aa64pfr0; 82 uint64_t id_aa64pfr1; |
|
67}; 68 69struct cpu_desc cpu_desc[MAXCPU]; | 83}; 84 85struct cpu_desc cpu_desc[MAXCPU]; |
86static u_int cpu_print_regs; 87#define PRINT_ID_AA64_AFR0 0x00000001 88#define PRINT_ID_AA64_AFR1 0x00000002 89#define PRINT_ID_AA64_DFR0 0x00000004 90#define PRINT_ID_AA64_DFR1 0x00000008 91#define PRINT_ID_AA64_ISAR0 0x00000010 92#define PRINT_ID_AA64_ISAR1 0x00000020 93#define PRINT_ID_AA64_MMFR0 0x00000040 94#define PRINT_ID_AA64_MMFR1 0x00000080 95#define PRINT_ID_AA64_PFR0 0x00000100 96#define PRINT_ID_AA64_PFR1 0x00000200 |
|
70 71struct cpu_parts { 72 u_int part_id; 73 const char *part_name; 74}; 75#define CPU_PART_NONE { 0, "Unknown Processor" } 76 77struct cpu_implementers { --- 41 unchanged lines hidden (view full) --- 119 { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none }, 120 { CPU_IMPL_APM, "APM", cpu_parts_none }, 121 { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none }, 122 { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none }, 123 { CPU_IMPL_INTEL, "Intel", cpu_parts_none }, 124 CPU_IMPLEMENTER_NONE, 125}; 126 | 97 98struct cpu_parts { 99 u_int part_id; 100 const char *part_name; 101}; 102#define CPU_PART_NONE { 0, "Unknown Processor" } 103 104struct cpu_implementers { --- 41 unchanged lines hidden (view full) --- 146 { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none }, 147 { CPU_IMPL_APM, "APM", cpu_parts_none }, 148 { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none }, 149 { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none }, 150 { CPU_IMPL_INTEL, "Intel", cpu_parts_none }, 151 CPU_IMPLEMENTER_NONE, 152}; 153 |
127void identify_cpu(void); | 154void 155print_cpu_features(u_int cpu) 156{ 157 int printed; |
128 | 158 |
159 printf("CPU%3d: %s %s r%dp%d", cpu, cpu_desc[cpu].cpu_impl_name, 160 cpu_desc[cpu].cpu_part_name, cpu_desc[cpu].cpu_variant, 161 cpu_desc[cpu].cpu_revision); 162 163 printf(" affinity:"); 164 switch(cpu_aff_levels) { 165 default: 166 case 4: 167 printf(" %2d", CPU_AFF3(cpu_desc[cpu].mpidr)); 168 /* FALLTHROUGH */ 169 case 3: 170 printf(" %2d", CPU_AFF2(cpu_desc[cpu].mpidr)); 171 /* FALLTHROUGH */ 172 case 2: 173 printf(" %2d", CPU_AFF1(cpu_desc[cpu].mpidr)); 174 /* FALLTHROUGH */ 175 case 1: 176 case 0: /* On UP this will be zero */ 177 printf(" %2d", CPU_AFF0(cpu_desc[cpu].mpidr)); 178 break; 179 } 180 printf("\n"); 181 182 if (cpu != 0 && cpu_print_regs == 0) 183 return; 184 185#define SEP_STR ((printed++) == 0) ? "" : "," 186 187 /* AArch64 Instruction Set Attribute Register 0 */ 188 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR0) != 0) { 189 printed = 0; 190 printf(" Instruction Set Attributes 0 = <"); 191 switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) { 192 case ID_AA64ISAR0_AES_NONE: 193 break; 194 case ID_AA64ISAR0_AES_BASE: 195 printf("%sAES", SEP_STR); 196 break; 197 case ID_AA64ISAR0_AES_PMULL: 198 printf("%sAES+PMULL", SEP_STR); 199 break; 200 default: 201 printf("%sUnknown AES", SEP_STR); 202 break; 203 } 204 205 switch (ID_AA64ISAR0_SHA1(cpu_desc[cpu].id_aa64isar0)) { 206 case ID_AA64ISAR0_SHA1_NONE: 207 break; 208 case ID_AA64ISAR0_SHA1_BASE: 209 printf("%sSHA1", SEP_STR); 210 break; 211 default: 212 printf("%sUnknown SHA1", SEP_STR); 213 break; 214 } 215 216 switch (ID_AA64ISAR0_SHA2(cpu_desc[cpu].id_aa64isar0)) { 217 case ID_AA64ISAR0_SHA2_NONE: 218 break; 219 case ID_AA64ISAR0_SHA2_BASE: 220 printf("%sSHA2", SEP_STR); 221 break; 222 default: 223 printf("%sUnknown SHA2", SEP_STR); 224 break; 225 } 226 227 switch (ID_AA64ISAR0_CRC32(cpu_desc[cpu].id_aa64isar0)) { 228 case ID_AA64ISAR0_CRC32_NONE: 229 break; 230 case ID_AA64ISAR0_CRC32_BASE: 231 printf("%sCRC32", SEP_STR); 232 break; 233 default: 234 printf("%sUnknown CRC32", SEP_STR); 235 break; 236 } 237 238 if ((cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK) != 0) 239 printf("%s%#lx", SEP_STR, 240 cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK); 241 242 printf(">\n"); 243 } 244 245 /* AArch64 Instruction Set Attribute Register 1 */ 246 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR1) != 0) { 247 printf(" Instruction Set Attributes 1 = <%#lx>\n", 248 cpu_desc[cpu].id_aa64isar1); 249 } 250 251 /* AArch64 Processor Feature Register 0 */ 252 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR0) != 0) { 253 printed = 0; 254 printf(" Processor Features 0 = <"); 255 switch (ID_AA64PFR0_GIC(cpu_desc[cpu].id_aa64pfr0)) { 256 case ID_AA64PFR0_GIC_CPUIF_NONE: 257 break; 258 case ID_AA64PFR0_GIC_CPUIF_EN: 259 printf("%sGIC", SEP_STR); 260 break; 261 default: 262 printf("%sUnknown GIC interface", SEP_STR); 263 break; 264 } 265 266 switch (ID_AA64PFR0_ADV_SIMD(cpu_desc[cpu].id_aa64pfr0)) { 267 case ID_AA64PFR0_ADV_SIMD_NONE: 268 break; 269 case ID_AA64PFR0_ADV_SIMD_IMPL: 270 printf("%sAdvSIMD", SEP_STR); 271 break; 272 default: 273 printf("%sUnknown AdvSIMD", SEP_STR); 274 break; 275 } 276 277 switch (ID_AA64PFR0_FP(cpu_desc[cpu].id_aa64pfr0)) { 278 case ID_AA64PFR0_FP_NONE: 279 break; 280 case ID_AA64PFR0_FP_IMPL: 281 printf("%sFloat", SEP_STR); 282 break; 283 default: 284 printf("%sUnknown Float", SEP_STR); 285 break; 286 } 287 288 switch (ID_AA64PFR0_EL3(cpu_desc[cpu].id_aa64pfr0)) { 289 case ID_AA64PFR0_EL3_NONE: 290 printf("%sNo EL3", SEP_STR); 291 break; 292 case ID_AA64PFR0_EL3_64: 293 printf("%sEL3", SEP_STR); 294 break; 295 case ID_AA64PFR0_EL3_64_32: 296 printf("%sEL3 32", SEP_STR); 297 break; 298 default: 299 printf("%sUnknown EL3", SEP_STR); 300 break; 301 } 302 303 switch (ID_AA64PFR0_EL2(cpu_desc[cpu].id_aa64pfr0)) { 304 case ID_AA64PFR0_EL2_NONE: 305 printf("%sNo EL2", SEP_STR); 306 break; 307 case ID_AA64PFR0_EL2_64: 308 printf("%sEL2", SEP_STR); 309 break; 310 case ID_AA64PFR0_EL2_64_32: 311 printf("%sEL2 32", SEP_STR); 312 break; 313 default: 314 printf("%sUnknown EL2", SEP_STR); 315 break; 316 } 317 318 switch (ID_AA64PFR0_EL1(cpu_desc[cpu].id_aa64pfr0)) { 319 case ID_AA64PFR0_EL1_64: 320 printf("%sEL1", SEP_STR); 321 break; 322 case ID_AA64PFR0_EL1_64_32: 323 printf("%sEL1 32", SEP_STR); 324 break; 325 default: 326 printf("%sUnknown EL1", SEP_STR); 327 break; 328 } 329 330 switch (ID_AA64PFR0_EL0(cpu_desc[cpu].id_aa64pfr0)) { 331 case ID_AA64PFR0_EL0_64: 332 printf("%sEL0", SEP_STR); 333 break; 334 case ID_AA64PFR0_EL0_64_32: 335 printf("%sEL0 32", SEP_STR); 336 break; 337 default: 338 printf("%sUnknown EL0", SEP_STR); 339 break; 340 } 341 342 if ((cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK) != 0) 343 printf("%s%#lx", SEP_STR, 344 cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK); 345 346 printf(">\n"); 347 } 348 349 /* AArch64 Processor Feature Register 1 */ 350 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR1) != 0) { 351 printf(" Processor Features 1 = <%#lx>\n", 352 cpu_desc[cpu].id_aa64pfr1); 353 } 354 355 /* AArch64 Memory Model Feature Register 0 */ 356 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR0) != 0) { 357 printed = 0; 358 printf(" Memory Model Features 0 = <"); 359 switch (ID_AA64MMFR0_TGRAN4(cpu_desc[cpu].id_aa64mmfr0)) { 360 case ID_AA64MMFR0_TGRAN4_NONE: 361 break; 362 case ID_AA64MMFR0_TGRAN4_IMPL: 363 printf("%s4k Granule", SEP_STR); 364 break; 365 default: 366 printf("%sUnknown 4k Granule", SEP_STR); 367 break; 368 } 369 370 switch (ID_AA64MMFR0_TGRAN16(cpu_desc[cpu].id_aa64mmfr0)) { 371 case ID_AA64MMFR0_TGRAN16_NONE: 372 break; 373 case ID_AA64MMFR0_TGRAN16_IMPL: 374 printf("%s16k Granule", SEP_STR); 375 break; 376 default: 377 printf("%sUnknown 16k Granule", SEP_STR); 378 break; 379 } 380 381 switch (ID_AA64MMFR0_TGRAN64(cpu_desc[cpu].id_aa64mmfr0)) { 382 case ID_AA64MMFR0_TGRAN64_NONE: 383 break; 384 case ID_AA64MMFR0_TGRAN64_IMPL: 385 printf("%s64k Granule", SEP_STR); 386 break; 387 default: 388 printf("%sUnknown 64k Granule", SEP_STR); 389 break; 390 } 391 392 switch (ID_AA64MMFR0_BIGEND(cpu_desc[cpu].id_aa64mmfr0)) { 393 case ID_AA64MMFR0_BIGEND_FIXED: 394 break; 395 case ID_AA64MMFR0_BIGEND_MIXED: 396 printf("%sMixedEndian", SEP_STR); 397 break; 398 default: 399 printf("%sUnknown Endian switching", SEP_STR); 400 break; 401 } 402 403 switch (ID_AA64MMFR0_BIGEND_EL0(cpu_desc[cpu].id_aa64mmfr0)) { 404 case ID_AA64MMFR0_BIGEND_EL0_FIXED: 405 break; 406 case ID_AA64MMFR0_BIGEND_EL0_MIXED: 407 printf("%sEL0 MixEndian", SEP_STR); 408 break; 409 default: 410 printf("%sUnknown EL0 Endian switching", SEP_STR); 411 break; 412 } 413 414 switch (ID_AA64MMFR0_S_NS_MEM(cpu_desc[cpu].id_aa64mmfr0)) { 415 case ID_AA64MMFR0_S_NS_MEM_NONE: 416 break; 417 case ID_AA64MMFR0_S_NS_MEM_DISTINCT: 418 printf("%sS/NS Mem", SEP_STR); 419 break; 420 default: 421 printf("%sUnknown S/NS Mem", SEP_STR); 422 break; 423 } 424 425 switch (ID_AA64MMFR0_ASID_BITS(cpu_desc[cpu].id_aa64mmfr0)) { 426 case ID_AA64MMFR0_ASID_BITS_8: 427 printf("%s8bit ASID", SEP_STR); 428 break; 429 case ID_AA64MMFR0_ASID_BITS_16: 430 printf("%s16bit ASID", SEP_STR); 431 break; 432 default: 433 printf("%sUnknown ASID", SEP_STR); 434 break; 435 } 436 437 switch (ID_AA64MMFR0_PA_RANGE(cpu_desc[cpu].id_aa64mmfr0)) { 438 case ID_AA64MMFR0_PA_RANGE_4G: 439 printf("%s4GB PA", SEP_STR); 440 break; 441 case ID_AA64MMFR0_PA_RANGE_64G: 442 printf("%s64GB PA", SEP_STR); 443 break; 444 case ID_AA64MMFR0_PA_RANGE_1T: 445 printf("%s1TB PA", SEP_STR); 446 break; 447 case ID_AA64MMFR0_PA_RANGE_4T: 448 printf("%s4TB PA", SEP_STR); 449 break; 450 case ID_AA64MMFR0_PA_RANGE_16T: 451 printf("%s16TB PA", SEP_STR); 452 break; 453 case ID_AA64MMFR0_PA_RANGE_256T: 454 printf("%s256TB PA", SEP_STR); 455 break; 456 default: 457 printf("%sUnknown PA Range", SEP_STR); 458 break; 459 } 460 461 if ((cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK) != 0) 462 printf("%s%#lx", SEP_STR, 463 cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK); 464 printf(">\n"); 465 } 466 467 /* AArch64 Memory Model Feature Register 1 */ 468 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR1) != 0) { 469 printf(" Memory Model Features 1 = <%#lx>\n", 470 cpu_desc[cpu].id_aa64mmfr1); 471 } 472 473 /* AArch64 Debug Feature Register 0 */ 474 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR0) != 0) { 475 printed = 0; 476 printf(" Debug Features 0 = <"); 477 printf("%s%lu CTX Breakpoints", SEP_STR, 478 ID_AA64DFR0_CTX_CMPS(cpu_desc[cpu].id_aa64dfr0)); 479 480 printf("%s%lu Watchpoints", SEP_STR, 481 ID_AA64DFR0_WRPS(cpu_desc[cpu].id_aa64dfr0)); 482 483 printf("%s%lu Breakpoints", SEP_STR, 484 ID_AA64DFR0_BRPS(cpu_desc[cpu].id_aa64dfr0)); 485 486 switch (ID_AA64DFR0_PMU_VER(cpu_desc[cpu].id_aa64dfr0)) { 487 case ID_AA64DFR0_PMU_VER_NONE: 488 break; 489 case ID_AA64DFR0_PMU_VER_3: 490 printf("%sPMUv3", SEP_STR); 491 break; 492 case ID_AA64DFR0_PMU_VER_IMPL: 493 printf("%sImplementation defined PMU", SEP_STR); 494 break; 495 default: 496 printf("%sUnknown PMU", SEP_STR); 497 break; 498 } 499 500 switch (ID_AA64DFR0_TRACE_VER(cpu_desc[cpu].id_aa64dfr0)) { 501 case ID_AA64DFR0_TRACE_VER_NONE: 502 break; 503 case ID_AA64DFR0_TRACE_VER_IMPL: 504 printf("%sTrace", SEP_STR); 505 break; 506 default: 507 printf("%sUnknown Trace", SEP_STR); 508 break; 509 } 510 511 switch (ID_AA64DFR0_DEBUG_VER(cpu_desc[cpu].id_aa64dfr0)) { 512 case ID_AA64DFR0_DEBUG_VER_8: 513 printf("%sDebug v8", SEP_STR); 514 break; 515 default: 516 printf("%sUnknown Debug", SEP_STR); 517 break; 518 } 519 520 if (cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK) 521 printf("%s%#lx", SEP_STR, 522 cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK); 523 printf(">\n"); 524 } 525 526 /* AArch64 Memory Model Feature Register 1 */ 527 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR1) != 0) { 528 printf(" Debug Features 1 = <%#lx>\n", 529 cpu_desc[cpu].id_aa64dfr1); 530 } 531 532 /* AArch64 Auxiliary Feature Register 0 */ 533 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR0) != 0) { 534 printf(" Auxiliary Features 0 = <%#lx>\n", 535 cpu_desc[cpu].id_aa64afr0); 536 } 537 538 /* AArch64 Auxiliary Feature Register 1 */ 539 if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR1) != 0) { 540 printf(" Auxiliary Features 1 = <%#lx>\n", 541 cpu_desc[cpu].id_aa64afr1); 542 } 543 544#undef SEP_STR 545} 546 |
|
129void 130identify_cpu(void) 131{ 132 u_int midr; 133 u_int impl_id; 134 u_int part_id; 135 u_int cpu; | 547void 548identify_cpu(void) 549{ 550 u_int midr; 551 u_int impl_id; 552 u_int part_id; 553 u_int cpu; |
136 uint64_t mpidr; | |
137 size_t i; 138 const struct cpu_parts *cpu_partsp = NULL; 139 140 cpu = PCPU_GET(cpuid); 141 midr = get_midr(); 142 143 /* 144 * Store midr to pcpu to allow fast reading --- 21 unchanged lines hidden (view full) --- 166 break; 167 } 168 } 169 170 cpu_desc[cpu].cpu_revision = CPU_REV(midr); 171 cpu_desc[cpu].cpu_variant = CPU_VAR(midr); 172 173 /* Save affinity for current CPU */ | 554 size_t i; 555 const struct cpu_parts *cpu_partsp = NULL; 556 557 cpu = PCPU_GET(cpuid); 558 midr = get_midr(); 559 560 /* 561 * Store midr to pcpu to allow fast reading --- 21 unchanged lines hidden (view full) --- 583 break; 584 } 585 } 586 587 cpu_desc[cpu].cpu_revision = CPU_REV(midr); 588 cpu_desc[cpu].cpu_variant = CPU_VAR(midr); 589 590 /* Save affinity for current CPU */ |
174 mpidr = get_mpidr(); 175 CPU_AFFINITY(cpu) = mpidr & CPU_AFF_MASK; | 591 cpu_desc[cpu].mpidr = get_mpidr(); 592 CPU_AFFINITY(cpu) = cpu_desc[cpu].mpidr & CPU_AFF_MASK; |
176 | 593 |
177 /* Print details for boot CPU or if we want verbose output */ 178 if (cpu == 0 || bootverbose) { 179 printf("CPU(%d): %s %s r%dp%d\n", cpu, 180 cpu_desc[cpu].cpu_impl_name, 181 cpu_desc[cpu].cpu_part_name, 182 cpu_desc[cpu].cpu_variant, 183 cpu_desc[cpu].cpu_revision); 184 } | 594 cpu_desc[cpu].id_aa64dfr0 = READ_SPECIALREG(id_aa64dfr0_el1); 595 cpu_desc[cpu].id_aa64dfr1 = READ_SPECIALREG(id_aa64dfr1_el1); 596 cpu_desc[cpu].id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1); 597 cpu_desc[cpu].id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1); 598 cpu_desc[cpu].id_aa64mmfr0 = READ_SPECIALREG(id_aa64mmfr0_el1); 599 cpu_desc[cpu].id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); 600 cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1); 601 cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1); |
185 | 602 |
186 if (bootverbose) 187 printf("CPU%u affinity: %u.%u.%u.%u\n", 0, CPU_AFF0(mpidr), 188 CPU_AFF1(mpidr), CPU_AFF2(mpidr), CPU_AFF3(mpidr)); | 603 if (cpu != 0) { 604 /* 605 * This code must run on one cpu at a time, but we are 606 * not scheduling on the current core so implement a 607 * simple spinlock. 608 */ 609 while (atomic_cmpset_acq_int(&ident_lock, 0, 1) == 0) 610 __asm __volatile("wfe" ::: "memory"); 611 612 switch (cpu_aff_levels) { 613 case 0: 614 if (CPU_AFF0(cpu_desc[cpu].mpidr) != 615 CPU_AFF0(cpu_desc[0].mpidr)) 616 cpu_aff_levels = 1; 617 /* FALLTHROUGH */ 618 case 1: 619 if (CPU_AFF1(cpu_desc[cpu].mpidr) != 620 CPU_AFF1(cpu_desc[0].mpidr)) 621 cpu_aff_levels = 2; 622 /* FALLTHROUGH */ 623 case 2: 624 if (CPU_AFF2(cpu_desc[cpu].mpidr) != 625 CPU_AFF2(cpu_desc[0].mpidr)) 626 cpu_aff_levels = 3; 627 /* FALLTHROUGH */ 628 case 3: 629 if (CPU_AFF3(cpu_desc[cpu].mpidr) != 630 CPU_AFF3(cpu_desc[0].mpidr)) 631 cpu_aff_levels = 4; 632 break; 633 } 634 635 if (cpu_desc[cpu].id_aa64afr0 != cpu_desc[0].id_aa64afr0) 636 cpu_print_regs |= PRINT_ID_AA64_AFR0; 637 if (cpu_desc[cpu].id_aa64afr1 != cpu_desc[0].id_aa64afr1) 638 cpu_print_regs |= PRINT_ID_AA64_AFR1; 639 640 if (cpu_desc[cpu].id_aa64dfr0 != cpu_desc[0].id_aa64dfr0) 641 cpu_print_regs |= PRINT_ID_AA64_DFR0; 642 if (cpu_desc[cpu].id_aa64dfr1 != cpu_desc[0].id_aa64dfr1) 643 cpu_print_regs |= PRINT_ID_AA64_DFR1; 644 645 if (cpu_desc[cpu].id_aa64isar0 != cpu_desc[0].id_aa64isar0) 646 cpu_print_regs |= PRINT_ID_AA64_ISAR0; 647 if (cpu_desc[cpu].id_aa64isar1 != cpu_desc[0].id_aa64isar1) 648 cpu_print_regs |= PRINT_ID_AA64_ISAR1; 649 650 if (cpu_desc[cpu].id_aa64mmfr0 != cpu_desc[0].id_aa64mmfr0) 651 cpu_print_regs |= PRINT_ID_AA64_MMFR0; 652 if (cpu_desc[cpu].id_aa64mmfr1 != cpu_desc[0].id_aa64mmfr1) 653 cpu_print_regs |= PRINT_ID_AA64_MMFR1; 654 655 if (cpu_desc[cpu].id_aa64pfr0 != cpu_desc[0].id_aa64pfr0) 656 cpu_print_regs |= PRINT_ID_AA64_PFR0; 657 if (cpu_desc[cpu].id_aa64pfr1 != cpu_desc[0].id_aa64pfr1) 658 cpu_print_regs |= PRINT_ID_AA64_PFR1; 659 660 /* Wake up the other CPUs */ 661 atomic_store_rel_int(&ident_lock, 0); 662 __asm __volatile("sev" ::: "memory"); 663 } |
189} | 664} |