Tue Jan 28 17:36:42 2020 UTC ()
More identification.


(maxv)
diff -r1.7 -r1.8 src/usr.sbin/cpuctl/arch/aarch64.c

cvs diff -r1.7 -r1.8 src/usr.sbin/cpuctl/arch/aarch64.c (switch to unified diff)

--- src/usr.sbin/cpuctl/arch/aarch64.c 2019/05/09 07:38:44 1.7
+++ src/usr.sbin/cpuctl/arch/aarch64.c 2020/01/28 17:36:42 1.8
@@ -1,635 +1,738 @@ @@ -1,635 +1,738 @@
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.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
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>
46#include <aarch64/armreg.h> 46#include <aarch64/armreg.h>
47 47
48#include "../cpuctl.h" 48#include "../cpuctl.h"
49 49
50struct cpuidtab { 50struct cpuidtab {
51 uint32_t cpu_partnum; 51 uint32_t cpu_partnum;
52 const char *cpu_name; 52 const char *cpu_name;
53 const char *cpu_class; 53 const char *cpu_class;
54 const char *cpu_architecture; 54 const char *cpu_architecture;
55}; 55};
56 56
57struct impltab { 57struct impltab {
58 uint32_t impl_id; 58 uint32_t impl_id;
59 const char *impl_name; 59 const char *impl_name;
60}; 60};
61 61
62struct fieldinfo { 62struct fieldinfo {
63 int bitpos; 63 int bitpos;
64 int bitwidth; 64 int bitwidth;
65 const char *name; 65 const char *name;
66 const char * const *info; 66 const char * const *info;
67}; 67};
68 68
69 69
70#define CPU_PARTMASK (CPU_ID_IMPLEMENTOR_MASK | CPU_ID_PARTNO_MASK) 70#define CPU_PARTMASK (CPU_ID_IMPLEMENTOR_MASK | CPU_ID_PARTNO_MASK)
71const struct cpuidtab cpuids[] = { 71const struct cpuidtab cpuids[] = {
72 { CPU_ID_CORTEXA53R0 & CPU_PARTMASK, "Cortex-A53", "Cortex", "V8-A" }, 72 { CPU_ID_CORTEXA53R0 & CPU_PARTMASK, "Cortex-A53", "Cortex", "V8-A" },
73 { CPU_ID_CORTEXA57R0 & CPU_PARTMASK, "Cortex-A57", "Cortex", "V8-A" }, 73 { CPU_ID_CORTEXA57R0 & CPU_PARTMASK, "Cortex-A57", "Cortex", "V8-A" },
74 { CPU_ID_CORTEXA72R0 & CPU_PARTMASK, "Cortex-A72", "Cortex", "V8-A" }, 74 { CPU_ID_CORTEXA72R0 & CPU_PARTMASK, "Cortex-A72", "Cortex", "V8-A" },
75 { CPU_ID_CORTEXA73R0 & CPU_PARTMASK, "Cortex-A73", "Cortex", "V8-A" }, 75 { CPU_ID_CORTEXA73R0 & CPU_PARTMASK, "Cortex-A73", "Cortex", "V8-A" },
76 { CPU_ID_CORTEXA55R1 & CPU_PARTMASK, "Cortex-A55", "Cortex", "V8.2-A" }, 76 { CPU_ID_CORTEXA55R1 & CPU_PARTMASK, "Cortex-A55", "Cortex", "V8.2-A" },
77 { CPU_ID_CORTEXA75R2 & CPU_PARTMASK, "Cortex-A75", "Cortex", "V8.2-A" }, 77 { CPU_ID_CORTEXA75R2 & CPU_PARTMASK, "Cortex-A75", "Cortex", "V8.2-A" },
78 { CPU_ID_CORTEXA76R3 & CPU_PARTMASK, "Cortex-A76", "Cortex", "V8.2-A" }, 78 { CPU_ID_CORTEXA76R3 & CPU_PARTMASK, "Cortex-A76", "Cortex", "V8.2-A" },
79 { CPU_ID_THUNDERXRX, "Cavium ThunderX", "Cavium", "V8-A" }, 79 { CPU_ID_THUNDERXRX, "Cavium ThunderX", "Cavium", "V8-A" },
80 { CPU_ID_THUNDERX81XXRX, "Cavium ThunderX CN81XX", "Cavium", "V8-A" }, 80 { CPU_ID_THUNDERX81XXRX, "Cavium ThunderX CN81XX", "Cavium", "V8-A" },
81 { CPU_ID_THUNDERX83XXRX, "Cavium ThunderX CN83XX", "Cavium", "V8-A" }, 81 { CPU_ID_THUNDERX83XXRX, "Cavium ThunderX CN83XX", "Cavium", "V8-A" },
82 { CPU_ID_THUNDERX2RX, "Cavium ThunderX2", "Cavium", "V8.1-A" }, 82 { CPU_ID_THUNDERX2RX, "Cavium ThunderX2", "Cavium", "V8.1-A" },
83}; 83};
84 84
85const struct impltab implids[] = { 85const struct impltab implids[] = {
86 { CPU_ID_ARM_LTD, "ARM Limited" }, 86 { CPU_ID_ARM_LTD, "ARM Limited" },
87 { CPU_ID_BROADCOM, "Broadcom Corporation" }, 87 { CPU_ID_BROADCOM, "Broadcom Corporation" },
88 { CPU_ID_CAVIUM, "Cavium Inc." }, 88 { CPU_ID_CAVIUM, "Cavium Inc." },
89 { CPU_ID_DEC, "Digital Equipment Corporation" }, 89 { CPU_ID_DEC, "Digital Equipment Corporation" },
90 { CPU_ID_INFINEON, "Infineon Technologies AG" }, 90 { CPU_ID_INFINEON, "Infineon Technologies AG" },
91 { CPU_ID_MOTOROLA, "Motorola or Freescale Semiconductor Inc." }, 91 { CPU_ID_MOTOROLA, "Motorola or Freescale Semiconductor Inc." },
92 { CPU_ID_NVIDIA, "NVIDIA Corporation" }, 92 { CPU_ID_NVIDIA, "NVIDIA Corporation" },
93 { CPU_ID_APM, "Applied Micro Circuits Corporation" }, 93 { CPU_ID_APM, "Applied Micro Circuits Corporation" },
94 { CPU_ID_QUALCOMM, "Qualcomm Inc." }, 94 { CPU_ID_QUALCOMM, "Qualcomm Inc." },
95 { CPU_ID_SAMSUNG, "SAMSUNG" }, 95 { CPU_ID_SAMSUNG, "SAMSUNG" },
96 { CPU_ID_TI, "Texas Instruments" }, 96 { CPU_ID_TI, "Texas Instruments" },
97 { CPU_ID_MARVELL, "Marvell International Ltd." }, 97 { CPU_ID_MARVELL, "Marvell International Ltd." },
98 { CPU_ID_APPLE, "Apple Inc." }, 98 { CPU_ID_APPLE, "Apple Inc." },
99 { CPU_ID_FARADAY, "Faraday Technology Corporation" }, 99 { CPU_ID_FARADAY, "Faraday Technology Corporation" },
100 { CPU_ID_INTEL, "Intel Corporation" } 100 { CPU_ID_INTEL, "Intel Corporation" }
101}; 101};
102 102
103/* ID_AA64PFR0_EL1 - AArch64 Processor Feature Register 0 */ 103/* ID_AA64PFR0_EL1 - AArch64 Processor Feature Register 0 */
104struct fieldinfo id_aa64pfr0_fieldinfo[] = { 104struct fieldinfo id_aa64pfr0_fieldinfo[] = {
105 { 105 {
106 .bitpos = 0, .bitwidth = 4, .name = "EL0", 106 .bitpos = 0, .bitwidth = 4, .name = "EL0",
107 .info = (const char *[16]) { /* 16=4bit */ 107 .info = (const char *[16]) { /* 16=4bit */
108 [0] = "No EL0", 108 [0] = "No EL0",
109 [1] = "AArch64", 109 [1] = "AArch64",
110 [2] = "AArch64/AArch32" 110 [2] = "AArch64/AArch32"
111 } 111 }
112 }, 112 },
113 { 113 {
114 .bitpos = 4, .bitwidth = 4, .name = "EL1", 114 .bitpos = 4, .bitwidth = 4, .name = "EL1",
115 .info = (const char *[16]) { /* 16=4bit */ 115 .info = (const char *[16]) { /* 16=4bit */
116 [0] = "No EL1", 116 [0] = "No EL1",
117 [1] = "AArch64", 117 [1] = "AArch64",
118 [2] = "AArch64/AArch32" 118 [2] = "AArch64/AArch32"
119 } 119 }
120 }, 120 },
121 { 121 {
122 .bitpos = 8, .bitwidth = 4, .name = "EL2", 122 .bitpos = 8, .bitwidth = 4, .name = "EL2",
123 .info = (const char *[16]) { /* 16=4bit */ 123 .info = (const char *[16]) { /* 16=4bit */
124 [0] = "No EL2", 124 [0] = "No EL2",
125 [1] = "AArch64", 125 [1] = "AArch64",
126 [2] = "AArch64/AArch32" 126 [2] = "AArch64/AArch32"
127 } 127 }
128 }, 128 },
129 { 129 {
130 .bitpos = 12, .bitwidth = 4, .name = "EL3", 130 .bitpos = 12, .bitwidth = 4, .name = "EL3",
131 .info = (const char *[16]) { /* 16=4bit */ 131 .info = (const char *[16]) { /* 16=4bit */
132 [0] = "No EL3", 132 [0] = "No EL3",
133 [1] = "AArch64", 133 [1] = "AArch64",
134 [2] = "AArch64/AArch32" 134 [2] = "AArch64/AArch32"
135 } 135 }
136 }, 136 },
137 { 137 {
138 .bitpos = 16, .bitwidth = 4, .name = "FP", 138 .bitpos = 16, .bitwidth = 4, .name = "FP",
139 .info = (const char *[16]) { /* 16=4bit */ 139 .info = (const char *[16]) { /* 16=4bit */
140 [0] = "Floating Point", 140 [0] = "Floating Point",
141 [15] = "No Floating Point" 141 [15] = "No Floating Point"
142 } 142 }
143 }, 143 },
144 { 144 {
145 .bitpos = 20, .bitwidth = 4, .name = "AdvSIMD", 145 .bitpos = 20, .bitwidth = 4, .name = "AdvSIMD",
146 .info = (const char *[16]) { /* 16=4bit */ 146 .info = (const char *[16]) { /* 16=4bit */
147 [0] = "Advanced SIMD", 147 [0] = "Advanced SIMD",
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 */
 162struct 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 */
162struct fieldinfo id_aa64isar0_fieldinfo[] = { 197struct 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 */
174 [0] = "No SHA1", 209 [0] = "No SHA1",
175 [1] = "SHA1C/SHA1P/SHA1M/SHA1H/SHA1SU0/SHA1SU1" 210 [1] = "SHA1C/SHA1P/SHA1M/SHA1H/SHA1SU0/SHA1SU1"
176 } 211 }
177 }, 212 },
178 { 213 {
179 .bitpos = 12, .bitwidth = 4, .name = "SHA2", 214 .bitpos = 12, .bitwidth = 4, .name = "SHA2",
180 .info = (const char *[16]) { /* 16=4bit */ 215 .info = (const char *[16]) { /* 16=4bit */
181 [0] = "No SHA2", 216 [0] = "No SHA2",
182 [1] = "SHA256H/SHA256H2/SHA256SU0/SHA256U1" 217 [1] = "SHA256H/SHA256H2/SHA256SU0/SHA256U1"
183 } 218 }
184 }, 219 },
185 { 220 {
186 .bitpos = 16, .bitwidth = 4, .name = "CRC32", 221 .bitpos = 16, .bitwidth = 4, .name = "CRC32",
187 .info = (const char *[16]) { /* 16=4bit */ 222 .info = (const char *[16]) { /* 16=4bit */
188 [0] = "No CRC32", 223 [0] = "No CRC32",
189 [1] = "CRC32B/CRC32H/CRC32W/CRC32X" 224 [1] = "CRC32B/CRC32H/CRC32W/CRC32X"
190 "/CRC32CB/CRC32CH/CRC32CW/CRC32CX" 225 "/CRC32CB/CRC32CH/CRC32CW/CRC32CX"
191 } 226 }
192 }, 227 },
193 { .bitwidth = 0 } /* end of table */ 228 { .bitwidth = 0 } /* end of table */
194}; 229};
195 230
196/* ID_AA64MMFR0_EL1 - AArch64 Memory Model Feature Register 0 */ 231/* ID_AA64MMFR0_EL1 - AArch64 Memory Model Feature Register 0 */
197struct fieldinfo id_aa64mmfr0_fieldinfo[] = { 232struct fieldinfo id_aa64mmfr0_fieldinfo[] = {
198 { 233 {
199 .bitpos = 0, .bitwidth = 4, .name = "PARange", 234 .bitpos = 0, .bitwidth = 4, .name = "PARange",
200 .info = (const char *[16]) { /* 16=4bit */ 235 .info = (const char *[16]) { /* 16=4bit */
201 [0] = "32bits/4GB", 236 [0] = "32bits/4GB",
202 [1] = "36bits/64GB", 237 [1] = "36bits/64GB",
203 [2] = "40bits/1TB", 238 [2] = "40bits/1TB",
204 [3] = "42bits/4TB", 239 [3] = "42bits/4TB",
205 [4] = "44bits/16TB", 240 [4] = "44bits/16TB",
206 [5] = "48bits/256TB" 241 [5] = "48bits/256TB"
207 } 242 }
208 }, 243 },
209 { 244 {
210 .bitpos = 4, .bitwidth = 4, .name = "ASIDBit", 245 .bitpos = 4, .bitwidth = 4, .name = "ASIDBit",
211 .info = (const char *[16]) { /* 16=4bit */ 246 .info = (const char *[16]) { /* 16=4bit */
212 [0] = "8bits", 247 [0] = "8bits",
213 [2] = "16bits" 248 [2] = "16bits"
214 } 249 }
215 }, 250 },
216 { 251 {
217 .bitpos = 8, .bitwidth = 4, .name = "BigEnd", 252 .bitpos = 8, .bitwidth = 4, .name = "BigEnd",
218 .info = (const char *[16]) { /* 16=4bit */ 253 .info = (const char *[16]) { /* 16=4bit */
219 [0] = "No mixed-endian", 254 [0] = "No mixed-endian",
220 [1] = "Mixed-endian" 255 [1] = "Mixed-endian"
221 } 256 }
222 }, 257 },
223 { 258 {
224 .bitpos = 12, .bitwidth = 4, .name = "SNSMem", 259 .bitpos = 12, .bitwidth = 4, .name = "SNSMem",
225 .info = (const char *[16]) { /* 16=4bit */ 260 .info = (const char *[16]) { /* 16=4bit */
226 [0] = "No distinction B/W Secure and Non-secure Memory", 261 [0] = "No distinction B/W Secure and Non-secure Memory",
227 [1] = "Distinction B/W Secure and Non-secure Memory" 262 [1] = "Distinction B/W Secure and Non-secure Memory"
228 } 263 }
229 }, 264 },
230 { 265 {
231 .bitpos = 16, .bitwidth = 4, .name = "BigEndEL0", 266 .bitpos = 16, .bitwidth = 4, .name = "BigEndEL0",
232 .info = (const char *[16]) { /* 16=4bit */ 267 .info = (const char *[16]) { /* 16=4bit */
233 [0] = "No mixed-endian at EL0", 268 [0] = "No mixed-endian at EL0",
234 [1] = "Mixed-endian at EL0" 269 [1] = "Mixed-endian at EL0"
235 } 270 }
236 }, 271 },
237 { 272 {
238 .bitpos = 20, .bitwidth = 4, .name = "TGran16", 273 .bitpos = 20, .bitwidth = 4, .name = "TGran16",
239 .info = (const char *[16]) { /* 16=4bit */ 274 .info = (const char *[16]) { /* 16=4bit */
240 [0] = "No 16KB granule", 275 [0] = "No 16KB granule",
241 [1] = "16KB granule" 276 [1] = "16KB granule"
242 } 277 }
243 }, 278 },
244 { 279 {
245 .bitpos = 24, .bitwidth = 4, .name = "TGran64", 280 .bitpos = 24, .bitwidth = 4, .name = "TGran64",
246 .info = (const char *[16]) { /* 16=4bit */ 281 .info = (const char *[16]) { /* 16=4bit */
247 [0] = "64KB granule", 282 [0] = "64KB granule",
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 */
 297struct 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 */
262struct fieldinfo id_aa64dfr0_fieldinfo[] = { 361struct 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"
274 } 373 }
275 }, 374 },
276 { 375 {
277 .bitpos = 8, .bitwidth = 4, .name = "PMUVer", 376 .bitpos = 8, .bitwidth = 4, .name = "PMUVer",
278 .info = (const char *[16]) { /* 16=4bit */ 377 .info = (const char *[16]) { /* 16=4bit */
279 [0] = "No Performance monitor", 378 [0] = "No Performance monitor",
280 [1] = "Performance monitor unit v3" 379 [1] = "Performance monitor unit v3"
281 } 380 }
282 }, 381 },
283 { .bitwidth = 0 } /* end of table */ 382 { .bitwidth = 0 } /* end of table */
284}; 383};
285 384
286 385
287/* MVFR0_EL1 - Media and VFP Feature Register 0 */ 386/* MVFR0_EL1 - Media and VFP Feature Register 0 */
288struct fieldinfo mvfr0_fieldinfo[] = { 387struct fieldinfo mvfr0_fieldinfo[] = {
289 { 388 {
290 .bitpos = 0, .bitwidth = 4, .name = "SIMDreg", 389 .bitpos = 0, .bitwidth = 4, .name = "SIMDreg",
291 .info = (const char *[16]) { /* 16=4bit */ 390 .info = (const char *[16]) { /* 16=4bit */
292 [0] = "No SIMD", 391 [0] = "No SIMD",
293 [1] = "16x64-bit SIMD", 392 [1] = "16x64-bit SIMD",
294 [2] = "32x64-bit SIMD" 393 [2] = "32x64-bit SIMD"
295 } 394 }
296 }, 395 },
297 { 396 {
298 .bitpos = 4, .bitwidth = 4, .name = "FPSP", 397 .bitpos = 4, .bitwidth = 4, .name = "FPSP",
299 .info = (const char *[16]) { /* 16=4bit */ 398 .info = (const char *[16]) { /* 16=4bit */
300 [0] = "No VFP support single precision", 399 [0] = "No VFP support single precision",
301 [1] = "VFPv2 support single precision", 400 [1] = "VFPv2 support single precision",
302 [2] = "VFPv2/VFPv3/VFPv4 support single precision" 401 [2] = "VFPv2/VFPv3/VFPv4 support single precision"
303 } 402 }
304 }, 403 },
305 { 404 {
306 .bitpos = 8, .bitwidth = 4, .name = "FPDP", 405 .bitpos = 8, .bitwidth = 4, .name = "FPDP",
307 .info = (const char *[16]) { /* 16=4bit */ 406 .info = (const char *[16]) { /* 16=4bit */
308 [0] = "No VFP support double precision", 407 [0] = "No VFP support double precision",
309 [1] = "VFPv2 support double precision", 408 [1] = "VFPv2 support double precision",
310 [2] = "VFPv2/VFPv3/VFPv4 support double precision" 409 [2] = "VFPv2/VFPv3/VFPv4 support double precision"
311 } 410 }
312 }, 411 },
313 { 412 {
314 .bitpos = 12, .bitwidth = 4, .name = "FPTrap", 413 .bitpos = 12, .bitwidth = 4, .name = "FPTrap",
315 .info = (const char *[16]) { /* 16=4bit */ 414 .info = (const char *[16]) { /* 16=4bit */
316 [0] = "No floating point exception trapping support", 415 [0] = "No floating point exception trapping support",
317 [1] = "VFPv2/VFPv3/VFPv4 support exception trapping" 416 [1] = "VFPv2/VFPv3/VFPv4 support exception trapping"
318 } 417 }
319 }, 418 },
320 { 419 {
321 .bitpos = 16, .bitwidth = 4, .name = "FPDivide", 420 .bitpos = 16, .bitwidth = 4, .name = "FPDivide",
322 .info = (const char *[16]) { /* 16=4bit */ 421 .info = (const char *[16]) { /* 16=4bit */
323 [0] = "VDIV not supported", 422 [0] = "VDIV not supported",
324 [1] = "VDIV supported" 423 [1] = "VDIV supported"
325 } 424 }
326 }, 425 },
327 { 426 {
328 .bitpos = 20, .bitwidth = 4, .name = "FPSqrt", 427 .bitpos = 20, .bitwidth = 4, .name = "FPSqrt",
329 .info = (const char *[16]) { /* 16=4bit */ 428 .info = (const char *[16]) { /* 16=4bit */
330 [0] = "VSQRT not supported", 429 [0] = "VSQRT not supported",
331 [1] = "VSQRT supported" 430 [1] = "VSQRT supported"
332 } 431 }
333 }, 432 },
334 { 433 {
335 .bitpos = 24, .bitwidth = 4, .name = "FPShVec", 434 .bitpos = 24, .bitwidth = 4, .name = "FPShVec",
336 .info = (const char *[16]) { /* 16=4bit */ 435 .info = (const char *[16]) { /* 16=4bit */
337 [0] = "Short Vectors not supported", 436 [0] = "Short Vectors not supported",
338 [1] = "Short Vectors supported" 437 [1] = "Short Vectors supported"
339 } 438 }
340 }, 439 },
341 { 440 {
342 .bitpos = 28, .bitwidth = 4, .name = "FPRound", 441 .bitpos = 28, .bitwidth = 4, .name = "FPRound",
343 .info = (const char *[16]) { /* 16=4bit */ 442 .info = (const char *[16]) { /* 16=4bit */
344 [0] = "Only Round to Nearest mode", 443 [0] = "Only Round to Nearest mode",
345 [1] = "All rounding modes" 444 [1] = "All rounding modes"
346 } 445 }
347 }, 446 },
348 { .bitwidth = 0 } /* end of table */ 447 { .bitwidth = 0 } /* end of table */
349}; 448};
350 449
351/* MVFR1_EL1 - Media and VFP Feature Register 1 */ 450/* MVFR1_EL1 - Media and VFP Feature Register 1 */
352struct fieldinfo mvfr1_fieldinfo[] = { 451struct fieldinfo mvfr1_fieldinfo[] = {
353 { 452 {
354 .bitpos = 0, .bitwidth = 4, .name = "FPFtZ", 453 .bitpos = 0, .bitwidth = 4, .name = "FPFtZ",
355 .info = (const char *[16]) { /* 16=4bit */ 454 .info = (const char *[16]) { /* 16=4bit */
356 [0] = "only the Flush-to-Zero", 455 [0] = "only the Flush-to-Zero",
357 [1] = "full Denormalized number arithmetic" 456 [1] = "full Denormalized number arithmetic"
358 } 457 }
359 }, 458 },
360 { 459 {
361 .bitpos = 4, .bitwidth = 4, .name = "FPDNan", 460 .bitpos = 4, .bitwidth = 4, .name = "FPDNan",
362 .info = (const char *[16]) { /* 16=4bit */ 461 .info = (const char *[16]) { /* 16=4bit */
363 [0] = "Default NaN", 462 [0] = "Default NaN",
364 [1] = "Propagation of NaN" 463 [1] = "Propagation of NaN"
365 } 464 }
366 }, 465 },
367 { 466 {
368 .bitpos = 8, .bitwidth = 4, .name = "SIMDLS", 467 .bitpos = 8, .bitwidth = 4, .name = "SIMDLS",
369 .info = (const char *[16]) { /* 16=4bit */ 468 .info = (const char *[16]) { /* 16=4bit */
370 [0] = "No Advanced SIMD Load/Store", 469 [0] = "No Advanced SIMD Load/Store",
371 [1] = "Advanced SIMD Load/Store" 470 [1] = "Advanced SIMD Load/Store"
372 } 471 }
373 }, 472 },
374 { 473 {
375 .bitpos = 12, .bitwidth = 4, .name = "SIMDInt", 474 .bitpos = 12, .bitwidth = 4, .name = "SIMDInt",
376 .info = (const char *[16]) { /* 16=4bit */ 475 .info = (const char *[16]) { /* 16=4bit */
377 [0] = "No Advanced SIMD Integer", 476 [0] = "No Advanced SIMD Integer",
378 [1] = "Advanced SIMD Integer" 477 [1] = "Advanced SIMD Integer"
379 } 478 }
380 }, 479 },
381 { 480 {
382 .bitpos = 16, .bitwidth = 4, .name = "SIMDSP", 481 .bitpos = 16, .bitwidth = 4, .name = "SIMDSP",
383 .info = (const char *[16]) { /* 16=4bit */ 482 .info = (const char *[16]) { /* 16=4bit */
384 [0] = "No Advanced SIMD single precision", 483 [0] = "No Advanced SIMD single precision",
385 [1] = "Advanced SIMD single precision" 484 [1] = "Advanced SIMD single precision"
386 } 485 }
387 }, 486 },
388 { 487 {
389 .bitpos = 20, .bitwidth = 4, .name = "SIMDHP", 488 .bitpos = 20, .bitwidth = 4, .name = "SIMDHP",
390 .info = (const char *[16]) { /* 16=4bit */ 489 .info = (const char *[16]) { /* 16=4bit */
391 [0] = "No Advanced SIMD half precision", 490 [0] = "No Advanced SIMD half precision",
392 [1] = "Advanced SIMD half precision" 491 [1] = "Advanced SIMD half precision"
393 } 492 }
394 }, 493 },
395 { 494 {
396 .bitpos = 24, .bitwidth = 4, .name = "FPHP", 495 .bitpos = 24, .bitwidth = 4, .name = "FPHP",
397 .info = (const char *[16]) { /* 16=4bit */ 496 .info = (const char *[16]) { /* 16=4bit */
398 [0] = "No half precision conversion", 497 [0] = "No half precision conversion",
399 [1] = "half/single precision conversion", 498 [1] = "half/single precision conversion",
400 [2] = "half/single/double precision conversion" 499 [2] = "half/single/double precision conversion"
401 } 500 }
402 }, 501 },
403 { 502 {
404 .bitpos = 28, .bitwidth = 4, .name = "SIMDFMAC", 503 .bitpos = 28, .bitwidth = 4, .name = "SIMDFMAC",
405 .info = (const char *[16]) { /* 16=4bit */ 504 .info = (const char *[16]) { /* 16=4bit */
406 [0] = "No Fused Multiply-Accumulate", 505 [0] = "No Fused Multiply-Accumulate",
407 [1] = "Fused Multiply-Accumulate" 506 [1] = "Fused Multiply-Accumulate"
408 } 507 }
409 }, 508 },
410 { .bitwidth = 0 } /* end of table */ 509 { .bitwidth = 0 } /* end of table */
411}; 510};
412 511
413/* MVFR2_EL1 - Media and VFP Feature Register 2 */ 512/* MVFR2_EL1 - Media and VFP Feature Register 2 */
414struct fieldinfo mvfr2_fieldinfo[] = { 513struct fieldinfo mvfr2_fieldinfo[] = {
415 { 514 {
416 .bitpos = 0, .bitwidth = 4, .name = "SIMDMisc", 515 .bitpos = 0, .bitwidth = 4, .name = "SIMDMisc",
417 .info = (const char *[16]) { /* 16=4bit */ 516 .info = (const char *[16]) { /* 16=4bit */
418 [0] = "No miscellaneous features", 517 [0] = "No miscellaneous features",
419 [1] = "Conversion to Integer w/Directed Rounding modes", 518 [1] = "Conversion to Integer w/Directed Rounding modes",
420 [2] = "Conversion to Integer w/Directed Rounding modes" 519 [2] = "Conversion to Integer w/Directed Rounding modes"
421 ", Round to Integral floating point", 520 ", Round to Integral floating point",
422 [3] = "Conversion to Integer w/Directed Rounding modes" 521 [3] = "Conversion to Integer w/Directed Rounding modes"
423 ", Round to Integral floating point" 522 ", Round to Integral floating point"
424 ", MaxNum and MinNum" 523 ", MaxNum and MinNum"
425 } 524 }
426 }, 525 },
427 { 526 {
428 .bitpos = 4, .bitwidth = 4, .name = "FPMisc", 527 .bitpos = 4, .bitwidth = 4, .name = "FPMisc",
429 .info = (const char *[16]) { /* 16=4bit */ 528 .info = (const char *[16]) { /* 16=4bit */
430 [0] = "No miscellaneous features", 529 [0] = "No miscellaneous features",
431 [1] = "Floating point selection", 530 [1] = "Floating point selection",
432 [2] = "Floating point selection" 531 [2] = "Floating point selection"
433 ", Conversion to Integer w/Directed Rounding modes", 532 ", Conversion to Integer w/Directed Rounding modes",
434 [3] = "Floating point selection" 533 [3] = "Floating point selection"
435 ", Conversion to Integer w/Directed Rounding modes" 534 ", Conversion to Integer w/Directed Rounding modes"
436 ", Round to Integral floating point", 535 ", Round to Integral floating point",
437 [4] = "Floating point selection" 536 [4] = "Floating point selection"
438 ", Conversion to Integer w/Directed Rounding modes" 537 ", Conversion to Integer w/Directed Rounding modes"
439 ", Round to Integral floating point" 538 ", Round to Integral floating point"
440 ", MaxNum and MinNum" 539 ", MaxNum and MinNum"
441 } 540 }
442 }, 541 },
443 { .bitwidth = 0 } /* end of table */ 542 { .bitwidth = 0 } /* end of table */
444}; 543};
445 544
446static void 545static void
447print_fieldinfo(const char *cpuname, const char *setname, 546print_fieldinfo(const char *cpuname, const char *setname,
448 struct fieldinfo *fieldinfo, uint64_t data) 547 struct fieldinfo *fieldinfo, uint64_t data)
449{ 548{
450 uint64_t v; 549 uint64_t v;
451 const char *info; 550 const char *info;
452 int i; 551 int i;
453 552
454#define WIDTHMASK(w) (0xffffffffffffffffULL >> (64 - (w))) 553#define WIDTHMASK(w) (0xffffffffffffffffULL >> (64 - (w)))
455 554
456 for (i = 0; fieldinfo[i].bitwidth != 0; i++) { 555 for (i = 0; fieldinfo[i].bitwidth != 0; i++) {
457 v = (data >> fieldinfo[i].bitpos) & 556 v = (data >> fieldinfo[i].bitpos) &
458 WIDTHMASK(fieldinfo[i].bitwidth); 557 WIDTHMASK(fieldinfo[i].bitwidth);
459 558
460 info = fieldinfo[i].info[v]; 559 info = fieldinfo[i].info[v];
461 if (info == NULL) 560 if (info == NULL)
462 printf("%s: %s: %s: 0x%"PRIx64"\n", 561 printf("%s: %s: %s: 0x%"PRIx64"\n",
463 cpuname, setname, fieldinfo[i].name, v); 562 cpuname, setname, fieldinfo[i].name, v);
464 else 563 else
465 printf("%s: %s: %s: %s\n", 564 printf("%s: %s: %s: %s\n",
466 cpuname, setname, fieldinfo[i].name, info); 565 cpuname, setname, fieldinfo[i].name, info);
467 } 566 }
468} 567}
469 568
470/* MIDR_EL1 - Main ID Register */ 569/* MIDR_EL1 - Main ID Register */
471static void 570static void
472identify_midr(const char *cpuname, uint32_t cpuid) 571identify_midr(const char *cpuname, uint32_t cpuid)
473{ 572{
474 unsigned int i; 573 unsigned int i;
475 uint32_t implid, cpupart, variant, revision; 574 uint32_t implid, cpupart, variant, revision;
476 const char *implementer = NULL; 575 const char *implementer = NULL;
477 static char implbuf[128]; 576 static char implbuf[128];
478 577
479 implid = cpuid & CPU_ID_IMPLEMENTOR_MASK; 578 implid = cpuid & CPU_ID_IMPLEMENTOR_MASK;
480 cpupart = cpuid & CPU_PARTMASK; 579 cpupart = cpuid & CPU_PARTMASK;
481 variant = __SHIFTOUT(cpuid, CPU_ID_VARIANT_MASK); 580 variant = __SHIFTOUT(cpuid, CPU_ID_VARIANT_MASK);
482 revision = __SHIFTOUT(cpuid, CPU_ID_REVISION_MASK); 581 revision = __SHIFTOUT(cpuid, CPU_ID_REVISION_MASK);
483 582
484 for (i = 0; i < __arraycount(implids); i++) { 583 for (i = 0; i < __arraycount(implids); i++) {
485 if (implid == implids[i].impl_id) { 584 if (implid == implids[i].impl_id) {
486 implementer = implids[i].impl_name; 585 implementer = implids[i].impl_name;
487 } 586 }
488 } 587 }
489 if (implementer == NULL) { 588 if (implementer == NULL) {
490 snprintf(implbuf, sizeof(implbuf), "unknown implementer: 0x%02x", 589 snprintf(implbuf, sizeof(implbuf), "unknown implementer: 0x%02x",
491 implid >> 24); 590 implid >> 24);
492 implementer = implbuf; 591 implementer = implbuf;
493 } 592 }
494 593
495 for (i = 0; i < __arraycount(cpuids); i++) { 594 for (i = 0; i < __arraycount(cpuids); i++) {
496 if (cpupart == cpuids[i].cpu_partnum) { 595 if (cpupart == cpuids[i].cpu_partnum) {
497 printf("%s: %s, %s r%dp%d (%s %s core)\n", 596 printf("%s: %s, %s r%dp%d (%s %s core)\n",
498 cpuname, implementer, 597 cpuname, implementer,
499 cpuids[i].cpu_name, variant, revision, 598 cpuids[i].cpu_name, variant, revision,
500 cpuids[i].cpu_class, 599 cpuids[i].cpu_class,
501 cpuids[i].cpu_architecture); 600 cpuids[i].cpu_architecture);
502 return; 601 return;
503 } 602 }
504 } 603 }
505 printf("%s: unknown CPU ID: 0x%08x\n", cpuname, cpuid); 604 printf("%s: unknown CPU ID: 0x%08x\n", cpuname, cpuid);
506} 605}
507 606
508/* REVIDR_EL1 - Revision ID Register */ 607/* REVIDR_EL1 - Revision ID Register */
509static void 608static void
510identify_revidr(const char *cpuname, uint32_t revidr) 609identify_revidr(const char *cpuname, uint32_t revidr)
511{ 610{
512 printf("%s: revision: 0x%08x\n", cpuname, revidr); 611 printf("%s: revision: 0x%08x\n", cpuname, revidr);
513} 612}
514 613
515/* MPIDR_EL1 - Multiprocessor Affinity Register */ 614/* MPIDR_EL1 - Multiprocessor Affinity Register */
516static void 615static void
517identify_mpidr(const char *cpuname, uint32_t mpidr) 616identify_mpidr(const char *cpuname, uint32_t mpidr)
518{ 617{
519 const char *setname = "multiprocessor affinity"; 618 const char *setname = "multiprocessor affinity";
520 619
521 printf("%s: %s: Affinity-Level: %"PRIu64"-%"PRIu64"-%"PRIu64"-%"PRIu64"\n", 620 printf("%s: %s: Affinity-Level: %"PRIu64"-%"PRIu64"-%"PRIu64"-%"PRIu64"\n",
522 cpuname, setname, 621 cpuname, setname,
523 __SHIFTOUT(mpidr, MPIDR_AFF3), 622 __SHIFTOUT(mpidr, MPIDR_AFF3),
524 __SHIFTOUT(mpidr, MPIDR_AFF2), 623 __SHIFTOUT(mpidr, MPIDR_AFF2),
525 __SHIFTOUT(mpidr, MPIDR_AFF1), 624 __SHIFTOUT(mpidr, MPIDR_AFF1),
526 __SHIFTOUT(mpidr, MPIDR_AFF0)); 625 __SHIFTOUT(mpidr, MPIDR_AFF0));
527 626
528 if ((mpidr & MPIDR_U) == 0) 627 if ((mpidr & MPIDR_U) == 0)
529 printf("%s: %s: Multiprocessor system\n", cpuname, setname); 628 printf("%s: %s: Multiprocessor system\n", cpuname, setname);
530 else 629 else
531 printf("%s: %s: Uniprocessor system\n", cpuname, setname); 630 printf("%s: %s: Uniprocessor system\n", cpuname, setname);
532 631
533 if ((mpidr & MPIDR_MT) == 0) 632 if ((mpidr & MPIDR_MT) == 0)
534 printf("%s: %s: Core Independent\n", cpuname, setname); 633 printf("%s: %s: Core Independent\n", cpuname, setname);
535 else 634 else
536 printf("%s: %s: Multi-Threading\n", cpuname, setname); 635 printf("%s: %s: Multi-Threading\n", cpuname, setname);
537 636
538} 637}
539 638
540/* AA64DFR0 - Debug feature register 0 */ 639/* AA64DFR0 - Debug feature register 0 */
541static void 640static void
542identify_dfr0(const char *cpuname, uint64_t dfr0) 641identify_dfr0(const char *cpuname, uint64_t dfr0)
543{ 642{
544 const char *setname = "debug feature 0"; 643 const char *setname = "debug feature 0";
545 644
546 printf("%s: %s: CTX_CMPs: %lu context-aware breakpoints\n", 645 printf("%s: %s: CTX_CMPs: %lu context-aware breakpoints\n",
547 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_CTX_CMPS) + 1); 646 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_CTX_CMPS) + 1);
548 printf("%s: %s: WRPs: %lu watchpoints\n", 647 printf("%s: %s: WRPs: %lu watchpoints\n",
549 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_WRPS) + 1); 648 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_WRPS) + 1);
550 printf("%s: %s: BRPs: %lu breakpoints\n", 649 printf("%s: %s: BRPs: %lu breakpoints\n",
551 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_BRPS) + 1); 650 cpuname, setname, __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_BRPS) + 1);
552 print_fieldinfo(cpuname, setname, 651 print_fieldinfo(cpuname, setname,
553 id_aa64dfr0_fieldinfo, dfr0); 652 id_aa64dfr0_fieldinfo, dfr0);
554} 653}
555 654
556void 655void
557identifycpu(int fd, const char *cpuname) 656identifycpu(int fd, const char *cpuname)
558{ 657{
559 char path[128]; 658 char path[128];
560 size_t len; 659 size_t len;
561#define SYSCTL_CPU_ID_MAXSIZE 64 660#define SYSCTL_CPU_ID_MAXSIZE 64
562 uint64_t sysctlbuf[SYSCTL_CPU_ID_MAXSIZE]; 661 uint64_t sysctlbuf[SYSCTL_CPU_ID_MAXSIZE];
563 struct aarch64_sysctl_cpu_id *id = 662 struct aarch64_sysctl_cpu_id *id =
564 (struct aarch64_sysctl_cpu_id *)sysctlbuf; 663 (struct aarch64_sysctl_cpu_id *)sysctlbuf;
565 664
566 snprintf(path, sizeof path, "machdep.%s.cpu_id", cpuname); 665 snprintf(path, sizeof path, "machdep.%s.cpu_id", cpuname);
567 len = sizeof(sysctlbuf); 666 len = sizeof(sysctlbuf);
568 if (sysctlbyname(path, id, &len, 0, 0) == -1) 667 if (sysctlbyname(path, id, &len, 0, 0) == -1)
569 err(1, "couldn't get %s", path); 668 err(1, "couldn't get %s", path);
570 if (len != sizeof(struct aarch64_sysctl_cpu_id)) 669 if (len != sizeof(struct aarch64_sysctl_cpu_id))
571 fprintf(stderr, "Warning: kernel version bumped?\n"); 670 fprintf(stderr, "Warning: kernel version bumped?\n");
572 671
573 if (verbose) { 672 if (verbose) {
574 printf("%s: MIDR_EL1: 0x%08"PRIx64"\n", 673 printf("%s: MIDR_EL1: 0x%08"PRIx64"\n",
575 cpuname, id->ac_midr); 674 cpuname, id->ac_midr);
576 printf("%s: MPIDR_EL1: 0x%016"PRIx64"\n", 675 printf("%s: MPIDR_EL1: 0x%016"PRIx64"\n",
577 cpuname, id->ac_mpidr); 676 cpuname, id->ac_mpidr);
578 printf("%s: ID_AA64DFR0_EL1: 0x%016"PRIx64"\n", 677 printf("%s: ID_AA64DFR0_EL1: 0x%016"PRIx64"\n",
579 cpuname, id->ac_aa64dfr0); 678 cpuname, id->ac_aa64dfr0);
580 printf("%s: ID_AA64DFR1_EL1: 0x%016"PRIx64"\n", 679 printf("%s: ID_AA64DFR1_EL1: 0x%016"PRIx64"\n",
581 cpuname, id->ac_aa64dfr1); 680 cpuname, id->ac_aa64dfr1);
582 printf("%s: ID_AA64ISAR0_EL1: 0x%016"PRIx64"\n", 681 printf("%s: ID_AA64ISAR0_EL1: 0x%016"PRIx64"\n",
583 cpuname, id->ac_aa64isar0); 682 cpuname, id->ac_aa64isar0);
584 printf("%s: ID_AA64ISAR1_EL1: 0x%016"PRIx64"\n", 683 printf("%s: ID_AA64ISAR1_EL1: 0x%016"PRIx64"\n",
585 cpuname, id->ac_aa64isar1); 684 cpuname, id->ac_aa64isar1);
586 printf("%s: ID_AA64MMFR0_EL1: 0x%016"PRIx64"\n", 685 printf("%s: ID_AA64MMFR0_EL1: 0x%016"PRIx64"\n",
587 cpuname, id->ac_aa64mmfr0); 686 cpuname, id->ac_aa64mmfr0);
588 printf("%s: ID_AA64MMFR1_EL1: 0x%016"PRIx64"\n", 687 printf("%s: ID_AA64MMFR1_EL1: 0x%016"PRIx64"\n",
589 cpuname, id->ac_aa64mmfr1); 688 cpuname, id->ac_aa64mmfr1);
590 printf("%s: ID_AA64MMFR2_EL1: 0x%016"PRIx64"\n", 689 printf("%s: ID_AA64MMFR2_EL1: 0x%016"PRIx64"\n",
591 cpuname, id->ac_aa64mmfr2); 690 cpuname, id->ac_aa64mmfr2);
592 printf("%s: ID_AA64PFR0_EL1: 0x%08"PRIx64"\n", 691 printf("%s: ID_AA64PFR0_EL1: 0x%08"PRIx64"\n",
593 cpuname, id->ac_aa64pfr0); 692 cpuname, id->ac_aa64pfr0);
594 printf("%s: ID_AA64PFR1_EL1: 0x%08"PRIx64"\n", 693 printf("%s: ID_AA64PFR1_EL1: 0x%08"PRIx64"\n",
595 cpuname, id->ac_aa64pfr1); 694 cpuname, id->ac_aa64pfr1);
596 printf("%s: ID_AA64ZFR0_EL1: 0x%016"PRIx64"\n", 695 printf("%s: ID_AA64ZFR0_EL1: 0x%016"PRIx64"\n",
597 cpuname, id->ac_aa64zfr0); 696 cpuname, id->ac_aa64zfr0);
598 printf("%s: MVFR0_EL1: 0x%08"PRIx32"\n", 697 printf("%s: MVFR0_EL1: 0x%08"PRIx32"\n",
599 cpuname, id->ac_mvfr0); 698 cpuname, id->ac_mvfr0);
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
625bool 728bool
626identifycpu_bind(void) 729identifycpu_bind(void)
627{ 730{
628 return false; 731 return false;
629} 732}
630 733
631int 734int
632ucodeupdate_check(int fd, struct cpu_ucode *uc) 735ucodeupdate_check(int fd, struct cpu_ucode *uc)
633{ 736{
634 return 0; 737 return 0;
635} 738}