| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: aarch64.c,v 1.7 2019/05/09 07:38:44 mrg Exp $ */ | | 1 | /* $NetBSD: aarch64.c,v 1.8 2020/01/28 17:36:42 maxv Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> | | 4 | * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -19,27 +19,27 @@ | | | @@ -19,27 +19,27 @@ |
19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | | 19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | | 20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | | 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | | | 30 | |
31 | #ifndef lint | | 31 | #ifndef lint |
32 | __RCSID("$NetBSD: aarch64.c,v 1.7 2019/05/09 07:38:44 mrg Exp $"); | | 32 | __RCSID("$NetBSD: aarch64.c,v 1.8 2020/01/28 17:36:42 maxv Exp $"); |
33 | #endif /* no lint */ | | 33 | #endif /* no lint */ |
34 | | | 34 | |
35 | #include <sys/types.h> | | 35 | #include <sys/types.h> |
36 | #include <sys/cpuio.h> | | 36 | #include <sys/cpuio.h> |
37 | #include <sys/sysctl.h> | | 37 | #include <sys/sysctl.h> |
38 | #include <stdio.h> | | 38 | #include <stdio.h> |
39 | #include <stdbool.h> | | 39 | #include <stdbool.h> |
40 | #include <stdlib.h> | | 40 | #include <stdlib.h> |
41 | #include <string.h> | | 41 | #include <string.h> |
42 | #include <inttypes.h> | | 42 | #include <inttypes.h> |
43 | #include <err.h> | | 43 | #include <err.h> |
44 | | | 44 | |
45 | #include <arm/cputypes.h> | | 45 | #include <arm/cputypes.h> |
| @@ -148,26 +148,61 @@ struct fieldinfo id_aa64pfr0_fieldinfo[] | | | @@ -148,26 +148,61 @@ struct fieldinfo id_aa64pfr0_fieldinfo[] |
148 | [15] = "No Advanced SIMD" | | 148 | [15] = "No Advanced SIMD" |
149 | } | | 149 | } |
150 | }, | | 150 | }, |
151 | { | | 151 | { |
152 | .bitpos = 24, .bitwidth = 4, .name = "GIC", | | 152 | .bitpos = 24, .bitwidth = 4, .name = "GIC", |
153 | .info = (const char *[16]) { /* 16=4bit */ | | 153 | .info = (const char *[16]) { /* 16=4bit */ |
154 | [0] = "No GIC", | | 154 | [0] = "No GIC", |
155 | [1] = "GICv3" | | 155 | [1] = "GICv3" |
156 | } | | 156 | } |
157 | }, | | 157 | }, |
158 | { .bitwidth = 0 } /* end of table */ | | 158 | { .bitwidth = 0 } /* end of table */ |
159 | }; | | 159 | }; |
160 | | | 160 | |
| | | 161 | /* ID_AA64PFR1_EL1 - AArch64 Processor Feature Register 1 */ |
| | | 162 | struct fieldinfo id_aa64pfr1_fieldinfo[] = { |
| | | 163 | { |
| | | 164 | .bitpos = 0, .bitwidth = 4, .name = "BT", |
| | | 165 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 166 | [0] = "Branch Target Identification not implemented", |
| | | 167 | [1] = "Branch Target Identification implemented", |
| | | 168 | } |
| | | 169 | }, |
| | | 170 | { |
| | | 171 | .bitpos = 4, .bitwidth = 4, .name = "SSBS", |
| | | 172 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 173 | [0] = "Speculative Store Bypassing control not implemented", |
| | | 174 | [1] = "Speculative Store Bypassing control implemented", |
| | | 175 | [2] = "Speculative Store Bypassing control implemented, plus MSR/MRS" |
| | | 176 | } |
| | | 177 | }, |
| | | 178 | { |
| | | 179 | .bitpos = 8, .bitwidth = 4, .name = "MTE", |
| | | 180 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 181 | [0] = "Tagged Memory Extension not implemented", |
| | | 182 | [1] = "Tagged Memory Extension implemented, EL0 only", |
| | | 183 | [2] = "Tagged Memory Extension implemented" |
| | | 184 | } |
| | | 185 | }, |
| | | 186 | { |
| | | 187 | .bitpos = 12, .bitwidth = 4, .name = "RAS_frac", |
| | | 188 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 189 | [0] = "Regular RAS", |
| | | 190 | [1] = "RAS plus registers", |
| | | 191 | } |
| | | 192 | }, |
| | | 193 | { .bitwidth = 0 } /* end of table */ |
| | | 194 | }; |
| | | 195 | |
161 | /* ID_AA64ISAR0_EL1 - AArch64 Instruction Set Attribute Register 0 */ | | 196 | /* ID_AA64ISAR0_EL1 - AArch64 Instruction Set Attribute Register 0 */ |
162 | struct fieldinfo id_aa64isar0_fieldinfo[] = { | | 197 | struct fieldinfo id_aa64isar0_fieldinfo[] = { |
163 | { | | 198 | { |
164 | .bitpos = 4, .bitwidth = 4, .name = "AES", | | 199 | .bitpos = 4, .bitwidth = 4, .name = "AES", |
165 | .info = (const char *[16]) { /* 16=4bit */ | | 200 | .info = (const char *[16]) { /* 16=4bit */ |
166 | [0] = "No AES", | | 201 | [0] = "No AES", |
167 | [1] = "AESE/AESD/AESMC/AESIMC", | | 202 | [1] = "AESE/AESD/AESMC/AESIMC", |
168 | [2] = "AESE/AESD/AESMC/AESIMC+PMULL/PMULL2" | | 203 | [2] = "AESE/AESD/AESMC/AESIMC+PMULL/PMULL2" |
169 | } | | 204 | } |
170 | }, | | 205 | }, |
171 | { | | 206 | { |
172 | .bitpos = 8, .bitwidth = 4, .name = "SHA1", | | 207 | .bitpos = 8, .bitwidth = 4, .name = "SHA1", |
173 | .info = (const char *[16]) { /* 16=4bit */ | | 208 | .info = (const char *[16]) { /* 16=4bit */ |
| @@ -248,26 +283,90 @@ struct fieldinfo id_aa64mmfr0_fieldinfo[ | | | @@ -248,26 +283,90 @@ struct fieldinfo id_aa64mmfr0_fieldinfo[ |
248 | [15] = "No 64KB granule" | | 283 | [15] = "No 64KB granule" |
249 | } | | 284 | } |
250 | }, | | 285 | }, |
251 | { | | 286 | { |
252 | .bitpos = 28, .bitwidth = 4, .name = "TGran4", | | 287 | .bitpos = 28, .bitwidth = 4, .name = "TGran4", |
253 | .info = (const char *[16]) { /* 16=4bit */ | | 288 | .info = (const char *[16]) { /* 16=4bit */ |
254 | [0] = "4KB granule", | | 289 | [0] = "4KB granule", |
255 | [15] = "No 4KB granule" | | 290 | [15] = "No 4KB granule" |
256 | } | | 291 | } |
257 | }, | | 292 | }, |
258 | { .bitwidth = 0 } /* end of table */ | | 293 | { .bitwidth = 0 } /* end of table */ |
259 | }; | | 294 | }; |
260 | | | 295 | |
| | | 296 | /* ID_AA64MMFR1_EL1 - AArch64 Memory Model Feature Register 1 */ |
| | | 297 | struct fieldinfo id_aa64mmfr1_fieldinfo[] = { |
| | | 298 | { |
| | | 299 | .bitpos = 0, .bitwidth = 4, .name = "HAFDBS", |
| | | 300 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 301 | [0] = "Access and Dirty flags not supported", |
| | | 302 | [1] = "Access flag supported", |
| | | 303 | [2] = "Access and Dirty flags supported", |
| | | 304 | } |
| | | 305 | }, |
| | | 306 | { |
| | | 307 | .bitpos = 4, .bitwidth = 4, .name = "VMIDBits", |
| | | 308 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 309 | [0] = "8bits", |
| | | 310 | [2] = "16bits" |
| | | 311 | } |
| | | 312 | }, |
| | | 313 | { |
| | | 314 | .bitpos = 8, .bitwidth = 4, .name = "VH", |
| | | 315 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 316 | [0] = "Virtualization Host Extensions not supported", |
| | | 317 | [1] = "Virtualization Host Extensions supported", |
| | | 318 | } |
| | | 319 | }, |
| | | 320 | { |
| | | 321 | .bitpos = 12, .bitwidth = 4, .name = "HPDS", |
| | | 322 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 323 | [0] = "Disabling of hierarchical controls not supported", |
| | | 324 | [1] = "Disabling of hierarchical controls supported", |
| | | 325 | [2] = "Disabling of hierarchical controls supported, plus PTD" |
| | | 326 | } |
| | | 327 | }, |
| | | 328 | { |
| | | 329 | .bitpos = 16, .bitwidth = 4, .name = "LO", |
| | | 330 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 331 | [0] = "LORegions not supported", |
| | | 332 | [1] = "LORegions supported" |
| | | 333 | } |
| | | 334 | }, |
| | | 335 | { |
| | | 336 | .bitpos = 20, .bitwidth = 4, .name = "PAN", |
| | | 337 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 338 | [0] = "PAN not supported", |
| | | 339 | [1] = "PAN supported", |
| | | 340 | [2] = "PAN supported, and instructions supported" |
| | | 341 | } |
| | | 342 | }, |
| | | 343 | { |
| | | 344 | .bitpos = 24, .bitwidth = 4, .name = "SpecSEI", |
| | | 345 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 346 | [0] = "SError interrupt not supported", |
| | | 347 | [1] = "SError interrupt supported" |
| | | 348 | } |
| | | 349 | }, |
| | | 350 | { |
| | | 351 | .bitpos = 28, .bitwidth = 4, .name = "XNX", |
| | | 352 | .info = (const char *[16]) { /* 16=4bit */ |
| | | 353 | [0] = "Distinction between EL0 and EL1 XN control at stage 2 not supported", |
| | | 354 | [1] = "Distinction between EL0 and EL1 XN control at stage 2 supported" |
| | | 355 | } |
| | | 356 | }, |
| | | 357 | { .bitwidth = 0 } /* end of table */ |
| | | 358 | }; |
| | | 359 | |
261 | /* ID_AA64DFR0_EL1 - AArch64 Debug Feature Register 0 */ | | 360 | /* ID_AA64DFR0_EL1 - AArch64 Debug Feature Register 0 */ |
262 | struct fieldinfo id_aa64dfr0_fieldinfo[] = { | | 361 | struct fieldinfo id_aa64dfr0_fieldinfo[] = { |
263 | { | | 362 | { |
264 | .bitpos = 0, .bitwidth = 4, .name = "DebugVer", | | 363 | .bitpos = 0, .bitwidth = 4, .name = "DebugVer", |
265 | .info = (const char *[16]) { /* 16=4bit */ | | 364 | .info = (const char *[16]) { /* 16=4bit */ |
266 | [6] = "v8-A debug architecture" | | 365 | [6] = "v8-A debug architecture" |
267 | } | | 366 | } |
268 | }, | | 367 | }, |
269 | { | | 368 | { |
270 | .bitpos = 4, .bitwidth = 4, .name = "TraceVer", | | 369 | .bitpos = 4, .bitwidth = 4, .name = "TraceVer", |
271 | .info = (const char *[16]) { /* 16=4bit */ | | 370 | .info = (const char *[16]) { /* 16=4bit */ |
272 | [0] = "Trace supported", | | 371 | [0] = "Trace supported", |
273 | [1] = "Trace not supported" | | 372 | [1] = "Trace not supported" |
| @@ -600,28 +699,32 @@ identifycpu(int fd, const char *cpuname) | | | @@ -600,28 +699,32 @@ identifycpu(int fd, const char *cpuname) |
600 | printf("%s: MVFR1_EL1: 0x%08"PRIx32"\n", | | 699 | printf("%s: MVFR1_EL1: 0x%08"PRIx32"\n", |
601 | cpuname, id->ac_mvfr1); | | 700 | cpuname, id->ac_mvfr1); |
602 | printf("%s: MVFR2_EL1: 0x%08"PRIx32"\n", | | 701 | printf("%s: MVFR2_EL1: 0x%08"PRIx32"\n", |
603 | cpuname, id->ac_mvfr2); | | 702 | cpuname, id->ac_mvfr2); |
604 | } | | 703 | } |
605 | | | 704 | |
606 | identify_midr(cpuname, id->ac_midr); | | 705 | identify_midr(cpuname, id->ac_midr); |
607 | identify_revidr(cpuname, id->ac_revidr); | | 706 | identify_revidr(cpuname, id->ac_revidr); |
608 | identify_mpidr(cpuname, id->ac_mpidr); | | 707 | identify_mpidr(cpuname, id->ac_mpidr); |
609 | print_fieldinfo(cpuname, "isa features 0", | | 708 | print_fieldinfo(cpuname, "isa features 0", |
610 | id_aa64isar0_fieldinfo, id->ac_aa64isar0); | | 709 | id_aa64isar0_fieldinfo, id->ac_aa64isar0); |
611 | print_fieldinfo(cpuname, "memory model 0", | | 710 | print_fieldinfo(cpuname, "memory model 0", |
612 | id_aa64mmfr0_fieldinfo, id->ac_aa64mmfr0); | | 711 | id_aa64mmfr0_fieldinfo, id->ac_aa64mmfr0); |
| | | 712 | print_fieldinfo(cpuname, "memory model 1", |
| | | 713 | id_aa64mmfr1_fieldinfo, id->ac_aa64mmfr1); |
613 | print_fieldinfo(cpuname, "processor feature 0", | | 714 | print_fieldinfo(cpuname, "processor feature 0", |
614 | id_aa64pfr0_fieldinfo, id->ac_aa64pfr0); | | 715 | id_aa64pfr0_fieldinfo, id->ac_aa64pfr0); |
| | | 716 | print_fieldinfo(cpuname, "processor feature 1", |
| | | 717 | id_aa64pfr1_fieldinfo, id->ac_aa64pfr1); |
615 | identify_dfr0(cpuname, id->ac_aa64dfr0); | | 718 | identify_dfr0(cpuname, id->ac_aa64dfr0); |
616 | | | 719 | |
617 | print_fieldinfo(cpuname, "media and VFP features 0", | | 720 | print_fieldinfo(cpuname, "media and VFP features 0", |
618 | mvfr0_fieldinfo, id->ac_mvfr0); | | 721 | mvfr0_fieldinfo, id->ac_mvfr0); |
619 | print_fieldinfo(cpuname, "media and VFP features 1", | | 722 | print_fieldinfo(cpuname, "media and VFP features 1", |
620 | mvfr1_fieldinfo, id->ac_mvfr1); | | 723 | mvfr1_fieldinfo, id->ac_mvfr1); |
621 | print_fieldinfo(cpuname, "media and VFP features 2", | | 724 | print_fieldinfo(cpuname, "media and VFP features 2", |
622 | mvfr2_fieldinfo, id->ac_mvfr2); | | 725 | mvfr2_fieldinfo, id->ac_mvfr2); |
623 | } | | 726 | } |
624 | | | 727 | |
625 | bool | | 728 | bool |
626 | identifycpu_bind(void) | | 729 | identifycpu_bind(void) |
627 | { | | 730 | { |