Deleted Added
full compact
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}