Thu Mar 3 06:26:06 2022 UTC ()
arm: Use device_set_private for cpuN.

For cpu at fdt, nix the fdt softc -- this was leaked and never used
for anything.  The device's private storage is the cpu_info.


(riastradh)
diff -r1.68 -r1.69 src/sys/arch/aarch64/aarch64/cpu.c
diff -r1.152 -r1.153 src/sys/arch/arm/arm32/cpu.c
diff -r1.41 -r1.42 src/sys/arch/arm/fdt/cpu_fdt.c

cvs diff -r1.68 -r1.69 src/sys/arch/aarch64/aarch64/cpu.c (switch to unified diff)

--- src/sys/arch/aarch64/aarch64/cpu.c 2021/11/12 06:44:46 1.68
+++ src/sys/arch/aarch64/aarch64/cpu.c 2022/03/03 06:26:05 1.69
@@ -1,741 +1,741 @@ @@ -1,741 +1,741 @@
1/* $NetBSD: cpu.c,v 1.68 2021/11/12 06:44:46 skrll Exp $ */ 1/* $NetBSD: cpu.c,v 1.69 2022/03/03 06:26:05 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2017 Ryo Shimizu <ryo@nerv.org> 4 * Copyright (c) 2017 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__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.68 2021/11/12 06:44:46 skrll Exp $"); 30__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.69 2022/03/03 06:26:05 riastradh Exp $");
31 31
32#include "locators.h" 32#include "locators.h"
33#include "opt_arm_debug.h" 33#include "opt_arm_debug.h"
34#include "opt_ddb.h" 34#include "opt_ddb.h"
35#include "opt_fdt.h" 35#include "opt_fdt.h"
36#include "opt_multiprocessor.h" 36#include "opt_multiprocessor.h"
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/atomic.h> 39#include <sys/atomic.h>
40#include <sys/cpu.h> 40#include <sys/cpu.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/reboot.h> 43#include <sys/reboot.h>
44#include <sys/rndsource.h> 44#include <sys/rndsource.h>
45#include <sys/sysctl.h> 45#include <sys/sysctl.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47 47
48#include <crypto/aes/aes_impl.h> 48#include <crypto/aes/aes_impl.h>
49#include <crypto/aes/arch/arm/aes_armv8.h> 49#include <crypto/aes/arch/arm/aes_armv8.h>
50#include <crypto/aes/arch/arm/aes_neon.h> 50#include <crypto/aes/arch/arm/aes_neon.h>
51#include <crypto/chacha/chacha_impl.h> 51#include <crypto/chacha/chacha_impl.h>
52#include <crypto/chacha/arch/arm/chacha_neon.h> 52#include <crypto/chacha/arch/arm/chacha_neon.h>
53 53
54#include <aarch64/armreg.h> 54#include <aarch64/armreg.h>
55#include <aarch64/cpu.h> 55#include <aarch64/cpu.h>
56#include <aarch64/cpu_counter.h> 56#include <aarch64/cpu_counter.h>
57#ifdef DDB 57#ifdef DDB
58#include <aarch64/db_machdep.h> 58#include <aarch64/db_machdep.h>
59#endif 59#endif
60#include <aarch64/machdep.h> 60#include <aarch64/machdep.h>
61 61
62#include <arm/cpufunc.h> 62#include <arm/cpufunc.h>
63#include <arm/cpu_topology.h> 63#include <arm/cpu_topology.h>
64#ifdef FDT 64#ifdef FDT
65#include <arm/fdt/arm_fdtvar.h> 65#include <arm/fdt/arm_fdtvar.h>
66#endif 66#endif
67 67
68#ifdef VERBOSE_INIT_ARM 68#ifdef VERBOSE_INIT_ARM
69#define VPRINTF(...) printf(__VA_ARGS__) 69#define VPRINTF(...) printf(__VA_ARGS__)
70#else 70#else
71#define VPRINTF(...) __nothing 71#define VPRINTF(...) __nothing
72#endif 72#endif
73 73
74void cpu_attach(device_t, cpuid_t); 74void cpu_attach(device_t, cpuid_t);
75void cpu_setup_id(struct cpu_info *); 75void cpu_setup_id(struct cpu_info *);
76 76
77static void identify_aarch64_model(uint32_t, char *, size_t); 77static void identify_aarch64_model(uint32_t, char *, size_t);
78static void cpu_identify(device_t self, struct cpu_info *); 78static void cpu_identify(device_t self, struct cpu_info *);
79static void cpu_identify1(device_t self, struct cpu_info *); 79static void cpu_identify1(device_t self, struct cpu_info *);
80static void cpu_identify2(device_t self, struct cpu_info *); 80static void cpu_identify2(device_t self, struct cpu_info *);
81static void cpu_init_counter(struct cpu_info *); 81static void cpu_init_counter(struct cpu_info *);
82static void cpu_setup_sysctl(device_t, struct cpu_info *); 82static void cpu_setup_sysctl(device_t, struct cpu_info *);
83static void cpu_setup_rng(device_t, struct cpu_info *); 83static void cpu_setup_rng(device_t, struct cpu_info *);
84static void cpu_setup_aes(device_t, struct cpu_info *); 84static void cpu_setup_aes(device_t, struct cpu_info *);
85static void cpu_setup_chacha(device_t, struct cpu_info *); 85static void cpu_setup_chacha(device_t, struct cpu_info *);
86 86
87#ifdef MULTIPROCESSOR 87#ifdef MULTIPROCESSOR
88#define NCPUINFO MAXCPUS 88#define NCPUINFO MAXCPUS
89#else 89#else
90#define NCPUINFO 1 90#define NCPUINFO 1
91#endif /* MULTIPROCESSOR */ 91#endif /* MULTIPROCESSOR */
92 92
93/* 93/*
94 * Our exported cpu_info structs; these will be first used by the 94 * Our exported cpu_info structs; these will be first used by the
95 * secondary cpus as part of cpu_mpstart and the hatching process. 95 * secondary cpus as part of cpu_mpstart and the hatching process.
96 */ 96 */
97struct cpu_info cpu_info_store[NCPUINFO] = { 97struct cpu_info cpu_info_store[NCPUINFO] = {
98 [0] = { 98 [0] = {
99 .ci_cpl = IPL_HIGH, 99 .ci_cpl = IPL_HIGH,
100 .ci_curlwp = &lwp0 100 .ci_curlwp = &lwp0
101 } 101 }
102}; 102};
103 103
104void 104void
105cpu_attach(device_t dv, cpuid_t id) 105cpu_attach(device_t dv, cpuid_t id)
106{ 106{
107 struct cpu_info *ci; 107 struct cpu_info *ci;
108 const int unit = device_unit(dv); 108 const int unit = device_unit(dv);
109 109
110 if (unit == 0) { 110 if (unit == 0) {
111 ci = curcpu(); 111 ci = curcpu();
112 ci->ci_cpuid = id; 112 ci->ci_cpuid = id;
113 } else { 113 } else {
114#ifdef MULTIPROCESSOR 114#ifdef MULTIPROCESSOR
115 if ((boothowto & RB_MD1) != 0) { 115 if ((boothowto & RB_MD1) != 0) {
116 aprint_naive("\n"); 116 aprint_naive("\n");
117 aprint_normal(": multiprocessor boot disabled\n"); 117 aprint_normal(": multiprocessor boot disabled\n");
118 return; 118 return;
119 } 119 }
120 120
121 KASSERT(unit < MAXCPUS); 121 KASSERT(unit < MAXCPUS);
122 ci = &cpu_info_store[unit]; 122 ci = &cpu_info_store[unit];
123 123
124 ci->ci_cpl = IPL_HIGH; 124 ci->ci_cpl = IPL_HIGH;
125 ci->ci_cpuid = id; 125 ci->ci_cpuid = id;
126 /* ci_id is stored by own cpus when hatching */ 126 /* ci_id is stored by own cpus when hatching */
127 127
128 cpu_info[ncpu] = ci; 128 cpu_info[ncpu] = ci;
129 if (cpu_hatched_p(unit) == 0) { 129 if (cpu_hatched_p(unit) == 0) {
130 ci->ci_dev = dv; 130 ci->ci_dev = dv;
131 dv->dv_private = ci; 131 device_set_private(dv, ci);
132 ci->ci_index = -1; 132 ci->ci_index = -1;
133 133
134 aprint_naive(": disabled\n"); 134 aprint_naive(": disabled\n");
135 aprint_normal(": disabled (unresponsive)\n"); 135 aprint_normal(": disabled (unresponsive)\n");
136 return; 136 return;
137 } 137 }
138#else /* MULTIPROCESSOR */ 138#else /* MULTIPROCESSOR */
139 aprint_naive(": disabled\n"); 139 aprint_naive(": disabled\n");
140 aprint_normal(": disabled (uniprocessor kernel)\n"); 140 aprint_normal(": disabled (uniprocessor kernel)\n");
141 return; 141 return;
142#endif /* MULTIPROCESSOR */ 142#endif /* MULTIPROCESSOR */
143 } 143 }
144 144
145 ci->ci_dev = dv; 145 ci->ci_dev = dv;
146 dv->dv_private = ci; 146 device_set_private(dv, ci);
147 147
148 ci->ci_kfpu_spl = -1; 148 ci->ci_kfpu_spl = -1;
149 149
150 arm_cpu_do_topology(ci); // XXXNH move this after mi_cpu_attach 150 arm_cpu_do_topology(ci); // XXXNH move this after mi_cpu_attach
151 cpu_identify(dv, ci); 151 cpu_identify(dv, ci);
152 152
153 cpu_setup_sysctl(dv, ci); 153 cpu_setup_sysctl(dv, ci);
154 154
155#ifdef MULTIPROCESSOR 155#ifdef MULTIPROCESSOR
156 if (unit != 0) { 156 if (unit != 0) {
157 mi_cpu_attach(ci); 157 mi_cpu_attach(ci);
158 pmap_tlb_info_attach(&pmap_tlb0_info, ci); 158 pmap_tlb_info_attach(&pmap_tlb0_info, ci);
159 aarch64_parsecacheinfo(ci); 159 aarch64_parsecacheinfo(ci);
160 } 160 }
161#endif /* MULTIPROCESSOR */ 161#endif /* MULTIPROCESSOR */
162 162
163 fpu_attach(ci); 163 fpu_attach(ci);
164 164
165 cpu_identify1(dv, ci); 165 cpu_identify1(dv, ci);
166 aarch64_printcacheinfo(dv, ci); 166 aarch64_printcacheinfo(dv, ci);
167 cpu_identify2(dv, ci); 167 cpu_identify2(dv, ci);
168 168
169 if (unit != 0) { 169 if (unit != 0) {
170 return; 170 return;
171 } 171 }
172 172
173 db_machdep_init(ci); 173 db_machdep_init(ci);
174 174
175 cpu_init_counter(ci); 175 cpu_init_counter(ci);
176 176
177 /* These currently only check the BP. */ 177 /* These currently only check the BP. */
178 cpu_setup_rng(dv, ci); 178 cpu_setup_rng(dv, ci);
179 cpu_setup_aes(dv, ci); 179 cpu_setup_aes(dv, ci);
180 cpu_setup_chacha(dv, ci); 180 cpu_setup_chacha(dv, ci);
181} 181}
182 182
183struct cpuidtab { 183struct cpuidtab {
184 uint32_t cpu_partnum; 184 uint32_t cpu_partnum;
185 const char *cpu_name; 185 const char *cpu_name;
186 const char *cpu_vendor; 186 const char *cpu_vendor;
187 const char *cpu_architecture; 187 const char *cpu_architecture;
188}; 188};
189 189
190#define CPU_PARTMASK (CPU_ID_IMPLEMENTOR_MASK | CPU_ID_PARTNO_MASK) 190#define CPU_PARTMASK (CPU_ID_IMPLEMENTOR_MASK | CPU_ID_PARTNO_MASK)
191 191
192const struct cpuidtab cpuids[] = { 192const struct cpuidtab cpuids[] = {
193 { CPU_ID_CORTEXA35R0 & CPU_PARTMASK, "Cortex-A35", "Arm", "v8-A" }, 193 { CPU_ID_CORTEXA35R0 & CPU_PARTMASK, "Cortex-A35", "Arm", "v8-A" },
194 { CPU_ID_CORTEXA53R0 & CPU_PARTMASK, "Cortex-A53", "Arm", "v8-A" }, 194 { CPU_ID_CORTEXA53R0 & CPU_PARTMASK, "Cortex-A53", "Arm", "v8-A" },
195 { CPU_ID_CORTEXA57R0 & CPU_PARTMASK, "Cortex-A57", "Arm", "v8-A" }, 195 { CPU_ID_CORTEXA57R0 & CPU_PARTMASK, "Cortex-A57", "Arm", "v8-A" },
196 { CPU_ID_CORTEXA55R1 & CPU_PARTMASK, "Cortex-A55", "Arm", "v8.2-A+" }, 196 { CPU_ID_CORTEXA55R1 & CPU_PARTMASK, "Cortex-A55", "Arm", "v8.2-A+" },
197 { CPU_ID_CORTEXA65R0 & CPU_PARTMASK, "Cortex-A65", "Arm", "v8.2-A+" }, 197 { CPU_ID_CORTEXA65R0 & CPU_PARTMASK, "Cortex-A65", "Arm", "v8.2-A+" },
198 { CPU_ID_CORTEXA72R0 & CPU_PARTMASK, "Cortex-A72", "Arm", "v8-A" }, 198 { CPU_ID_CORTEXA72R0 & CPU_PARTMASK, "Cortex-A72", "Arm", "v8-A" },
199 { CPU_ID_CORTEXA73R0 & CPU_PARTMASK, "Cortex-A73", "Arm", "v8-A" }, 199 { CPU_ID_CORTEXA73R0 & CPU_PARTMASK, "Cortex-A73", "Arm", "v8-A" },
200 { CPU_ID_CORTEXA75R2 & CPU_PARTMASK, "Cortex-A75", "Arm", "v8.2-A+" }, 200 { CPU_ID_CORTEXA75R2 & CPU_PARTMASK, "Cortex-A75", "Arm", "v8.2-A+" },
201 { CPU_ID_CORTEXA76R3 & CPU_PARTMASK, "Cortex-A76", "Arm", "v8.2-A+" }, 201 { CPU_ID_CORTEXA76R3 & CPU_PARTMASK, "Cortex-A76", "Arm", "v8.2-A+" },
202 { CPU_ID_CORTEXA76AER1 & CPU_PARTMASK, "Cortex-A76AE", "Arm", "v8.2-A+" }, 202 { CPU_ID_CORTEXA76AER1 & CPU_PARTMASK, "Cortex-A76AE", "Arm", "v8.2-A+" },
203 { CPU_ID_CORTEXA77R0 & CPU_PARTMASK, "Cortex-A77", "Arm", "v8.2-A+" }, 203 { CPU_ID_CORTEXA77R0 & CPU_PARTMASK, "Cortex-A77", "Arm", "v8.2-A+" },
204 { CPU_ID_NVIDIADENVER2 & CPU_PARTMASK, "Denver2", "NVIDIA", "v8-A" }, 204 { CPU_ID_NVIDIADENVER2 & CPU_PARTMASK, "Denver2", "NVIDIA", "v8-A" },
205 { CPU_ID_EMAG8180 & CPU_PARTMASK, "eMAG", "Ampere", "v8-A" }, 205 { CPU_ID_EMAG8180 & CPU_PARTMASK, "eMAG", "Ampere", "v8-A" },
206 { CPU_ID_NEOVERSEE1R1 & CPU_PARTMASK, "Neoverse E1", "Arm", "v8.2-A+" }, 206 { CPU_ID_NEOVERSEE1R1 & CPU_PARTMASK, "Neoverse E1", "Arm", "v8.2-A+" },
207 { CPU_ID_NEOVERSEN1R3 & CPU_PARTMASK, "Neoverse N1", "Arm", "v8.2-A+" }, 207 { CPU_ID_NEOVERSEN1R3 & CPU_PARTMASK, "Neoverse N1", "Arm", "v8.2-A+" },
208 { CPU_ID_THUNDERXRX, "ThunderX", "Cavium", "v8-A" }, 208 { CPU_ID_THUNDERXRX, "ThunderX", "Cavium", "v8-A" },
209 { CPU_ID_THUNDERX81XXRX, "ThunderX CN81XX", "Cavium", "v8-A" }, 209 { CPU_ID_THUNDERX81XXRX, "ThunderX CN81XX", "Cavium", "v8-A" },
210 { CPU_ID_THUNDERX83XXRX, "ThunderX CN83XX", "Cavium", "v8-A" }, 210 { CPU_ID_THUNDERX83XXRX, "ThunderX CN83XX", "Cavium", "v8-A" },
211 { CPU_ID_THUNDERX2RX, "ThunderX2", "Marvell", "v8.1-A" }, 211 { CPU_ID_THUNDERX2RX, "ThunderX2", "Marvell", "v8.1-A" },
212 { CPU_ID_APPLE_M1_ICESTORM & CPU_PARTMASK, "M1 Icestorm", "Apple", "Apple Silicon" }, 212 { CPU_ID_APPLE_M1_ICESTORM & CPU_PARTMASK, "M1 Icestorm", "Apple", "Apple Silicon" },
213 { CPU_ID_APPLE_M1_FIRESTORM & CPU_PARTMASK, "M1 Firestorm", "Apple", "Apple Silicon" }, 213 { CPU_ID_APPLE_M1_FIRESTORM & CPU_PARTMASK, "M1 Firestorm", "Apple", "Apple Silicon" },
214}; 214};
215 215
216static void 216static void
217identify_aarch64_model(uint32_t cpuid, char *buf, size_t len) 217identify_aarch64_model(uint32_t cpuid, char *buf, size_t len)
218{ 218{
219 int i; 219 int i;
220 uint32_t cpupart, variant, revision; 220 uint32_t cpupart, variant, revision;
221 221
222 cpupart = cpuid & CPU_PARTMASK; 222 cpupart = cpuid & CPU_PARTMASK;
223 variant = __SHIFTOUT(cpuid, CPU_ID_VARIANT_MASK); 223 variant = __SHIFTOUT(cpuid, CPU_ID_VARIANT_MASK);
224 revision = __SHIFTOUT(cpuid, CPU_ID_REVISION_MASK); 224 revision = __SHIFTOUT(cpuid, CPU_ID_REVISION_MASK);
225 225
226 for (i = 0; i < __arraycount(cpuids); i++) { 226 for (i = 0; i < __arraycount(cpuids); i++) {
227 if (cpupart == cpuids[i].cpu_partnum) { 227 if (cpupart == cpuids[i].cpu_partnum) {
228 snprintf(buf, len, "%s %s r%dp%d (%s)", 228 snprintf(buf, len, "%s %s r%dp%d (%s)",
229 cpuids[i].cpu_vendor, cpuids[i].cpu_name, 229 cpuids[i].cpu_vendor, cpuids[i].cpu_name,
230 variant, revision, 230 variant, revision,
231 cpuids[i].cpu_architecture); 231 cpuids[i].cpu_architecture);
232 return; 232 return;
233 } 233 }
234 } 234 }
235 235
236 snprintf(buf, len, "unknown CPU (ID = 0x%08x)", cpuid); 236 snprintf(buf, len, "unknown CPU (ID = 0x%08x)", cpuid);
237} 237}
238 238
239static void 239static void
240cpu_identify(device_t self, struct cpu_info *ci) 240cpu_identify(device_t self, struct cpu_info *ci)
241{ 241{
242 char model[128]; 242 char model[128];
243 const char *m; 243 const char *m;
244 244
245 identify_aarch64_model(ci->ci_id.ac_midr, model, sizeof(model)); 245 identify_aarch64_model(ci->ci_id.ac_midr, model, sizeof(model));
246 246
247 aprint_naive("\n"); 247 aprint_naive("\n");
248 aprint_normal(": %s, id 0x%lx\n", model, ci->ci_cpuid); 248 aprint_normal(": %s, id 0x%lx\n", model, ci->ci_cpuid);
249 aprint_normal_dev(ci->ci_dev, "package %u, core %u, smt %u\n", 249 aprint_normal_dev(ci->ci_dev, "package %u, core %u, smt %u\n",
250 ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id); 250 ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
251 251
252 if (ci->ci_index == 0) { 252 if (ci->ci_index == 0) {
253 m = cpu_getmodel(); 253 m = cpu_getmodel();
254 if (m == NULL || *m == 0) 254 if (m == NULL || *m == 0)
255 cpu_setmodel("%s", model); 255 cpu_setmodel("%s", model);
256 256
257 if (CPU_ID_ERRATA_CAVIUM_THUNDERX_1_1_P(ci->ci_id.ac_midr)) 257 if (CPU_ID_ERRATA_CAVIUM_THUNDERX_1_1_P(ci->ci_id.ac_midr))
258 aprint_normal("WARNING: ThunderX Pass 1.1 detected.\n" 258 aprint_normal("WARNING: ThunderX Pass 1.1 detected.\n"
259 "This has known hardware bugs that may cause the " 259 "This has known hardware bugs that may cause the "
260 "incorrect operation of atomic operations.\n"); 260 "incorrect operation of atomic operations.\n");
261 } 261 }
262} 262}
263 263
264static void 264static void
265cpu_identify1(device_t self, struct cpu_info *ci) 265cpu_identify1(device_t self, struct cpu_info *ci)
266{ 266{
267 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 267 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
268 uint64_t sctlr = ci->ci_sctlr_el1; 268 uint64_t sctlr = ci->ci_sctlr_el1;
269 269
270 if (sctlr & SCTLR_I) 270 if (sctlr & SCTLR_I)
271 aprint_verbose_dev(self, "IC enabled"); 271 aprint_verbose_dev(self, "IC enabled");
272 else 272 else
273 aprint_verbose_dev(self, "IC disabled"); 273 aprint_verbose_dev(self, "IC disabled");
274 274
275 if (sctlr & SCTLR_C) 275 if (sctlr & SCTLR_C)
276 aprint_verbose(", DC enabled"); 276 aprint_verbose(", DC enabled");
277 else 277 else
278 aprint_verbose(", DC disabled"); 278 aprint_verbose(", DC disabled");
279 279
280 if (sctlr & SCTLR_A) 280 if (sctlr & SCTLR_A)
281 aprint_verbose(", Alignment check enabled\n"); 281 aprint_verbose(", Alignment check enabled\n");
282 else { 282 else {
283 switch (sctlr & (SCTLR_SA | SCTLR_SA0)) { 283 switch (sctlr & (SCTLR_SA | SCTLR_SA0)) {
284 case SCTLR_SA | SCTLR_SA0: 284 case SCTLR_SA | SCTLR_SA0:
285 aprint_verbose( 285 aprint_verbose(
286 ", EL0/EL1 stack Alignment check enabled\n"); 286 ", EL0/EL1 stack Alignment check enabled\n");
287 break; 287 break;
288 case SCTLR_SA: 288 case SCTLR_SA:
289 aprint_verbose(", EL1 stack Alignment check enabled\n"); 289 aprint_verbose(", EL1 stack Alignment check enabled\n");
290 break; 290 break;
291 case SCTLR_SA0: 291 case SCTLR_SA0:
292 aprint_verbose(", EL0 stack Alignment check enabled\n"); 292 aprint_verbose(", EL0 stack Alignment check enabled\n");
293 break; 293 break;
294 case 0: 294 case 0:
295 aprint_verbose(", Alignment check disabled\n"); 295 aprint_verbose(", Alignment check disabled\n");
296 break; 296 break;
297 } 297 }
298 } 298 }
299 299
300 /* 300 /*
301 * CTR - Cache Type Register 301 * CTR - Cache Type Register
302 */ 302 */
303 const uint64_t ctr = id->ac_ctr; 303 const uint64_t ctr = id->ac_ctr;
304 const uint64_t clidr = id->ac_clidr; 304 const uint64_t clidr = id->ac_clidr;
305 aprint_verbose_dev(self, "Cache Writeback Granule %" PRIu64 "B," 305 aprint_verbose_dev(self, "Cache Writeback Granule %" PRIu64 "B,"
306 " Exclusives Reservation Granule %" PRIu64 "B\n", 306 " Exclusives Reservation Granule %" PRIu64 "B\n",
307 __SHIFTOUT(ctr, CTR_EL0_CWG_LINE) * 4, 307 __SHIFTOUT(ctr, CTR_EL0_CWG_LINE) * 4,
308 __SHIFTOUT(ctr, CTR_EL0_ERG_LINE) * 4); 308 __SHIFTOUT(ctr, CTR_EL0_ERG_LINE) * 4);
309 309
310 aprint_verbose_dev(self, "Dcache line %ld, Icache line %ld" 310 aprint_verbose_dev(self, "Dcache line %ld, Icache line %ld"
311 ", DIC=%lu, IDC=%lu, LoUU=%lu, LoC=%lu, LoUIS=%lu\n", 311 ", DIC=%lu, IDC=%lu, LoUU=%lu, LoC=%lu, LoUIS=%lu\n",
312 sizeof(int) << __SHIFTOUT(ctr, CTR_EL0_DMIN_LINE), 312 sizeof(int) << __SHIFTOUT(ctr, CTR_EL0_DMIN_LINE),
313 sizeof(int) << __SHIFTOUT(ctr, CTR_EL0_IMIN_LINE), 313 sizeof(int) << __SHIFTOUT(ctr, CTR_EL0_IMIN_LINE),
314 __SHIFTOUT(ctr, CTR_EL0_DIC), 314 __SHIFTOUT(ctr, CTR_EL0_DIC),
315 __SHIFTOUT(ctr, CTR_EL0_IDC), 315 __SHIFTOUT(ctr, CTR_EL0_IDC),
316 __SHIFTOUT(clidr, CLIDR_LOUU), 316 __SHIFTOUT(clidr, CLIDR_LOUU),
317 __SHIFTOUT(clidr, CLIDR_LOC), 317 __SHIFTOUT(clidr, CLIDR_LOC),
318 __SHIFTOUT(clidr, CLIDR_LOUIS)); 318 __SHIFTOUT(clidr, CLIDR_LOUIS));
319} 319}
320 320
321 321
322/* 322/*
323 * identify vfp, etc. 323 * identify vfp, etc.
324 */ 324 */
325static void 325static void
326cpu_identify2(device_t self, struct cpu_info *ci) 326cpu_identify2(device_t self, struct cpu_info *ci)
327{ 327{
328 struct aarch64_sysctl_cpu_id * const id = &ci->ci_id; 328 struct aarch64_sysctl_cpu_id * const id = &ci->ci_id;
329 329
330 aprint_debug_dev(self, "midr=0x%" PRIx32 " mpidr=0x%" PRIx32 "\n", 330 aprint_debug_dev(self, "midr=0x%" PRIx32 " mpidr=0x%" PRIx32 "\n",
331 (uint32_t)id->ac_midr, (uint32_t)id->ac_mpidr); 331 (uint32_t)id->ac_midr, (uint32_t)id->ac_mpidr);
332 aprint_verbose_dev(self, "revID=0x%" PRIx64, id->ac_revidr); 332 aprint_verbose_dev(self, "revID=0x%" PRIx64, id->ac_revidr);
333 333
334 /* ID_AA64DFR0_EL1 */ 334 /* ID_AA64DFR0_EL1 */
335 switch (__SHIFTOUT(id->ac_aa64dfr0, ID_AA64DFR0_EL1_PMUVER)) { 335 switch (__SHIFTOUT(id->ac_aa64dfr0, ID_AA64DFR0_EL1_PMUVER)) {
336 case ID_AA64DFR0_EL1_PMUVER_V3: 336 case ID_AA64DFR0_EL1_PMUVER_V3:
337 aprint_verbose(", PMCv3"); 337 aprint_verbose(", PMCv3");
338 break; 338 break;
339 case ID_AA64DFR0_EL1_PMUVER_NOV3: 339 case ID_AA64DFR0_EL1_PMUVER_NOV3:
340 aprint_verbose(", PMC"); 340 aprint_verbose(", PMC");
341 break; 341 break;
342 } 342 }
343 343
344 /* ID_AA64MMFR0_EL1 */ 344 /* ID_AA64MMFR0_EL1 */
345 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN4)) { 345 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN4)) {
346 case ID_AA64MMFR0_EL1_TGRAN4_4KB: 346 case ID_AA64MMFR0_EL1_TGRAN4_4KB:
347 aprint_verbose(", 4k table"); 347 aprint_verbose(", 4k table");
348 break; 348 break;
349 } 349 }
350 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN16)) { 350 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN16)) {
351 case ID_AA64MMFR0_EL1_TGRAN16_16KB: 351 case ID_AA64MMFR0_EL1_TGRAN16_16KB:
352 aprint_verbose(", 16k table"); 352 aprint_verbose(", 16k table");
353 break; 353 break;
354 } 354 }
355 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN64)) { 355 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN64)) {
356 case ID_AA64MMFR0_EL1_TGRAN64_64KB: 356 case ID_AA64MMFR0_EL1_TGRAN64_64KB:
357 aprint_verbose(", 64k table"); 357 aprint_verbose(", 64k table");
358 break; 358 break;
359 } 359 }
360 360
361 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_ASIDBITS)) { 361 switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_ASIDBITS)) {
362 case ID_AA64MMFR0_EL1_ASIDBITS_8BIT: 362 case ID_AA64MMFR0_EL1_ASIDBITS_8BIT:
363 aprint_verbose(", 8bit ASID"); 363 aprint_verbose(", 8bit ASID");
364 break; 364 break;
365 case ID_AA64MMFR0_EL1_ASIDBITS_16BIT: 365 case ID_AA64MMFR0_EL1_ASIDBITS_16BIT:
366 aprint_verbose(", 16bit ASID"); 366 aprint_verbose(", 16bit ASID");
367 break; 367 break;
368 } 368 }
369 aprint_verbose("\n"); 369 aprint_verbose("\n");
370 370
371 aprint_verbose_dev(self, "auxID=0x%" PRIx64, ci->ci_id.ac_aa64isar0); 371 aprint_verbose_dev(self, "auxID=0x%" PRIx64, ci->ci_id.ac_aa64isar0);
372 372
373 /* PFR0 */ 373 /* PFR0 */
374 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_CSV3)) { 374 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_CSV3)) {
375 case ID_AA64PFR0_EL1_CSV3_IMPL: 375 case ID_AA64PFR0_EL1_CSV3_IMPL:
376 aprint_verbose(", CSV3"); 376 aprint_verbose(", CSV3");
377 break; 377 break;
378 } 378 }
379 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_CSV2)) { 379 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_CSV2)) {
380 case ID_AA64PFR0_EL1_CSV2_IMPL: 380 case ID_AA64PFR0_EL1_CSV2_IMPL:
381 aprint_verbose(", CSV2"); 381 aprint_verbose(", CSV2");
382 break; 382 break;
383 } 383 }
384 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_GIC)) { 384 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_GIC)) {
385 case ID_AA64PFR0_EL1_GIC_CPUIF_EN: 385 case ID_AA64PFR0_EL1_GIC_CPUIF_EN:
386 aprint_verbose(", GICv3"); 386 aprint_verbose(", GICv3");
387 break; 387 break;
388 } 388 }
389 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_FP)) { 389 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_FP)) {
390 case ID_AA64PFR0_EL1_FP_NONE: 390 case ID_AA64PFR0_EL1_FP_NONE:
391 break; 391 break;
392 default: 392 default:
393 aprint_verbose(", FP"); 393 aprint_verbose(", FP");
394 break; 394 break;
395 } 395 }
396 396
397 /* ISAR0 */ 397 /* ISAR0 */
398 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_CRC32)) { 398 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_CRC32)) {
399 case ID_AA64ISAR0_EL1_CRC32_CRC32X: 399 case ID_AA64ISAR0_EL1_CRC32_CRC32X:
400 aprint_verbose(", CRC32"); 400 aprint_verbose(", CRC32");
401 break; 401 break;
402 } 402 }
403 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA1)) { 403 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA1)) {
404 case ID_AA64ISAR0_EL1_SHA1_SHA1CPMHSU: 404 case ID_AA64ISAR0_EL1_SHA1_SHA1CPMHSU:
405 aprint_verbose(", SHA1"); 405 aprint_verbose(", SHA1");
406 break; 406 break;
407 } 407 }
408 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA2)) { 408 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA2)) {
409 case ID_AA64ISAR0_EL1_SHA2_SHA256HSU: 409 case ID_AA64ISAR0_EL1_SHA2_SHA256HSU:
410 aprint_verbose(", SHA256"); 410 aprint_verbose(", SHA256");
411 break; 411 break;
412 } 412 }
413 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_AES)) { 413 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_AES)) {
414 case ID_AA64ISAR0_EL1_AES_AES: 414 case ID_AA64ISAR0_EL1_AES_AES:
415 aprint_verbose(", AES"); 415 aprint_verbose(", AES");
416 break; 416 break;
417 case ID_AA64ISAR0_EL1_AES_PMUL: 417 case ID_AA64ISAR0_EL1_AES_PMUL:
418 aprint_verbose(", AES+PMULL"); 418 aprint_verbose(", AES+PMULL");
419 break; 419 break;
420 } 420 }
421 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_RNDR)) { 421 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_RNDR)) {
422 case ID_AA64ISAR0_EL1_RNDR_RNDRRS: 422 case ID_AA64ISAR0_EL1_RNDR_RNDRRS:
423 aprint_verbose(", RNDRRS"); 423 aprint_verbose(", RNDRRS");
424 break; 424 break;
425 } 425 }
426 426
427 /* PFR0:DIT -- data-independent timing support */ 427 /* PFR0:DIT -- data-independent timing support */
428 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_DIT)) { 428 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_DIT)) {
429 case ID_AA64PFR0_EL1_DIT_IMPL: 429 case ID_AA64PFR0_EL1_DIT_IMPL:
430 aprint_verbose(", DIT"); 430 aprint_verbose(", DIT");
431 break; 431 break;
432 } 432 }
433 433
434 /* PFR0:AdvSIMD */ 434 /* PFR0:AdvSIMD */
435 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) { 435 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
436 case ID_AA64PFR0_EL1_ADV_SIMD_NONE: 436 case ID_AA64PFR0_EL1_ADV_SIMD_NONE:
437 break; 437 break;
438 default: 438 default:
439 aprint_verbose(", NEON"); 439 aprint_verbose(", NEON");
440 break; 440 break;
441 } 441 }
442 442
443 /* MVFR0/MVFR1 */ 443 /* MVFR0/MVFR1 */
444 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPROUND)) { 444 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPROUND)) {
445 case MVFR0_FPROUND_ALL: 445 case MVFR0_FPROUND_ALL:
446 aprint_verbose(", rounding"); 446 aprint_verbose(", rounding");
447 break; 447 break;
448 } 448 }
449 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPTRAP)) { 449 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPTRAP)) {
450 case MVFR0_FPTRAP_TRAP: 450 case MVFR0_FPTRAP_TRAP:
451 aprint_verbose(", exceptions"); 451 aprint_verbose(", exceptions");
452 break; 452 break;
453 } 453 }
454 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPDNAN)) { 454 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPDNAN)) {
455 case MVFR1_FPDNAN_NAN: 455 case MVFR1_FPDNAN_NAN:
456 aprint_verbose(", NaN propagation"); 456 aprint_verbose(", NaN propagation");
457 break; 457 break;
458 } 458 }
459 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPFTZ)) { 459 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPFTZ)) {
460 case MVFR1_FPFTZ_DENORMAL: 460 case MVFR1_FPFTZ_DENORMAL:
461 aprint_verbose(", denormals"); 461 aprint_verbose(", denormals");
462 break; 462 break;
463 } 463 }
464 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_SIMDREG)) { 464 switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_SIMDREG)) {
465 case MVFR0_SIMDREG_16x64: 465 case MVFR0_SIMDREG_16x64:
466 aprint_verbose(", 16x64bitRegs"); 466 aprint_verbose(", 16x64bitRegs");
467 break; 467 break;
468 case MVFR0_SIMDREG_32x64: 468 case MVFR0_SIMDREG_32x64:
469 aprint_verbose(", 32x64bitRegs"); 469 aprint_verbose(", 32x64bitRegs");
470 break; 470 break;
471 } 471 }
472 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_SIMDFMAC)) { 472 switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_SIMDFMAC)) {
473 case MVFR1_SIMDFMAC_FMAC: 473 case MVFR1_SIMDFMAC_FMAC:
474 aprint_verbose(", Fused Multiply-Add"); 474 aprint_verbose(", Fused Multiply-Add");
475 break; 475 break;
476 } 476 }
477 477
478 aprint_verbose("\n"); 478 aprint_verbose("\n");
479} 479}
480 480
481/* 481/*
482 * Enable the performance counter, then estimate frequency for 482 * Enable the performance counter, then estimate frequency for
483 * the current PE and store the result in cpu_cc_freq. 483 * the current PE and store the result in cpu_cc_freq.
484 */ 484 */
485static void 485static void
486cpu_init_counter(struct cpu_info *ci) 486cpu_init_counter(struct cpu_info *ci)
487{ 487{
488 const uint64_t dfr0 = reg_id_aa64dfr0_el1_read(); 488 const uint64_t dfr0 = reg_id_aa64dfr0_el1_read();
489 const u_int pmuver = __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_PMUVER); 489 const u_int pmuver = __SHIFTOUT(dfr0, ID_AA64DFR0_EL1_PMUVER);
490 if (pmuver == ID_AA64DFR0_EL1_PMUVER_NONE) { 490 if (pmuver == ID_AA64DFR0_EL1_PMUVER_NONE) {
491 /* Performance Monitors Extension not implemented. */ 491 /* Performance Monitors Extension not implemented. */
492 return; 492 return;
493 } 493 }
494 if (pmuver == ID_AA64DFR0_EL1_PMUVER_IMPL) { 494 if (pmuver == ID_AA64DFR0_EL1_PMUVER_IMPL) {
495 /* Non-standard Performance Monitors are not supported. */ 495 /* Non-standard Performance Monitors are not supported. */
496 return; 496 return;
497 } 497 }
498 498
499 reg_pmcr_el0_write(PMCR_E | PMCR_C); 499 reg_pmcr_el0_write(PMCR_E | PMCR_C);
500 reg_pmcntenset_el0_write(PMCNTEN_C); 500 reg_pmcntenset_el0_write(PMCNTEN_C);
501 501
502 const uint32_t prev = cpu_counter32(); 502 const uint32_t prev = cpu_counter32();
503 delay(100000); 503 delay(100000);
504 ci->ci_data.cpu_cc_freq = (cpu_counter32() - prev) * 10; 504 ci->ci_data.cpu_cc_freq = (cpu_counter32() - prev) * 10;
505} 505}
506 506
507/* 507/*
508 * Fill in this CPUs id data. Must be called on all cpus. 508 * Fill in this CPUs id data. Must be called on all cpus.
509 */ 509 */
510void __noasan 510void __noasan
511cpu_setup_id(struct cpu_info *ci) 511cpu_setup_id(struct cpu_info *ci)
512{ 512{
513 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 513 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
514 514
515 /* SCTLR - System Control Register */ 515 /* SCTLR - System Control Register */
516 ci->ci_sctlr_el1 = reg_sctlr_el1_read(); 516 ci->ci_sctlr_el1 = reg_sctlr_el1_read();
517 517
518 memset(id, 0, sizeof *id); 518 memset(id, 0, sizeof *id);
519 519
520 id->ac_midr = reg_midr_el1_read(); 520 id->ac_midr = reg_midr_el1_read();
521 id->ac_revidr = reg_revidr_el1_read(); 521 id->ac_revidr = reg_revidr_el1_read();
522 id->ac_mpidr = reg_mpidr_el1_read(); 522 id->ac_mpidr = reg_mpidr_el1_read();
523 523
524 id->ac_aa64dfr0 = reg_id_aa64dfr0_el1_read(); 524 id->ac_aa64dfr0 = reg_id_aa64dfr0_el1_read();
525 id->ac_aa64dfr1 = reg_id_aa64dfr1_el1_read(); 525 id->ac_aa64dfr1 = reg_id_aa64dfr1_el1_read();
526 526
527 id->ac_aa64isar0 = reg_id_aa64isar0_el1_read(); 527 id->ac_aa64isar0 = reg_id_aa64isar0_el1_read();
528 id->ac_aa64isar1 = reg_id_aa64isar1_el1_read(); 528 id->ac_aa64isar1 = reg_id_aa64isar1_el1_read();
529 529
530 id->ac_aa64mmfr0 = reg_id_aa64mmfr0_el1_read(); 530 id->ac_aa64mmfr0 = reg_id_aa64mmfr0_el1_read();
531 id->ac_aa64mmfr1 = reg_id_aa64mmfr1_el1_read(); 531 id->ac_aa64mmfr1 = reg_id_aa64mmfr1_el1_read();
532 id->ac_aa64mmfr2 = reg_id_aa64mmfr2_el1_read(); 532 id->ac_aa64mmfr2 = reg_id_aa64mmfr2_el1_read();
533 533
534 id->ac_mvfr0 = reg_mvfr0_el1_read(); 534 id->ac_mvfr0 = reg_mvfr0_el1_read();
535 id->ac_mvfr1 = reg_mvfr1_el1_read(); 535 id->ac_mvfr1 = reg_mvfr1_el1_read();
536 id->ac_mvfr2 = reg_mvfr2_el1_read(); 536 id->ac_mvfr2 = reg_mvfr2_el1_read();
537 537
538 id->ac_clidr = reg_clidr_el1_read(); 538 id->ac_clidr = reg_clidr_el1_read();
539 id->ac_ctr = reg_ctr_el0_read(); 539 id->ac_ctr = reg_ctr_el0_read();
540 540
541 /* Only in ARMv8.2. */ 541 /* Only in ARMv8.2. */
542 id->ac_aa64zfr0 = 0 /* reg_id_aa64zfr0_el1_read() */; 542 id->ac_aa64zfr0 = 0 /* reg_id_aa64zfr0_el1_read() */;
543 543
544 id->ac_aa64pfr0 = reg_id_aa64pfr0_el1_read(); 544 id->ac_aa64pfr0 = reg_id_aa64pfr0_el1_read();
545 id->ac_aa64pfr1 = reg_id_aa64pfr1_el1_read(); 545 id->ac_aa64pfr1 = reg_id_aa64pfr1_el1_read();
546} 546}
547 547
548/* 548/*
549 * setup the per-cpu sysctl tree. 549 * setup the per-cpu sysctl tree.
550 */ 550 */
551static void 551static void
552cpu_setup_sysctl(device_t dv, struct cpu_info *ci) 552cpu_setup_sysctl(device_t dv, struct cpu_info *ci)
553{ 553{
554 const struct sysctlnode *cpunode = NULL; 554 const struct sysctlnode *cpunode = NULL;
555 555
556 sysctl_createv(NULL, 0, NULL, &cpunode, 556 sysctl_createv(NULL, 0, NULL, &cpunode,
557 CTLFLAG_PERMANENT, 557 CTLFLAG_PERMANENT,
558 CTLTYPE_NODE, device_xname(dv), NULL, 558 CTLTYPE_NODE, device_xname(dv), NULL,
559 NULL, 0, NULL, 0, 559 NULL, 0, NULL, 0,
560 CTL_MACHDEP, 560 CTL_MACHDEP,
561 CTL_CREATE, CTL_EOL); 561 CTL_CREATE, CTL_EOL);
562 562
563 if (cpunode == NULL) 563 if (cpunode == NULL)
564 return; 564 return;
565 565
566 sysctl_createv(NULL, 0, &cpunode, NULL, 566 sysctl_createv(NULL, 0, &cpunode, NULL,
567 CTLFLAG_PERMANENT, 567 CTLFLAG_PERMANENT,
568 CTLTYPE_STRUCT, "cpu_id", NULL, 568 CTLTYPE_STRUCT, "cpu_id", NULL,
569 NULL, 0, &ci->ci_id, sizeof(ci->ci_id), 569 NULL, 0, &ci->ci_id, sizeof(ci->ci_id),
570 CTL_CREATE, CTL_EOL); 570 CTL_CREATE, CTL_EOL);
571} 571}
572 572
573static struct krndsource rndrrs_source; 573static struct krndsource rndrrs_source;
574 574
575static void 575static void
576rndrrs_get(size_t nbytes, void *cookie) 576rndrrs_get(size_t nbytes, void *cookie)
577{ 577{
578 /* Entropy bits per data byte, wild-arse guess. */ 578 /* Entropy bits per data byte, wild-arse guess. */
579 const unsigned bpb = 4; 579 const unsigned bpb = 4;
580 size_t nbits = nbytes*NBBY; 580 size_t nbits = nbytes*NBBY;
581 uint64_t x; 581 uint64_t x;
582 int error; 582 int error;
583 583
584 while (nbits) { 584 while (nbits) {
585 /* 585 /*
586 * x := random 64-bit sample 586 * x := random 64-bit sample
587 * error := Z bit, set to 1 if sample is bad 587 * error := Z bit, set to 1 if sample is bad
588 * 588 *
589 * XXX This should be done by marking the function 589 * XXX This should be done by marking the function
590 * __attribute__((target("arch=armv8.5-a+rng"))) and 590 * __attribute__((target("arch=armv8.5-a+rng"))) and
591 * using `mrs %0, rndrrs', but: 591 * using `mrs %0, rndrrs', but:
592 * 592 *
593 * (a) the version of gcc we use doesn't support that, 593 * (a) the version of gcc we use doesn't support that,
594 * and 594 * and
595 * (b) clang doesn't seem to like `rndrrs' itself. 595 * (b) clang doesn't seem to like `rndrrs' itself.
596 * 596 *
597 * So we use the numeric encoding for now. 597 * So we use the numeric encoding for now.
598 */ 598 */
599 __asm __volatile("" 599 __asm __volatile(""
600 "mrs %0, s3_3_c2_c4_1\n" 600 "mrs %0, s3_3_c2_c4_1\n"
601 "cset %w1, eq" 601 "cset %w1, eq"
602 : "=r"(x), "=r"(error)); 602 : "=r"(x), "=r"(error));
603 if (error) 603 if (error)
604 break; 604 break;
605 rnd_add_data_sync(&rndrrs_source, &x, sizeof(x), 605 rnd_add_data_sync(&rndrrs_source, &x, sizeof(x),
606 bpb*sizeof(x)); 606 bpb*sizeof(x));
607 nbits -= MIN(nbits, bpb*sizeof(x)); 607 nbits -= MIN(nbits, bpb*sizeof(x));
608 } 608 }
609 609
610 explicit_memset(&x, 0, sizeof x); 610 explicit_memset(&x, 0, sizeof x);
611} 611}
612 612
613/* 613/*
614 * setup the RNDRRS entropy source 614 * setup the RNDRRS entropy source
615 */ 615 */
616static void 616static void
617cpu_setup_rng(device_t dv, struct cpu_info *ci) 617cpu_setup_rng(device_t dv, struct cpu_info *ci)
618{ 618{
619 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 619 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
620 620
621 /* Verify that it is supported. */ 621 /* Verify that it is supported. */
622 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_RNDR)) { 622 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_RNDR)) {
623 case ID_AA64ISAR0_EL1_RNDR_RNDRRS: 623 case ID_AA64ISAR0_EL1_RNDR_RNDRRS:
624 break; 624 break;
625 default: 625 default:
626 return; 626 return;
627 } 627 }
628 628
629 /* Attach it. */ 629 /* Attach it. */
630 rndsource_setcb(&rndrrs_source, rndrrs_get, NULL); 630 rndsource_setcb(&rndrrs_source, rndrrs_get, NULL);
631 rnd_attach_source(&rndrrs_source, "rndrrs", RND_TYPE_RNG, 631 rnd_attach_source(&rndrrs_source, "rndrrs", RND_TYPE_RNG,
632 RND_FLAG_DEFAULT|RND_FLAG_HASCB); 632 RND_FLAG_DEFAULT|RND_FLAG_HASCB);
633} 633}
634 634
635/* 635/*
636 * setup the AES implementation 636 * setup the AES implementation
637 */ 637 */
638static void 638static void
639cpu_setup_aes(device_t dv, struct cpu_info *ci) 639cpu_setup_aes(device_t dv, struct cpu_info *ci)
640{ 640{
641 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 641 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
642 642
643 /* Check for ARMv8.0-AES support. */ 643 /* Check for ARMv8.0-AES support. */
644 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_AES)) { 644 switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_AES)) {
645 case ID_AA64ISAR0_EL1_AES_AES: 645 case ID_AA64ISAR0_EL1_AES_AES:
646 case ID_AA64ISAR0_EL1_AES_PMUL: 646 case ID_AA64ISAR0_EL1_AES_PMUL:
647 aes_md_init(&aes_armv8_impl); 647 aes_md_init(&aes_armv8_impl);
648 return; 648 return;
649 default: 649 default:
650 break; 650 break;
651 } 651 }
652 652
653 /* Failing that, check for SIMD support. */ 653 /* Failing that, check for SIMD support. */
654 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) { 654 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
655 case ID_AA64PFR0_EL1_ADV_SIMD_IMPL: 655 case ID_AA64PFR0_EL1_ADV_SIMD_IMPL:
656 aes_md_init(&aes_neon_impl); 656 aes_md_init(&aes_neon_impl);
657 return; 657 return;
658 default: 658 default:
659 break; 659 break;
660 } 660 }
661} 661}
662 662
663/* 663/*
664 * setup the ChaCha implementation 664 * setup the ChaCha implementation
665 */ 665 */
666static void 666static void
667cpu_setup_chacha(device_t dv, struct cpu_info *ci) 667cpu_setup_chacha(device_t dv, struct cpu_info *ci)
668{ 668{
669 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 669 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
670 670
671 /* Check for SIMD support. */ 671 /* Check for SIMD support. */
672 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) { 672 switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
673 case ID_AA64PFR0_EL1_ADV_SIMD_IMPL: 673 case ID_AA64PFR0_EL1_ADV_SIMD_IMPL:
674 chacha_md_init(&chacha_neon_impl); 674 chacha_md_init(&chacha_neon_impl);
675 return; 675 return;
676 default: 676 default:
677 break; 677 break;
678 } 678 }
679} 679}
680 680
681#ifdef MULTIPROCESSOR 681#ifdef MULTIPROCESSOR
682/* 682/*
683 * Initialise a secondary processor. 683 * Initialise a secondary processor.
684 * 684 *
685 * printf isn't available as kmutex(9) relies on curcpu which isn't setup yet. 685 * printf isn't available as kmutex(9) relies on curcpu which isn't setup yet.
686 * 686 *
687 */ 687 */
688void __noasan 688void __noasan
689cpu_init_secondary_processor(int cpuindex) 689cpu_init_secondary_processor(int cpuindex)
690{ 690{
691 struct cpu_info * ci = &cpu_info_store[cpuindex]; 691 struct cpu_info * ci = &cpu_info_store[cpuindex];
692 struct aarch64_sysctl_cpu_id *id = &ci->ci_id; 692 struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
693 693
694 aarch64_setcpufuncs(ci); 694 aarch64_setcpufuncs(ci);
695 695
696 /* Sets ci->ci_{sctlr,midr,mpidr}, etc */ 696 /* Sets ci->ci_{sctlr,midr,mpidr}, etc */
697 cpu_setup_id(ci); 697 cpu_setup_id(ci);
698 698
699 arm_cpu_topology_set(ci, id->ac_mpidr); 699 arm_cpu_topology_set(ci, id->ac_mpidr);
700 aarch64_getcacheinfo(ci); 700 aarch64_getcacheinfo(ci);
701 701
702 cpu_set_hatched(cpuindex); 702 cpu_set_hatched(cpuindex);
703 703
704 /* 704 /*
705 * return to assembly to wait for cpu_boot_secondary_processors 705 * return to assembly to wait for cpu_boot_secondary_processors
706 */ 706 */
707} 707}
708 708
709 709
710/* 710/*
711 * When we are called, the MMU and caches are on and we are running on the stack 711 * When we are called, the MMU and caches are on and we are running on the stack
712 * of the idlelwp for this cpu. 712 * of the idlelwp for this cpu.
713 */ 713 */
714void 714void
715cpu_hatch(struct cpu_info *ci) 715cpu_hatch(struct cpu_info *ci)
716{ 716{
717 KASSERT(curcpu() == ci); 717 KASSERT(curcpu() == ci);
718 KASSERT((reg_tcr_el1_read() & TCR_EPD0) != 0); 718 KASSERT((reg_tcr_el1_read() & TCR_EPD0) != 0);
719 719
720#ifdef DDB 720#ifdef DDB
721 db_machdep_cpu_init(); 721 db_machdep_cpu_init();
722#endif 722#endif
723 723
724 cpu_init_counter(ci); 724 cpu_init_counter(ci);
725 725
726 intr_cpu_init(ci); 726 intr_cpu_init(ci);
727 727
728#ifdef FDT 728#ifdef FDT
729 arm_fdt_cpu_hatch(ci); 729 arm_fdt_cpu_hatch(ci);
730#endif 730#endif
731 731
732 /* 732 /*
733 * clear my bit of arm_cpu_mbox to tell cpu_boot_secondary_processors(). 733 * clear my bit of arm_cpu_mbox to tell cpu_boot_secondary_processors().
734 * there are cpu0,1,2,3, and if cpu2 is unresponsive, 734 * there are cpu0,1,2,3, and if cpu2 is unresponsive,
735 * ci_index are each cpu0=0, cpu1=1, cpu2=undef, cpu3=2. 735 * ci_index are each cpu0=0, cpu1=1, cpu2=undef, cpu3=2.
736 * therefore we have to use device_unit instead of ci_index for mbox. 736 * therefore we have to use device_unit instead of ci_index for mbox.
737 */ 737 */
738 738
739 cpu_clr_mbox(device_unit(ci->ci_dev)); 739 cpu_clr_mbox(device_unit(ci->ci_dev));
740} 740}
741#endif /* MULTIPROCESSOR */ 741#endif /* MULTIPROCESSOR */

cvs diff -r1.152 -r1.153 src/sys/arch/arm/arm32/cpu.c (switch to unified diff)

--- src/sys/arch/arm/arm32/cpu.c 2021/10/31 16:23:47 1.152
+++ src/sys/arch/arm/arm32/cpu.c 2022/03/03 06:26:05 1.153
@@ -1,915 +1,915 @@ @@ -1,915 +1,915 @@
1/* $NetBSD: cpu.c,v 1.152 2021/10/31 16:23:47 skrll Exp $ */ 1/* $NetBSD: cpu.c,v 1.153 2022/03/03 06:26:05 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1995 Mark Brinicombe. 4 * Copyright (c) 1995 Mark Brinicombe.
5 * Copyright (c) 1995 Brini. 5 * Copyright (c) 1995 Brini.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by Brini. 18 * This product includes software developed by Brini.
19 * 4. The name of the company nor the name of the author may be used to 19 * 4. The name of the company nor the name of the author may be used to
20 * endorse or promote products derived from this software without specific 20 * endorse or promote products derived from this software without specific
21 * prior written permission. 21 * prior written permission.
22 * 22 *
23 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE. 33 * SUCH DAMAGE.
34 * 34 *
35 * RiscBSD kernel project 35 * RiscBSD kernel project
36 * 36 *
37 * cpu.c 37 * cpu.c
38 * 38 *
39 * Probing and configuration for the master CPU 39 * Probing and configuration for the master CPU
40 * 40 *
41 * Created : 10/10/95 41 * Created : 10/10/95
42 */ 42 */
43 43
44#include "opt_armfpe.h" 44#include "opt_armfpe.h"
45#include "opt_cputypes.h" 45#include "opt_cputypes.h"
46#include "opt_multiprocessor.h" 46#include "opt_multiprocessor.h"
47 47
48#include <sys/cdefs.h> 48#include <sys/cdefs.h>
49__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.152 2021/10/31 16:23:47 skrll Exp $"); 49__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.153 2022/03/03 06:26:05 riastradh Exp $");
50 50
51#include <sys/param.h> 51#include <sys/param.h>
52 52
53#include <sys/conf.h> 53#include <sys/conf.h>
54#include <sys/cpu.h> 54#include <sys/cpu.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/kmem.h> 56#include <sys/kmem.h>
57#include <sys/proc.h> 57#include <sys/proc.h>
58#include <sys/reboot.h> 58#include <sys/reboot.h>
59#include <sys/systm.h> 59#include <sys/systm.h>
60 60
61#include <uvm/uvm_extern.h> 61#include <uvm/uvm_extern.h>
62 62
63#include <arm/locore.h> 63#include <arm/locore.h>
64#include <arm/undefined.h> 64#include <arm/undefined.h>
65#include <arm/cpu_topology.h> 65#include <arm/cpu_topology.h>
66 66
67extern const char *cpu_arch; 67extern const char *cpu_arch;
68 68
69#ifdef MULTIPROCESSOR 69#ifdef MULTIPROCESSOR
70#ifdef MPDEBUG 70#ifdef MPDEBUG
71uint32_t arm_cpu_marker[2] __cacheline_aligned = { 0, 0 }; 71uint32_t arm_cpu_marker[2] __cacheline_aligned = { 0, 0 };
72#endif 72#endif
73 73
74#endif 74#endif
75 75
76/* Prototypes */ 76/* Prototypes */
77void identify_arm_cpu(device_t, struct cpu_info *); 77void identify_arm_cpu(device_t, struct cpu_info *);
78void identify_features(device_t, struct cpu_info *); 78void identify_features(device_t, struct cpu_info *);
79void identify_cortex_caches(device_t); 79void identify_cortex_caches(device_t);
80 80
81/* 81/*
82 * Identify the master (boot) CPU 82 * Identify the master (boot) CPU
83 */ 83 */
84 84
85void 85void
86cpu_attach(device_t dv, cpuid_t id) 86cpu_attach(device_t dv, cpuid_t id)
87{ 87{
88 const char * const xname = device_xname(dv); 88 const char * const xname = device_xname(dv);
89 const int unit = device_unit(dv); 89 const int unit = device_unit(dv);
90 struct cpu_info *ci; 90 struct cpu_info *ci;
91 91
92 if (unit == 0) { 92 if (unit == 0) {
93 ci = curcpu(); 93 ci = curcpu();
94 94
95 /* Read SCTLR from cpu */ 95 /* Read SCTLR from cpu */
96 ci->ci_ctrl = cpu_control(0, 0); 96 ci->ci_ctrl = cpu_control(0, 0);
97 97
98 /* Get the CPU ID from coprocessor 15 */ 98 /* Get the CPU ID from coprocessor 15 */
99 ci->ci_cpuid = id; 99 ci->ci_cpuid = id;
100 ci->ci_arm_cpuid = cpu_idnum(); 100 ci->ci_arm_cpuid = cpu_idnum();
101 ci->ci_arm_cputype = ci->ci_arm_cpuid & CPU_ID_CPU_MASK; 101 ci->ci_arm_cputype = ci->ci_arm_cpuid & CPU_ID_CPU_MASK;
102 ci->ci_arm_cpurev = ci->ci_arm_cpuid & CPU_ID_REVISION_MASK; 102 ci->ci_arm_cpurev = ci->ci_arm_cpuid & CPU_ID_REVISION_MASK;
103 103
104 /* 104 /*
105 * Get other sysregs for BP. APs information is grabbed in 105 * Get other sysregs for BP. APs information is grabbed in
106 * cpu_init_secondary_processor. 106 * cpu_init_secondary_processor.
107 */ 107 */
108 ci->ci_actlr = armreg_auxctl_read(); 108 ci->ci_actlr = armreg_auxctl_read();
109 ci->ci_revidr = armreg_revidr_read(); 109 ci->ci_revidr = armreg_revidr_read();
110 } else { 110 } else {
111#ifdef MULTIPROCESSOR 111#ifdef MULTIPROCESSOR
112 if ((boothowto & RB_MD1) != 0) { 112 if ((boothowto & RB_MD1) != 0) {
113 aprint_naive("\n"); 113 aprint_naive("\n");
114 aprint_normal(": multiprocessor boot disabled\n"); 114 aprint_normal(": multiprocessor boot disabled\n");
115 return; 115 return;
116 } 116 }
117 117
118 KASSERT(unit < MAXCPUS); 118 KASSERT(unit < MAXCPUS);
119 ci = &cpu_info_store[unit]; 119 ci = &cpu_info_store[unit];
120 120
121 KASSERT(cpu_info[unit] == NULL); 121 KASSERT(cpu_info[unit] == NULL);
122 ci->ci_cpl = IPL_HIGH; 122 ci->ci_cpl = IPL_HIGH;
123 ci->ci_cpuid = id; 123 ci->ci_cpuid = id;
124 ci->ci_data.cpu_cc_freq = cpu_info_store[0].ci_data.cpu_cc_freq; 124 ci->ci_data.cpu_cc_freq = cpu_info_store[0].ci_data.cpu_cc_freq;
125 125
126 ci->ci_undefsave[2] = cpu_info_store[0].ci_undefsave[2]; 126 ci->ci_undefsave[2] = cpu_info_store[0].ci_undefsave[2];
127 127
128 cpu_info[unit] = ci; 128 cpu_info[unit] = ci;
129 if (cpu_hatched_p(unit) == false) { 129 if (cpu_hatched_p(unit) == false) {
130 ci->ci_dev = dv; 130 ci->ci_dev = dv;
131 dv->dv_private = ci; 131 device_set_private(dv, ci);
132 aprint_naive(": disabled\n"); 132 aprint_naive(": disabled\n");
133 aprint_normal(": disabled (unresponsive)\n"); 133 aprint_normal(": disabled (unresponsive)\n");
134 return; 134 return;
135 } 135 }
136#else 136#else
137 aprint_naive(": disabled\n"); 137 aprint_naive(": disabled\n");
138 aprint_normal(": disabled (uniprocessor kernel)\n"); 138 aprint_normal(": disabled (uniprocessor kernel)\n");
139 return; 139 return;
140#endif 140#endif
141 } 141 }
142 142
143 ci->ci_dev = dv; 143 ci->ci_dev = dv;
144 dv->dv_private = ci; 144 device_set_private(dv, ci);
145 145
146 arm_cpu_do_topology(ci); 146 arm_cpu_do_topology(ci);
147 147
148 evcnt_attach_dynamic(&ci->ci_arm700bugcount, EVCNT_TYPE_MISC, 148 evcnt_attach_dynamic(&ci->ci_arm700bugcount, EVCNT_TYPE_MISC,
149 NULL, xname, "arm700swibug"); 149 NULL, xname, "arm700swibug");
150 150
151 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_0], EVCNT_TYPE_TRAP, 151 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_0], EVCNT_TYPE_TRAP,
152 NULL, xname, "vector abort"); 152 NULL, xname, "vector abort");
153 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_1], EVCNT_TYPE_TRAP, 153 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_WRTBUF_1], EVCNT_TYPE_TRAP,
154 NULL, xname, "terminal abort"); 154 NULL, xname, "terminal abort");
155 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_0], EVCNT_TYPE_TRAP, 155 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_0], EVCNT_TYPE_TRAP,
156 NULL, xname, "external linefetch abort (S)"); 156 NULL, xname, "external linefetch abort (S)");
157 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_1], EVCNT_TYPE_TRAP, 157 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_1], EVCNT_TYPE_TRAP,
158 NULL, xname, "external linefetch abort (P)"); 158 NULL, xname, "external linefetch abort (P)");
159 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_2], EVCNT_TYPE_TRAP, 159 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_2], EVCNT_TYPE_TRAP,
160 NULL, xname, "external non-linefetch abort (S)"); 160 NULL, xname, "external non-linefetch abort (S)");
161 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_3], EVCNT_TYPE_TRAP, 161 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSERR_3], EVCNT_TYPE_TRAP,
162 NULL, xname, "external non-linefetch abort (P)"); 162 NULL, xname, "external non-linefetch abort (P)");
163 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL1], EVCNT_TYPE_TRAP, 163 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL1], EVCNT_TYPE_TRAP,
164 NULL, xname, "external translation abort (L1)"); 164 NULL, xname, "external translation abort (L1)");
165 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL2], EVCNT_TYPE_TRAP, 165 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_BUSTRNL2], EVCNT_TYPE_TRAP,
166 NULL, xname, "external translation abort (L2)"); 166 NULL, xname, "external translation abort (L2)");
167 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_0], EVCNT_TYPE_TRAP, 167 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_0], EVCNT_TYPE_TRAP,
168 NULL, xname, "alignment abort (0)"); 168 NULL, xname, "alignment abort (0)");
169 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_1], EVCNT_TYPE_TRAP, 169 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_ALIGN_1], EVCNT_TYPE_TRAP,
170 NULL, xname, "alignment abort (1)"); 170 NULL, xname, "alignment abort (1)");
171 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_S], EVCNT_TYPE_TRAP, 171 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_S], EVCNT_TYPE_TRAP,
172 NULL, xname, "translation abort (S)"); 172 NULL, xname, "translation abort (S)");
173 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_P], EVCNT_TYPE_TRAP, 173 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_TRANS_P], EVCNT_TYPE_TRAP,
174 NULL, xname, "translation abort (P)"); 174 NULL, xname, "translation abort (P)");
175 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_S], EVCNT_TYPE_TRAP, 175 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_S], EVCNT_TYPE_TRAP,
176 NULL, xname, "domain abort (S)"); 176 NULL, xname, "domain abort (S)");
177 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_P], EVCNT_TYPE_TRAP, 177 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_DOMAIN_P], EVCNT_TYPE_TRAP,
178 NULL, xname, "domain abort (P)"); 178 NULL, xname, "domain abort (P)");
179 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_S], EVCNT_TYPE_TRAP, 179 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_S], EVCNT_TYPE_TRAP,
180 NULL, xname, "permission abort (S)"); 180 NULL, xname, "permission abort (S)");
181 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_P], EVCNT_TYPE_TRAP, 181 evcnt_attach_dynamic_nozero(&ci->ci_abt_evs[FAULT_PERM_P], EVCNT_TYPE_TRAP,
182 NULL, xname, "permission abort (P)"); 182 NULL, xname, "permission abort (P)");
183 evcnt_attach_dynamic_nozero(&ci->ci_und_ev, EVCNT_TYPE_TRAP, 183 evcnt_attach_dynamic_nozero(&ci->ci_und_ev, EVCNT_TYPE_TRAP,
184 NULL, xname, "undefined insn traps"); 184 NULL, xname, "undefined insn traps");
185 evcnt_attach_dynamic_nozero(&ci->ci_und_cp15_ev, EVCNT_TYPE_TRAP, 185 evcnt_attach_dynamic_nozero(&ci->ci_und_cp15_ev, EVCNT_TYPE_TRAP,
186 NULL, xname, "undefined cp15 insn traps"); 186 NULL, xname, "undefined cp15 insn traps");
187 187
188 ci->ci_kfpu_spl = -1; 188 ci->ci_kfpu_spl = -1;
189 189
190#ifdef MULTIPROCESSOR 190#ifdef MULTIPROCESSOR
191 if (unit != 0) { 191 if (unit != 0) {
192 mi_cpu_attach(ci); 192 mi_cpu_attach(ci);
193#ifdef ARM_MMU_EXTENDED 193#ifdef ARM_MMU_EXTENDED
194 pmap_tlb_info_attach(&pmap_tlb0_info, ci); 194 pmap_tlb_info_attach(&pmap_tlb0_info, ci);
195#endif 195#endif
196 } 196 }
197#endif 197#endif
198 198
199 identify_arm_cpu(dv, ci); 199 identify_arm_cpu(dv, ci);
200 200
201#ifdef CPU_STRONGARM 201#ifdef CPU_STRONGARM
202 if (ci->ci_arm_cputype == CPU_ID_SA110 && 202 if (ci->ci_arm_cputype == CPU_ID_SA110 &&
203 ci->ci_arm_cpurev < 3) { 203 ci->ci_arm_cpurev < 3) {
204 aprint_normal_dev(dv, "SA-110 with bugged STM^ instruction\n"); 204 aprint_normal_dev(dv, "SA-110 with bugged STM^ instruction\n");
205 } 205 }
206#endif 206#endif
207 207
208#ifdef CPU_ARM8 208#ifdef CPU_ARM8
209 if ((ci->ci_arm_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) { 209 if ((ci->ci_arm_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) {
210 int clock = arm8_clock_config(0, 0); 210 int clock = arm8_clock_config(0, 0);
211 char *fclk; 211 char *fclk;
212 aprint_normal_dev(dv, "ARM810 cp15=%02x", clock); 212 aprint_normal_dev(dv, "ARM810 cp15=%02x", clock);
213 aprint_normal(" clock:%s", (clock & 1) ? " dynamic" : ""); 213 aprint_normal(" clock:%s", (clock & 1) ? " dynamic" : "");
214 aprint_normal("%s", (clock & 2) ? " sync" : ""); 214 aprint_normal("%s", (clock & 2) ? " sync" : "");
215 switch ((clock >> 2) & 3) { 215 switch ((clock >> 2) & 3) {
216 case 0: 216 case 0:
217 fclk = "bus clock"; 217 fclk = "bus clock";
218 break; 218 break;
219 case 1: 219 case 1:
220 fclk = "ref clock"; 220 fclk = "ref clock";
221 break; 221 break;
222 case 3: 222 case 3:
223 fclk = "pll"; 223 fclk = "pll";
224 break; 224 break;
225 default: 225 default:
226 fclk = "illegal"; 226 fclk = "illegal";
227 break; 227 break;
228 } 228 }
229 aprint_normal(" fclk source=%s\n", fclk); 229 aprint_normal(" fclk source=%s\n", fclk);
230 } 230 }
231#endif 231#endif
232 232
233 vfp_attach(ci); 233 vfp_attach(ci);
234} 234}
235 235
236enum cpu_class { 236enum cpu_class {
237 CPU_CLASS_NONE, 237 CPU_CLASS_NONE,
238 CPU_CLASS_ARM2, 238 CPU_CLASS_ARM2,
239 CPU_CLASS_ARM2AS, 239 CPU_CLASS_ARM2AS,
240 CPU_CLASS_ARM3, 240 CPU_CLASS_ARM3,
241 CPU_CLASS_ARM6, 241 CPU_CLASS_ARM6,
242 CPU_CLASS_ARM7, 242 CPU_CLASS_ARM7,
243 CPU_CLASS_ARM7TDMI, 243 CPU_CLASS_ARM7TDMI,
244 CPU_CLASS_ARM8, 244 CPU_CLASS_ARM8,
245 CPU_CLASS_ARM9TDMI, 245 CPU_CLASS_ARM9TDMI,
246 CPU_CLASS_ARM9ES, 246 CPU_CLASS_ARM9ES,
247 CPU_CLASS_ARM9EJS, 247 CPU_CLASS_ARM9EJS,
248 CPU_CLASS_ARM10E, 248 CPU_CLASS_ARM10E,
249 CPU_CLASS_ARM10EJ, 249 CPU_CLASS_ARM10EJ,
250 CPU_CLASS_SA1, 250 CPU_CLASS_SA1,
251 CPU_CLASS_XSCALE, 251 CPU_CLASS_XSCALE,
252 CPU_CLASS_ARM11J, 252 CPU_CLASS_ARM11J,
253 CPU_CLASS_ARMV4, 253 CPU_CLASS_ARMV4,
254 CPU_CLASS_CORTEX, 254 CPU_CLASS_CORTEX,
255 CPU_CLASS_PJ4B, 255 CPU_CLASS_PJ4B,
256}; 256};
257 257
258static const char * const generic_steppings[16] = { 258static const char * const generic_steppings[16] = {
259 "rev 0", "rev 1", "rev 2", "rev 3", 259 "rev 0", "rev 1", "rev 2", "rev 3",
260 "rev 4", "rev 5", "rev 6", "rev 7", 260 "rev 4", "rev 5", "rev 6", "rev 7",
261 "rev 8", "rev 9", "rev 10", "rev 11", 261 "rev 8", "rev 9", "rev 10", "rev 11",
262 "rev 12", "rev 13", "rev 14", "rev 15", 262 "rev 12", "rev 13", "rev 14", "rev 15",
263}; 263};
264 264
265static const char * const pN_steppings[16] = { 265static const char * const pN_steppings[16] = {
266 "*p0", "*p1", "*p2", "*p3", "*p4", "*p5", "*p6", "*p7", 266 "*p0", "*p1", "*p2", "*p3", "*p4", "*p5", "*p6", "*p7",
267 "*p8", "*p9", "*p10", "*p11", "*p12", "*p13", "*p14", "*p15", 267 "*p8", "*p9", "*p10", "*p11", "*p12", "*p13", "*p14", "*p15",
268}; 268};
269 269
270static const char * const sa110_steppings[16] = { 270static const char * const sa110_steppings[16] = {
271 "rev 0", "step J", "step K", "step S", 271 "rev 0", "step J", "step K", "step S",
272 "step T", "rev 5", "rev 6", "rev 7", 272 "step T", "rev 5", "rev 6", "rev 7",
273 "rev 8", "rev 9", "rev 10", "rev 11", 273 "rev 8", "rev 9", "rev 10", "rev 11",
274 "rev 12", "rev 13", "rev 14", "rev 15", 274 "rev 12", "rev 13", "rev 14", "rev 15",
275}; 275};
276 276
277static const char * const sa1100_steppings[16] = { 277static const char * const sa1100_steppings[16] = {
278 "rev 0", "step B", "step C", "rev 3", 278 "rev 0", "step B", "step C", "rev 3",
279 "rev 4", "rev 5", "rev 6", "rev 7", 279 "rev 4", "rev 5", "rev 6", "rev 7",
280 "step D", "step E", "rev 10" "step G", 280 "step D", "step E", "rev 10" "step G",
281 "rev 12", "rev 13", "rev 14", "rev 15", 281 "rev 12", "rev 13", "rev 14", "rev 15",
282}; 282};
283 283
284static const char * const sa1110_steppings[16] = { 284static const char * const sa1110_steppings[16] = {
285 "step A-0", "rev 1", "rev 2", "rev 3", 285 "step A-0", "rev 1", "rev 2", "rev 3",
286 "step B-0", "step B-1", "step B-2", "step B-3", 286 "step B-0", "step B-1", "step B-2", "step B-3",
287 "step B-4", "step B-5", "rev 10", "rev 11", 287 "step B-4", "step B-5", "rev 10", "rev 11",
288 "rev 12", "rev 13", "rev 14", "rev 15", 288 "rev 12", "rev 13", "rev 14", "rev 15",
289}; 289};
290 290
291static const char * const ixp12x0_steppings[16] = { 291static const char * const ixp12x0_steppings[16] = {
292 "(IXP1200 step A)", "(IXP1200 step B)", 292 "(IXP1200 step A)", "(IXP1200 step B)",
293 "rev 2", "(IXP1200 step C)", 293 "rev 2", "(IXP1200 step C)",
294 "(IXP1200 step D)", "(IXP1240/1250 step A)", 294 "(IXP1200 step D)", "(IXP1240/1250 step A)",
295 "(IXP1240 step B)", "(IXP1250 step B)", 295 "(IXP1240 step B)", "(IXP1250 step B)",
296 "rev 8", "rev 9", "rev 10", "rev 11", 296 "rev 8", "rev 9", "rev 10", "rev 11",
297 "rev 12", "rev 13", "rev 14", "rev 15", 297 "rev 12", "rev 13", "rev 14", "rev 15",
298}; 298};
299 299
300static const char * const xscale_steppings[16] = { 300static const char * const xscale_steppings[16] = {
301 "step A-0", "step A-1", "step B-0", "step C-0", 301 "step A-0", "step A-1", "step B-0", "step C-0",
302 "step D-0", "rev 5", "rev 6", "rev 7", 302 "step D-0", "rev 5", "rev 6", "rev 7",
303 "rev 8", "rev 9", "rev 10", "rev 11", 303 "rev 8", "rev 9", "rev 10", "rev 11",
304 "rev 12", "rev 13", "rev 14", "rev 15", 304 "rev 12", "rev 13", "rev 14", "rev 15",
305}; 305};
306 306
307static const char * const i80321_steppings[16] = { 307static const char * const i80321_steppings[16] = {
308 "step A-0", "step B-0", "rev 2", "rev 3", 308 "step A-0", "step B-0", "rev 2", "rev 3",
309 "rev 4", "rev 5", "rev 6", "rev 7", 309 "rev 4", "rev 5", "rev 6", "rev 7",
310 "rev 8", "rev 9", "rev 10", "rev 11", 310 "rev 8", "rev 9", "rev 10", "rev 11",
311 "rev 12", "rev 13", "rev 14", "rev 15", 311 "rev 12", "rev 13", "rev 14", "rev 15",
312}; 312};
313 313
314static const char * const i80219_steppings[16] = { 314static const char * const i80219_steppings[16] = {
315 "step A-0", "rev 1", "rev 2", "rev 3", 315 "step A-0", "rev 1", "rev 2", "rev 3",
316 "rev 4", "rev 5", "rev 6", "rev 7", 316 "rev 4", "rev 5", "rev 6", "rev 7",
317 "rev 8", "rev 9", "rev 10", "rev 11", 317 "rev 8", "rev 9", "rev 10", "rev 11",
318 "rev 12", "rev 13", "rev 14", "rev 15", 318 "rev 12", "rev 13", "rev 14", "rev 15",
319}; 319};
320 320
321/* Steppings for PXA2[15]0 */ 321/* Steppings for PXA2[15]0 */
322static const char * const pxa2x0_steppings[16] = { 322static const char * const pxa2x0_steppings[16] = {
323 "step A-0", "step A-1", "step B-0", "step B-1", 323 "step A-0", "step A-1", "step B-0", "step B-1",
324 "step B-2", "step C-0", "rev 6", "rev 7", 324 "step B-2", "step C-0", "rev 6", "rev 7",
325 "rev 8", "rev 9", "rev 10", "rev 11", 325 "rev 8", "rev 9", "rev 10", "rev 11",
326 "rev 12", "rev 13", "rev 14", "rev 15", 326 "rev 12", "rev 13", "rev 14", "rev 15",
327}; 327};
328 328
329/* Steppings for PXA255/26x. 329/* Steppings for PXA255/26x.
330 * rev 5: PXA26x B0, rev 6: PXA255 A0 330 * rev 5: PXA26x B0, rev 6: PXA255 A0
331 */ 331 */
332static const char * const pxa255_steppings[16] = { 332static const char * const pxa255_steppings[16] = {
333 "rev 0", "rev 1", "rev 2", "step A-0", 333 "rev 0", "rev 1", "rev 2", "step A-0",
334 "rev 4", "step B-0", "step A-0", "rev 7", 334 "rev 4", "step B-0", "step A-0", "rev 7",
335 "rev 8", "rev 9", "rev 10", "rev 11", 335 "rev 8", "rev 9", "rev 10", "rev 11",
336 "rev 12", "rev 13", "rev 14", "rev 15", 336 "rev 12", "rev 13", "rev 14", "rev 15",
337}; 337};
338 338
339/* Stepping for PXA27x */ 339/* Stepping for PXA27x */
340static const char * const pxa27x_steppings[16] = { 340static const char * const pxa27x_steppings[16] = {
341 "step A-0", "step A-1", "step B-0", "step B-1", 341 "step A-0", "step A-1", "step B-0", "step B-1",
342 "step C-0", "rev 5", "rev 6", "rev 7", 342 "step C-0", "rev 5", "rev 6", "rev 7",
343 "rev 8", "rev 9", "rev 10", "rev 11", 343 "rev 8", "rev 9", "rev 10", "rev 11",
344 "rev 12", "rev 13", "rev 14", "rev 15", 344 "rev 12", "rev 13", "rev 14", "rev 15",
345}; 345};
346 346
347static const char * const ixp425_steppings[16] = { 347static const char * const ixp425_steppings[16] = {
348 "step 0", "rev 1", "rev 2", "rev 3", 348 "step 0", "rev 1", "rev 2", "rev 3",
349 "rev 4", "rev 5", "rev 6", "rev 7", 349 "rev 4", "rev 5", "rev 6", "rev 7",
350 "rev 8", "rev 9", "rev 10", "rev 11", 350 "rev 8", "rev 9", "rev 10", "rev 11",
351 "rev 12", "rev 13", "rev 14", "rev 15", 351 "rev 12", "rev 13", "rev 14", "rev 15",
352}; 352};
353 353
354struct cpuidtab { 354struct cpuidtab {
355 uint32_t cpuid; 355 uint32_t cpuid;
356 enum cpu_class cpu_class; 356 enum cpu_class cpu_class;
357 const char *cpu_classname; 357 const char *cpu_classname;
358 const char * const *cpu_steppings; 358 const char * const *cpu_steppings;
359 char cpu_arch[8]; 359 char cpu_arch[8];
360}; 360};
361 361
362const struct cpuidtab cpuids[] = { 362const struct cpuidtab cpuids[] = {
363 { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2", 363 { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2",
364 generic_steppings, "2" }, 364 generic_steppings, "2" },
365 { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250", 365 { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250",
366 generic_steppings, "2" }, 366 generic_steppings, "2" },
367 367
368 { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3", 368 { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3",
369 generic_steppings, "2A" }, 369 generic_steppings, "2A" },
370 370
371 { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600", 371 { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600",
372 generic_steppings, "3" }, 372 generic_steppings, "3" },
373 { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610", 373 { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610",
374 generic_steppings, "3" }, 374 generic_steppings, "3" },
375 { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620", 375 { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620",
376 generic_steppings, "3" }, 376 generic_steppings, "3" },
377 377
378 { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700", 378 { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700",
379 generic_steppings, "3" }, 379 generic_steppings, "3" },
380 { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710", 380 { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710",
381 generic_steppings, "3" }, 381 generic_steppings, "3" },
382 { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500", 382 { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500",
383 generic_steppings, "3" }, 383 generic_steppings, "3" },
384 { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a", 384 { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a",
385 generic_steppings, "3" }, 385 generic_steppings, "3" },
386 { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE", 386 { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE",
387 generic_steppings, "3" }, 387 generic_steppings, "3" },
388 388
389 { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810", 389 { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810",
390 generic_steppings, "4" }, 390 generic_steppings, "4" },
391 391
392 { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", 392 { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110",
393 sa110_steppings, "4" }, 393 sa110_steppings, "4" },
394 { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", 394 { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100",
395 sa1100_steppings, "4" }, 395 sa1100_steppings, "4" },
396 { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", 396 { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110",
397 sa1110_steppings, "4" }, 397 sa1110_steppings, "4" },
398 398
399 { CPU_ID_FA526, CPU_CLASS_ARMV4, "FA526", 399 { CPU_ID_FA526, CPU_CLASS_ARMV4, "FA526",
400 generic_steppings, "4" }, 400 generic_steppings, "4" },
401 401
402 { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", 402 { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200",
403 ixp12x0_steppings, "4" }, 403 ixp12x0_steppings, "4" },
404 404
405 { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T", 405 { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T",
406 generic_steppings, "4T" }, 406 generic_steppings, "4T" },
407 { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T", 407 { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T",
408 generic_steppings, "4T" }, 408 generic_steppings, "4T" },
409 { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)", 409 { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
410 generic_steppings, "4T" }, 410 generic_steppings, "4T" },
411 { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)", 411 { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
412 generic_steppings, "4T" }, 412 generic_steppings, "4T" },
413 { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", 413 { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T",
414 generic_steppings, "4T" }, 414 generic_steppings, "4T" },
415 { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", 415 { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T",
416 generic_steppings, "4T" }, 416 generic_steppings, "4T" },
417 { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", 417 { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T",
418 generic_steppings, "4T" }, 418 generic_steppings, "4T" },
419 { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", 419 { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T",
420 generic_steppings, "4T" }, 420 generic_steppings, "4T" },
421 421
422 { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", 422 { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S",
423 generic_steppings, "5TE" }, 423 generic_steppings, "5TE" },
424 { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", 424 { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S",
425 generic_steppings, "5TE" }, 425 generic_steppings, "5TE" },
426 { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", 426 { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S",
427 generic_steppings, "5TE" }, 427 generic_steppings, "5TE" },
428 { CPU_ID_MV88SV131, CPU_CLASS_ARM9ES, "Sheeva 88SV131", 428 { CPU_ID_MV88SV131, CPU_CLASS_ARM9ES, "Sheeva 88SV131",
429 generic_steppings, "5TE" }, 429 generic_steppings, "5TE" },
430 { CPU_ID_MV88FR571_VD, CPU_CLASS_ARM9ES, "Sheeva 88FR571-vd", 430 { CPU_ID_MV88FR571_VD, CPU_CLASS_ARM9ES, "Sheeva 88FR571-vd",
431 generic_steppings, "5TE" }, 431 generic_steppings, "5TE" },
432 432
433 { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", 433 { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200",
434 xscale_steppings, "5TE" }, 434 xscale_steppings, "5TE" },
435 435
436 { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", 436 { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz",
437 i80321_steppings, "5TE" }, 437 i80321_steppings, "5TE" },
438 { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", 438 { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz",
439 i80321_steppings, "5TE" }, 439 i80321_steppings, "5TE" },
440 { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", 440 { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz",
441 i80321_steppings, "5TE" }, 441 i80321_steppings, "5TE" },
442 { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", 442 { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz",
443 i80321_steppings, "5TE" }, 443 i80321_steppings, "5TE" },
444 444
445 { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz", 445 { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz",
446 i80219_steppings, "5TE" }, 446 i80219_steppings, "5TE" },
447 { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz", 447 { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz",
448 i80219_steppings, "5TE" }, 448 i80219_steppings, "5TE" },
449 449
450 { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x", 450 { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x",
451 pxa27x_steppings, "5TE" }, 451 pxa27x_steppings, "5TE" },
452 { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", 452 { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250",
453 pxa2x0_steppings, "5TE" }, 453 pxa2x0_steppings, "5TE" },
454 { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", 454 { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210",
455 pxa2x0_steppings, "5TE" }, 455 pxa2x0_steppings, "5TE" },
456 { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", 456 { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250",
457 pxa2x0_steppings, "5TE" }, 457 pxa2x0_steppings, "5TE" },
458 { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", 458 { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210",
459 pxa2x0_steppings, "5TE" }, 459 pxa2x0_steppings, "5TE" },
460 { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255/26x", 460 { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255/26x",
461 pxa255_steppings, "5TE" }, 461 pxa255_steppings, "5TE" },
462 { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", 462 { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210",
463 pxa2x0_steppings, "5TE" }, 463 pxa2x0_steppings, "5TE" },
464 464
465 { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", 465 { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz",
466 ixp425_steppings, "5TE" }, 466 ixp425_steppings, "5TE" },
467 { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", 467 { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz",
468 ixp425_steppings, "5TE" }, 468 ixp425_steppings, "5TE" },
469 { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", 469 { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz",
470 ixp425_steppings, "5TE" }, 470 ixp425_steppings, "5TE" },
471 471
472 { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", 472 { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E",
473 generic_steppings, "5TE" }, 473 generic_steppings, "5TE" },
474 { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", 474 { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S",
475 generic_steppings, "5TE" }, 475 generic_steppings, "5TE" },
476 476
477 { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S", 477 { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S",
478 generic_steppings, "5TEJ" }, 478 generic_steppings, "5TEJ" },
479 { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S r0", 479 { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S r0",
480 pN_steppings, "5TEJ" }, 480 pN_steppings, "5TEJ" },
481 481
482 { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S r0", 482 { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S r0",
483 pN_steppings, "6J" }, 483 pN_steppings, "6J" },
484 { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S r1", 484 { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S r1",
485 pN_steppings, "6J" }, 485 pN_steppings, "6J" },
486#if 0 486#if 0
487 /* The ARM1156T2-S only has a memory protection unit */ 487 /* The ARM1156T2-S only has a memory protection unit */
488 { CPU_ID_ARM1156T2S, CPU_CLASS_ARM11J, "ARM1156T2-S r0", 488 { CPU_ID_ARM1156T2S, CPU_CLASS_ARM11J, "ARM1156T2-S r0",
489 pN_steppings, "6T2" }, 489 pN_steppings, "6T2" },
490#endif 490#endif
491 { CPU_ID_ARM1176JZS, CPU_CLASS_ARM11J, "ARM1176JZ-S r0", 491 { CPU_ID_ARM1176JZS, CPU_CLASS_ARM11J, "ARM1176JZ-S r0",
492 pN_steppings, "6ZK" }, 492 pN_steppings, "6ZK" },
493 493
494 { CPU_ID_ARM11MPCORE, CPU_CLASS_ARM11J, "ARM11 MPCore", 494 { CPU_ID_ARM11MPCORE, CPU_CLASS_ARM11J, "ARM11 MPCore",
495 generic_steppings, "6K" }, 495 generic_steppings, "6K" },
496 496
497 { CPU_ID_CORTEXA5R0, CPU_CLASS_CORTEX, "Cortex-A5 r0", 497 { CPU_ID_CORTEXA5R0, CPU_CLASS_CORTEX, "Cortex-A5 r0",
498 pN_steppings, "7A" }, 498 pN_steppings, "7A" },
499 { CPU_ID_CORTEXA7R0, CPU_CLASS_CORTEX, "Cortex-A7 r0", 499 { CPU_ID_CORTEXA7R0, CPU_CLASS_CORTEX, "Cortex-A7 r0",
500 pN_steppings, "7A" }, 500 pN_steppings, "7A" },
501 { CPU_ID_CORTEXA8R1, CPU_CLASS_CORTEX, "Cortex-A8 r1", 501 { CPU_ID_CORTEXA8R1, CPU_CLASS_CORTEX, "Cortex-A8 r1",
502 pN_steppings, "7A" }, 502 pN_steppings, "7A" },
503 { CPU_ID_CORTEXA8R2, CPU_CLASS_CORTEX, "Cortex-A8 r2", 503 { CPU_ID_CORTEXA8R2, CPU_CLASS_CORTEX, "Cortex-A8 r2",
504 pN_steppings, "7A" }, 504 pN_steppings, "7A" },
505 { CPU_ID_CORTEXA8R3, CPU_CLASS_CORTEX, "Cortex-A8 r3", 505 { CPU_ID_CORTEXA8R3, CPU_CLASS_CORTEX, "Cortex-A8 r3",
506 pN_steppings, "7A" }, 506 pN_steppings, "7A" },
507 { CPU_ID_CORTEXA9R1, CPU_CLASS_CORTEX, "Cortex-A9 r1", 507 { CPU_ID_CORTEXA9R1, CPU_CLASS_CORTEX, "Cortex-A9 r1",
508 pN_steppings, "7A" }, 508 pN_steppings, "7A" },
509 { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEX, "Cortex-A9 r2", 509 { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEX, "Cortex-A9 r2",
510 pN_steppings, "7A" }, 510 pN_steppings, "7A" },
511 { CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEX, "Cortex-A9 r3", 511 { CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEX, "Cortex-A9 r3",
512 pN_steppings, "7A" }, 512 pN_steppings, "7A" },
513 { CPU_ID_CORTEXA9R4, CPU_CLASS_CORTEX, "Cortex-A9 r4", 513 { CPU_ID_CORTEXA9R4, CPU_CLASS_CORTEX, "Cortex-A9 r4",
514 pN_steppings, "7A" }, 514 pN_steppings, "7A" },
515 { CPU_ID_CORTEXA12R0, CPU_CLASS_CORTEX, "Cortex-A17(A12) r0", /* A12 was rebranded A17 */ 515 { CPU_ID_CORTEXA12R0, CPU_CLASS_CORTEX, "Cortex-A17(A12) r0", /* A12 was rebranded A17 */
516 pN_steppings, "7A" }, 516 pN_steppings, "7A" },
517 { CPU_ID_CORTEXA15R2, CPU_CLASS_CORTEX, "Cortex-A15 r2", 517 { CPU_ID_CORTEXA15R2, CPU_CLASS_CORTEX, "Cortex-A15 r2",
518 pN_steppings, "7A" }, 518 pN_steppings, "7A" },
519 { CPU_ID_CORTEXA15R3, CPU_CLASS_CORTEX, "Cortex-A15 r3", 519 { CPU_ID_CORTEXA15R3, CPU_CLASS_CORTEX, "Cortex-A15 r3",
520 pN_steppings, "7A" }, 520 pN_steppings, "7A" },
521 { CPU_ID_CORTEXA15R4, CPU_CLASS_CORTEX, "Cortex-A15 r4", 521 { CPU_ID_CORTEXA15R4, CPU_CLASS_CORTEX, "Cortex-A15 r4",
522 pN_steppings, "7A" }, 522 pN_steppings, "7A" },
523 { CPU_ID_CORTEXA17R1, CPU_CLASS_CORTEX, "Cortex-A17 r1", 523 { CPU_ID_CORTEXA17R1, CPU_CLASS_CORTEX, "Cortex-A17 r1",
524 pN_steppings, "7A" }, 524 pN_steppings, "7A" },
525 { CPU_ID_CORTEXA35R0, CPU_CLASS_CORTEX, "Cortex-A35 r0", 525 { CPU_ID_CORTEXA35R0, CPU_CLASS_CORTEX, "Cortex-A35 r0",
526 pN_steppings, "8A" }, 526 pN_steppings, "8A" },
527 { CPU_ID_CORTEXA53R0, CPU_CLASS_CORTEX, "Cortex-A53 r0", 527 { CPU_ID_CORTEXA53R0, CPU_CLASS_CORTEX, "Cortex-A53 r0",
528 pN_steppings, "8A" }, 528 pN_steppings, "8A" },
529 { CPU_ID_CORTEXA57R0, CPU_CLASS_CORTEX, "Cortex-A57 r0", 529 { CPU_ID_CORTEXA57R0, CPU_CLASS_CORTEX, "Cortex-A57 r0",
530 pN_steppings, "8A" }, 530 pN_steppings, "8A" },
531 { CPU_ID_CORTEXA57R1, CPU_CLASS_CORTEX, "Cortex-A57 r1", 531 { CPU_ID_CORTEXA57R1, CPU_CLASS_CORTEX, "Cortex-A57 r1",
532 pN_steppings, "8A" }, 532 pN_steppings, "8A" },
533 { CPU_ID_CORTEXA72R0, CPU_CLASS_CORTEX, "Cortex-A72 r0", 533 { CPU_ID_CORTEXA72R0, CPU_CLASS_CORTEX, "Cortex-A72 r0",
534 pN_steppings, "8A" }, 534 pN_steppings, "8A" },
535 535
536 { CPU_ID_MV88SV581X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV581x", 536 { CPU_ID_MV88SV581X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV581x",
537 generic_steppings }, 537 generic_steppings },
538 { CPU_ID_ARM_88SV581X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV581x", 538 { CPU_ID_ARM_88SV581X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV581x",
539 generic_steppings }, 539 generic_steppings },
540 { CPU_ID_MV88SV581X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV581x", 540 { CPU_ID_MV88SV581X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV581x",
541 generic_steppings }, 541 generic_steppings },
542 { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV581x", 542 { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV581x",
543 generic_steppings }, 543 generic_steppings },
544 { CPU_ID_MV88SV584X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV584x", 544 { CPU_ID_MV88SV584X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV584x",
545 generic_steppings }, 545 generic_steppings },
546 { CPU_ID_ARM_88SV584X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV584x", 546 { CPU_ID_ARM_88SV584X_V6, CPU_CLASS_PJ4B, "Sheeva 88SV584x",
547 generic_steppings }, 547 generic_steppings },
548 { CPU_ID_MV88SV584X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV584x", 548 { CPU_ID_MV88SV584X_V7, CPU_CLASS_PJ4B, "Sheeva 88SV584x",
549 generic_steppings }, 549 generic_steppings },
550 550
551 551
552 { 0, CPU_CLASS_NONE, NULL, NULL, "" } 552 { 0, CPU_CLASS_NONE, NULL, NULL, "" }
553}; 553};
554 554
555struct cpu_classtab { 555struct cpu_classtab {
556 const char *class_name; 556 const char *class_name;
557 const char *class_option; 557 const char *class_option;
558}; 558};
559 559
560const struct cpu_classtab cpu_classes[] = { 560const struct cpu_classtab cpu_classes[] = {
561 [CPU_CLASS_NONE] = { "unknown", NULL }, 561 [CPU_CLASS_NONE] = { "unknown", NULL },
562 [CPU_CLASS_ARM2] = { "ARM2", "CPU_ARM2" }, 562 [CPU_CLASS_ARM2] = { "ARM2", "CPU_ARM2" },
563 [CPU_CLASS_ARM2AS] = { "ARM2as", "CPU_ARM250" }, 563 [CPU_CLASS_ARM2AS] = { "ARM2as", "CPU_ARM250" },
564 [CPU_CLASS_ARM3] = { "ARM3", "CPU_ARM3" }, 564 [CPU_CLASS_ARM3] = { "ARM3", "CPU_ARM3" },
565 [CPU_CLASS_ARM6] = { "ARM6", "CPU_ARM6" }, 565 [CPU_CLASS_ARM6] = { "ARM6", "CPU_ARM6" },
566 [CPU_CLASS_ARM7] = { "ARM7", "CPU_ARM7" }, 566 [CPU_CLASS_ARM7] = { "ARM7", "CPU_ARM7" },
567 [CPU_CLASS_ARM7TDMI] = { "ARM7TDMI", "CPU_ARM7TDMI" }, 567 [CPU_CLASS_ARM7TDMI] = { "ARM7TDMI", "CPU_ARM7TDMI" },
568 [CPU_CLASS_ARM8] = { "ARM8", "CPU_ARM8" }, 568 [CPU_CLASS_ARM8] = { "ARM8", "CPU_ARM8" },
569 [CPU_CLASS_ARM9TDMI] = { "ARM9TDMI", NULL }, 569 [CPU_CLASS_ARM9TDMI] = { "ARM9TDMI", NULL },
570 [CPU_CLASS_ARM9ES] = { "ARM9E-S", "CPU_ARM9E" }, 570 [CPU_CLASS_ARM9ES] = { "ARM9E-S", "CPU_ARM9E" },
571 [CPU_CLASS_ARM9EJS] = { "ARM9EJ-S", "CPU_ARM9E" }, 571 [CPU_CLASS_ARM9EJS] = { "ARM9EJ-S", "CPU_ARM9E" },
572 [CPU_CLASS_ARM10E] = { "ARM10E", "CPU_ARM10" }, 572 [CPU_CLASS_ARM10E] = { "ARM10E", "CPU_ARM10" },
573 [CPU_CLASS_ARM10EJ] = { "ARM10EJ", "CPU_ARM10" }, 573 [CPU_CLASS_ARM10EJ] = { "ARM10EJ", "CPU_ARM10" },
574 [CPU_CLASS_SA1] = { "SA-1", "CPU_SA110" }, 574 [CPU_CLASS_SA1] = { "SA-1", "CPU_SA110" },
575 [CPU_CLASS_XSCALE] = { "XScale", "CPU_XSCALE_..." }, 575 [CPU_CLASS_XSCALE] = { "XScale", "CPU_XSCALE_..." },
576 [CPU_CLASS_ARM11J] = { "ARM11J", "CPU_ARM11" }, 576 [CPU_CLASS_ARM11J] = { "ARM11J", "CPU_ARM11" },
577 [CPU_CLASS_ARMV4] = { "ARMv4", "CPU_ARMV4" }, 577 [CPU_CLASS_ARMV4] = { "ARMv4", "CPU_ARMV4" },
578 [CPU_CLASS_CORTEX] = { "Cortex", "CPU_CORTEX" }, 578 [CPU_CLASS_CORTEX] = { "Cortex", "CPU_CORTEX" },
579 [CPU_CLASS_PJ4B] = { "Marvell", "CPU_PJ4B" }, 579 [CPU_CLASS_PJ4B] = { "Marvell", "CPU_PJ4B" },
580}; 580};
581 581
582/* 582/*
583 * Report the type of the specified arm processor. This uses the generic and 583 * Report the type of the specified arm processor. This uses the generic and
584 * arm specific information in the CPU structure to identify the processor. 584 * arm specific information in the CPU structure to identify the processor.
585 * The remaining fields in the CPU structure are filled in appropriately. 585 * The remaining fields in the CPU structure are filled in appropriately.
586 */ 586 */
587 587
588static const char * const wtnames[] = { 588static const char * const wtnames[] = {
589 "write-through", 589 "write-through",
590 "write-back", 590 "write-back",
591 "write-back", 591 "write-back",
592 "**unknown 3**", 592 "**unknown 3**",
593 "**unknown 4**", 593 "**unknown 4**",
594 "write-back-locking", /* XXX XScale-specific? */ 594 "write-back-locking", /* XXX XScale-specific? */
595 "write-back-locking-A", 595 "write-back-locking-A",
596 "write-back-locking-B", 596 "write-back-locking-B",
597 "**unknown 8**", 597 "**unknown 8**",
598 "**unknown 9**", 598 "**unknown 9**",
599 "**unknown 10**", 599 "**unknown 10**",
600 "**unknown 11**", 600 "**unknown 11**",
601 "write-back", 601 "write-back",
602 "write-back-locking-line", 602 "write-back-locking-line",
603 "write-back-locking-C", 603 "write-back-locking-C",
604 "write-back-locking-D", 604 "write-back-locking-D",
605}; 605};
606 606
607static void 607static void
608print_cache_info(device_t dv, struct arm_cache_info *info, u_int level) 608print_cache_info(device_t dv, struct arm_cache_info *info, u_int level)
609{ 609{
610 if (info->cache_unified) { 610 if (info->cache_unified) {
611 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %s %cI%cT Unified cache\n", 611 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %s %cI%cT Unified cache\n",
612 level + 1, 612 level + 1,
613 info->dcache_size / 1024, 613 info->dcache_size / 1024,
614 info->dcache_line_size, info->dcache_ways, 614 info->dcache_line_size, info->dcache_ways,
615 info->dcache_sets ? info->dcache_sets : 615 info->dcache_sets ? info->dcache_sets :
616 info->dcache_size / 616 info->dcache_size /
617 (info->dcache_line_size * info->dcache_ways), 617 (info->dcache_line_size * info->dcache_ways),
618 wtnames[info->cache_type], 618 wtnames[info->cache_type],
619 info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V', 619 info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V',
620 info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); 620 info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V');
621 } else { 621 } else {
622 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %cI%cT Instruction cache\n", 622 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %cI%cT Instruction cache\n",
623 level + 1, 623 level + 1,
624 info->icache_size / 1024, 624 info->icache_size / 1024,
625 info->icache_line_size, info->icache_ways, 625 info->icache_line_size, info->icache_ways,
626 info->icache_sets ? info->icache_sets : 626 info->icache_sets ? info->icache_sets :
627 info->icache_size / 627 info->icache_size /
628 (info->icache_line_size * info->icache_ways), 628 (info->icache_line_size * info->icache_ways),
629 info->icache_type & CACHE_TYPE_PIxx ? 'P' : 'V', 629 info->icache_type & CACHE_TYPE_PIxx ? 'P' : 'V',
630 info->icache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); 630 info->icache_type & CACHE_TYPE_xxPT ? 'P' : 'V');
631 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %s %cI%cT Data cache\n", 631 aprint_normal_dev(dv, "L%u %dKB/%dB %d-way (%u set) %s %cI%cT Data cache\n",
632 level + 1, 632 level + 1,
633 info->dcache_size / 1024, 633 info->dcache_size / 1024,
634 info->dcache_line_size, info->dcache_ways, 634 info->dcache_line_size, info->dcache_ways,
635 info->dcache_sets ? info->dcache_sets : 635 info->dcache_sets ? info->dcache_sets :
636 info->dcache_size / 636 info->dcache_size /
637 (info->dcache_line_size * info->dcache_ways), 637 (info->dcache_line_size * info->dcache_ways),
638 wtnames[info->cache_type], 638 wtnames[info->cache_type],
639 info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V', 639 info->dcache_type & CACHE_TYPE_PIxx ? 'P' : 'V',
640 info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V'); 640 info->dcache_type & CACHE_TYPE_xxPT ? 'P' : 'V');
641 } 641 }
642} 642}
643 643
644static enum cpu_class 644static enum cpu_class
645identify_arm_model(uint32_t cpuid, char *buf, size_t len) 645identify_arm_model(uint32_t cpuid, char *buf, size_t len)
646{ 646{
647 enum cpu_class cpu_class = CPU_CLASS_NONE; 647 enum cpu_class cpu_class = CPU_CLASS_NONE;
648 for (const struct cpuidtab *id = cpuids; id->cpuid != 0; id++) { 648 for (const struct cpuidtab *id = cpuids; id->cpuid != 0; id++) {
649 if (id->cpuid == (cpuid & CPU_ID_CPU_MASK)) { 649 if (id->cpuid == (cpuid & CPU_ID_CPU_MASK)) {
650 const char *steppingstr = 650 const char *steppingstr =
651 id->cpu_steppings[cpuid & CPU_ID_REVISION_MASK]; 651 id->cpu_steppings[cpuid & CPU_ID_REVISION_MASK];
652 cpu_arch = id->cpu_arch; 652 cpu_arch = id->cpu_arch;
653 cpu_class = id->cpu_class; 653 cpu_class = id->cpu_class;
654 snprintf(buf, len, "%s%s%s (%s V%s core)", 654 snprintf(buf, len, "%s%s%s (%s V%s core)",
655 id->cpu_classname, 655 id->cpu_classname,
656 steppingstr[0] == '*' ? "" : " ", 656 steppingstr[0] == '*' ? "" : " ",
657 &steppingstr[steppingstr[0] == '*'], 657 &steppingstr[steppingstr[0] == '*'],
658 cpu_classes[cpu_class].class_name, 658 cpu_classes[cpu_class].class_name,
659 cpu_arch); 659 cpu_arch);
660 return cpu_class; 660 return cpu_class;
661 } 661 }
662 } 662 }
663 663
664 snprintf(buf, len, "unknown CPU (ID = 0x%x)", cpuid); 664 snprintf(buf, len, "unknown CPU (ID = 0x%x)", cpuid);
665 return cpu_class; 665 return cpu_class;
666} 666}
667 667
668void 668void
669identify_arm_cpu(device_t dv, struct cpu_info *ci) 669identify_arm_cpu(device_t dv, struct cpu_info *ci)
670{ 670{
671 const uint32_t arm_cpuid = ci->ci_arm_cpuid; 671 const uint32_t arm_cpuid = ci->ci_arm_cpuid;
672 const char * const xname = device_xname(dv); 672 const char * const xname = device_xname(dv);
673 char model[128]; 673 char model[128];
674 const char *m; 674 const char *m;
675 675
676 if (arm_cpuid == 0) { 676 if (arm_cpuid == 0) {
677 aprint_error("Processor failed probe - no CPU ID\n"); 677 aprint_error("Processor failed probe - no CPU ID\n");
678 return; 678 return;
679 } 679 }
680 680
681 const enum cpu_class cpu_class = identify_arm_model(arm_cpuid, 681 const enum cpu_class cpu_class = identify_arm_model(arm_cpuid,
682 model, sizeof(model)); 682 model, sizeof(model));
683 if (ci->ci_cpuid == 0) { 683 if (ci->ci_cpuid == 0) {
684 m = cpu_getmodel(); 684 m = cpu_getmodel();
685 if (m == NULL || *m == 0) 685 if (m == NULL || *m == 0)
686 cpu_setmodel("%s", model); 686 cpu_setmodel("%s", model);
687 } 687 }
688 688
689 if (ci->ci_data.cpu_cc_freq != 0) { 689 if (ci->ci_data.cpu_cc_freq != 0) {
690 char freqbuf[10]; 690 char freqbuf[10];
691 humanize_number(freqbuf, sizeof(freqbuf), ci->ci_data.cpu_cc_freq, 691 humanize_number(freqbuf, sizeof(freqbuf), ci->ci_data.cpu_cc_freq,
692 "Hz", 1000); 692 "Hz", 1000);
693 693
694 aprint_naive(": %s %s\n", freqbuf, model); 694 aprint_naive(": %s %s\n", freqbuf, model);
695 aprint_normal(": %s %s\n", freqbuf, model); 695 aprint_normal(": %s %s\n", freqbuf, model);
696 } else { 696 } else {
697 aprint_naive(": %s\n", model); 697 aprint_naive(": %s\n", model);
698 aprint_normal(": %s\n", model); 698 aprint_normal(": %s\n", model);
699 } 699 }
700 700
701 aprint_debug_dev(dv, "midr: %#x\n", arm_cpuid); 701 aprint_debug_dev(dv, "midr: %#x\n", arm_cpuid);
702 702
703 aprint_normal("%s:", xname); 703 aprint_normal("%s:", xname);
704 704
705 switch (cpu_class) { 705 switch (cpu_class) {
706 case CPU_CLASS_ARM6: 706 case CPU_CLASS_ARM6:
707 case CPU_CLASS_ARM7: 707 case CPU_CLASS_ARM7:
708 case CPU_CLASS_ARM7TDMI: 708 case CPU_CLASS_ARM7TDMI:
709 case CPU_CLASS_ARM8: 709 case CPU_CLASS_ARM8:
710 if ((ci->ci_ctrl & CPU_CONTROL_IDC_ENABLE) == 0) 710 if ((ci->ci_ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
711 aprint_normal(" IDC disabled"); 711 aprint_normal(" IDC disabled");
712 else 712 else
713 aprint_normal(" IDC enabled"); 713 aprint_normal(" IDC enabled");
714 break; 714 break;
715 case CPU_CLASS_ARM9TDMI: 715 case CPU_CLASS_ARM9TDMI:
716 case CPU_CLASS_ARM9ES: 716 case CPU_CLASS_ARM9ES:
717 case CPU_CLASS_ARM9EJS: 717 case CPU_CLASS_ARM9EJS:
718 case CPU_CLASS_ARM10E: 718 case CPU_CLASS_ARM10E:
719 case CPU_CLASS_ARM10EJ: 719 case CPU_CLASS_ARM10EJ:
720 case CPU_CLASS_SA1: 720 case CPU_CLASS_SA1:
721 case CPU_CLASS_XSCALE: 721 case CPU_CLASS_XSCALE:
722 case CPU_CLASS_ARM11J: 722 case CPU_CLASS_ARM11J:
723 case CPU_CLASS_ARMV4: 723 case CPU_CLASS_ARMV4:
724 case CPU_CLASS_CORTEX: 724 case CPU_CLASS_CORTEX:
725 case CPU_CLASS_PJ4B: 725 case CPU_CLASS_PJ4B:
726 if ((ci->ci_ctrl & CPU_CONTROL_DC_ENABLE) == 0) 726 if ((ci->ci_ctrl & CPU_CONTROL_DC_ENABLE) == 0)
727 aprint_normal(" DC disabled"); 727 aprint_normal(" DC disabled");
728 else 728 else
729 aprint_normal(" DC enabled"); 729 aprint_normal(" DC enabled");
730 if ((ci->ci_ctrl & CPU_CONTROL_IC_ENABLE) == 0) 730 if ((ci->ci_ctrl & CPU_CONTROL_IC_ENABLE) == 0)
731 aprint_normal(" IC disabled"); 731 aprint_normal(" IC disabled");
732 else 732 else
733 aprint_normal(" IC enabled"); 733 aprint_normal(" IC enabled");
734 break; 734 break;
735 default: 735 default:
736 break; 736 break;
737 } 737 }
738 if ((ci->ci_ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) 738 if ((ci->ci_ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
739 aprint_normal(" WB disabled"); 739 aprint_normal(" WB disabled");
740 else 740 else
741 aprint_normal(" WB enabled"); 741 aprint_normal(" WB enabled");
742 742
743 if (ci->ci_ctrl & CPU_CONTROL_LABT_ENABLE) 743 if (ci->ci_ctrl & CPU_CONTROL_LABT_ENABLE)
744 aprint_normal(" LABT"); 744 aprint_normal(" LABT");
745 else 745 else
746 aprint_normal(" EABT"); 746 aprint_normal(" EABT");
747 747
748 if (ci->ci_ctrl & CPU_CONTROL_BPRD_ENABLE) 748 if (ci->ci_ctrl & CPU_CONTROL_BPRD_ENABLE)
749 aprint_normal(" branch prediction enabled"); 749 aprint_normal(" branch prediction enabled");
750 750
751 aprint_normal("\n"); 751 aprint_normal("\n");
752 752
753 if (CPU_ID_CORTEX_P(arm_cpuid) || 753 if (CPU_ID_CORTEX_P(arm_cpuid) ||
754 CPU_ID_ARM11_P(arm_cpuid) || 754 CPU_ID_ARM11_P(arm_cpuid) ||
755 CPU_ID_MV88SV58XX_P(arm_cpuid)) { 755 CPU_ID_MV88SV58XX_P(arm_cpuid)) {
756 if ((arm_cpuid & CPU_ID_CPU_MASK) != CPU_ID_ARM1136JS && 756 if ((arm_cpuid & CPU_ID_CPU_MASK) != CPU_ID_ARM1136JS &&
757 (arm_cpuid & CPU_ID_CPU_MASK) != CPU_ID_ARM1176JZS) { 757 (arm_cpuid & CPU_ID_CPU_MASK) != CPU_ID_ARM1176JZS) {
758 identify_features(dv, ci); 758 identify_features(dv, ci);
759 } 759 }
760 } 760 }
761 761
762 /* Print cache info. */ 762 /* Print cache info. */
763 if (arm_pcache.icache_line_size != 0 || arm_pcache.dcache_line_size != 0) { 763 if (arm_pcache.icache_line_size != 0 || arm_pcache.dcache_line_size != 0) {
764 print_cache_info(dv, &arm_pcache, 0); 764 print_cache_info(dv, &arm_pcache, 0);
765 } 765 }
766 if (arm_scache.icache_line_size != 0 || arm_scache.dcache_line_size != 0) { 766 if (arm_scache.icache_line_size != 0 || arm_scache.dcache_line_size != 0) {
767 print_cache_info(dv, &arm_scache, 1); 767 print_cache_info(dv, &arm_scache, 1);
768 } 768 }
769 769
770 770
771 switch (cpu_class) { 771 switch (cpu_class) {
772#ifdef CPU_ARM6 772#ifdef CPU_ARM6
773 case CPU_CLASS_ARM6: 773 case CPU_CLASS_ARM6:
774#endif 774#endif
775#ifdef CPU_ARM7 775#ifdef CPU_ARM7
776 case CPU_CLASS_ARM7: 776 case CPU_CLASS_ARM7:
777#endif 777#endif
778#ifdef CPU_ARM7TDMI 778#ifdef CPU_ARM7TDMI
779 case CPU_CLASS_ARM7TDMI: 779 case CPU_CLASS_ARM7TDMI:
780#endif 780#endif
781#ifdef CPU_ARM8 781#ifdef CPU_ARM8
782 case CPU_CLASS_ARM8: 782 case CPU_CLASS_ARM8:
783#endif 783#endif
784#ifdef CPU_ARM9 784#ifdef CPU_ARM9
785 case CPU_CLASS_ARM9TDMI: 785 case CPU_CLASS_ARM9TDMI:
786#endif 786#endif
787#if defined(CPU_ARM9E) || defined(CPU_SHEEVA) 787#if defined(CPU_ARM9E) || defined(CPU_SHEEVA)
788 case CPU_CLASS_ARM9ES: 788 case CPU_CLASS_ARM9ES:
789 case CPU_CLASS_ARM9EJS: 789 case CPU_CLASS_ARM9EJS:
790#endif 790#endif
791#ifdef CPU_ARM10 791#ifdef CPU_ARM10
792 case CPU_CLASS_ARM10E: 792 case CPU_CLASS_ARM10E:
793 case CPU_CLASS_ARM10EJ: 793 case CPU_CLASS_ARM10EJ:
794#endif 794#endif
795#if defined(CPU_SA110) || defined(CPU_SA1100) || \ 795#if defined(CPU_SA110) || defined(CPU_SA1100) || \
796 defined(CPU_SA1110) || defined(CPU_IXP12X0) 796 defined(CPU_SA1110) || defined(CPU_IXP12X0)
797 case CPU_CLASS_SA1: 797 case CPU_CLASS_SA1:
798#endif 798#endif
799#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 799#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
800 defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) 800 defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425)
801 case CPU_CLASS_XSCALE: 801 case CPU_CLASS_XSCALE:
802#endif 802#endif
803#if defined(CPU_ARM11) 803#if defined(CPU_ARM11)
804 case CPU_CLASS_ARM11J: 804 case CPU_CLASS_ARM11J:
805#endif 805#endif
806#if defined(CPU_CORTEX) 806#if defined(CPU_CORTEX)
807 case CPU_CLASS_CORTEX: 807 case CPU_CLASS_CORTEX:
808#endif 808#endif
809#if defined(CPU_PJ4B) 809#if defined(CPU_PJ4B)
810 case CPU_CLASS_PJ4B: 810 case CPU_CLASS_PJ4B:
811#endif 811#endif
812#if defined(CPU_FA526) 812#if defined(CPU_FA526)
813 case CPU_CLASS_ARMV4: 813 case CPU_CLASS_ARMV4:
814#endif 814#endif
815 break; 815 break;
816 default: 816 default:
817 if (cpu_classes[cpu_class].class_option == NULL) { 817 if (cpu_classes[cpu_class].class_option == NULL) {
818 aprint_error_dev(dv, "%s does not fully support this CPU.\n", 818 aprint_error_dev(dv, "%s does not fully support this CPU.\n",
819 ostype); 819 ostype);
820 } else { 820 } else {
821 aprint_error_dev(dv, "This kernel does not fully support " 821 aprint_error_dev(dv, "This kernel does not fully support "
822 "this CPU.\n"); 822 "this CPU.\n");
823 aprint_normal_dev(dv, "Recompile with \"options %s\" to " 823 aprint_normal_dev(dv, "Recompile with \"options %s\" to "
824 "correct this.\n", cpu_classes[cpu_class].class_option); 824 "correct this.\n", cpu_classes[cpu_class].class_option);
825 } 825 }
826 break; 826 break;
827 } 827 }
828} 828}
829 829
830extern int cpu_instruction_set_attributes[6]; 830extern int cpu_instruction_set_attributes[6];
831extern int cpu_memory_model_features[4]; 831extern int cpu_memory_model_features[4];
832extern int cpu_processor_features[2]; 832extern int cpu_processor_features[2];
833extern int cpu_simd_present; 833extern int cpu_simd_present;
834extern int cpu_simdex_present; 834extern int cpu_simdex_present;
835 835
836void 836void
837identify_features(device_t dv, struct cpu_info *ci) 837identify_features(device_t dv, struct cpu_info *ci)
838{ 838{
839 const int unit = device_unit(dv); 839 const int unit = device_unit(dv);
840 840
841 aprint_debug_dev(dv, "sctlr: %#x\n", ci->ci_ctrl); 841 aprint_debug_dev(dv, "sctlr: %#x\n", ci->ci_ctrl);
842 aprint_debug_dev(dv, "actlr: %#x\n", ci->ci_actlr); 842 aprint_debug_dev(dv, "actlr: %#x\n", ci->ci_actlr);
843 aprint_debug_dev(dv, "revidr: %#x\n", ci->ci_revidr); 843 aprint_debug_dev(dv, "revidr: %#x\n", ci->ci_revidr);
844#ifdef MULTIPROCESSOR 844#ifdef MULTIPROCESSOR
845 aprint_debug_dev(dv, "mpidr: %#x\n", ci->ci_mpidr); 845 aprint_debug_dev(dv, "mpidr: %#x\n", ci->ci_mpidr);
846#endif 846#endif
847 847
848 if (unit != 0) 848 if (unit != 0)
849 return; 849 return;
850 850
851 cpu_instruction_set_attributes[0] = armreg_isar0_read(); 851 cpu_instruction_set_attributes[0] = armreg_isar0_read();
852 cpu_instruction_set_attributes[1] = armreg_isar1_read(); 852 cpu_instruction_set_attributes[1] = armreg_isar1_read();
853 cpu_instruction_set_attributes[2] = armreg_isar2_read(); 853 cpu_instruction_set_attributes[2] = armreg_isar2_read();
854 cpu_instruction_set_attributes[3] = armreg_isar3_read(); 854 cpu_instruction_set_attributes[3] = armreg_isar3_read();
855 cpu_instruction_set_attributes[4] = armreg_isar4_read(); 855 cpu_instruction_set_attributes[4] = armreg_isar4_read();
856 cpu_instruction_set_attributes[5] = armreg_isar5_read(); 856 cpu_instruction_set_attributes[5] = armreg_isar5_read();
857 857
858 cpu_hwdiv_present = 858 cpu_hwdiv_present =
859 ((cpu_instruction_set_attributes[0] >> 24) & 0x0f) >= 2; 859 ((cpu_instruction_set_attributes[0] >> 24) & 0x0f) >= 2;
860 cpu_simd_present = 860 cpu_simd_present =
861 ((cpu_instruction_set_attributes[3] >> 4) & 0x0f) >= 3; 861 ((cpu_instruction_set_attributes[3] >> 4) & 0x0f) >= 3;
862 cpu_simdex_present = cpu_simd_present 862 cpu_simdex_present = cpu_simd_present
863 && ((cpu_instruction_set_attributes[1] >> 12) & 0x0f) >= 2; 863 && ((cpu_instruction_set_attributes[1] >> 12) & 0x0f) >= 2;
864 cpu_synchprim_present = 864 cpu_synchprim_present =
865 ((cpu_instruction_set_attributes[3] >> 8) & 0xf0) 865 ((cpu_instruction_set_attributes[3] >> 8) & 0xf0)
866 | ((cpu_instruction_set_attributes[4] >> 20) & 0x0f); 866 | ((cpu_instruction_set_attributes[4] >> 20) & 0x0f);
867 867
868 cpu_memory_model_features[0] = armreg_mmfr0_read(); 868 cpu_memory_model_features[0] = armreg_mmfr0_read();
869 cpu_memory_model_features[1] = armreg_mmfr1_read(); 869 cpu_memory_model_features[1] = armreg_mmfr1_read();
870 cpu_memory_model_features[2] = armreg_mmfr2_read(); 870 cpu_memory_model_features[2] = armreg_mmfr2_read();
871 cpu_memory_model_features[3] = armreg_mmfr3_read(); 871 cpu_memory_model_features[3] = armreg_mmfr3_read();
872 872
873#if 0 873#if 0
874 if (__SHIFTOUT(cpu_memory_model_features[3], __BITS(23,20))) { 874 if (__SHIFTOUT(cpu_memory_model_features[3], __BITS(23,20))) {
875 /* 875 /*
876 * Updates to the translation tables do not require a clean 876 * Updates to the translation tables do not require a clean
877 * to the point of unification to ensure visibility by 877 * to the point of unification to ensure visibility by
878 * subsequent translation table walks. 878 * subsequent translation table walks.
879 */ 879 */
880 pmap_needs_pte_sync = 0; 880 pmap_needs_pte_sync = 0;
881 } 881 }
882#endif 882#endif
883 883
884 cpu_processor_features[0] = armreg_pfr0_read(); 884 cpu_processor_features[0] = armreg_pfr0_read();
885 cpu_processor_features[1] = armreg_pfr1_read(); 885 cpu_processor_features[1] = armreg_pfr1_read();
886 886
887 aprint_debug_dev(dv, 887 aprint_debug_dev(dv,
888 "isar: [0]=%#x [1]=%#x [2]=%#x [3]=%#x, [4]=%#x, [5]=%#x\n", 888 "isar: [0]=%#x [1]=%#x [2]=%#x [3]=%#x, [4]=%#x, [5]=%#x\n",
889 cpu_instruction_set_attributes[0], 889 cpu_instruction_set_attributes[0],
890 cpu_instruction_set_attributes[1], 890 cpu_instruction_set_attributes[1],
891 cpu_instruction_set_attributes[2], 891 cpu_instruction_set_attributes[2],
892 cpu_instruction_set_attributes[3], 892 cpu_instruction_set_attributes[3],
893 cpu_instruction_set_attributes[4], 893 cpu_instruction_set_attributes[4],
894 cpu_instruction_set_attributes[5]); 894 cpu_instruction_set_attributes[5]);
895 aprint_debug_dev(dv, 895 aprint_debug_dev(dv,
896 "mmfr: [0]=%#x [1]=%#x [2]=%#x [3]=%#x\n", 896 "mmfr: [0]=%#x [1]=%#x [2]=%#x [3]=%#x\n",
897 cpu_memory_model_features[0], cpu_memory_model_features[1], 897 cpu_memory_model_features[0], cpu_memory_model_features[1],
898 cpu_memory_model_features[2], cpu_memory_model_features[3]); 898 cpu_memory_model_features[2], cpu_memory_model_features[3]);
899 aprint_debug_dev(dv, 899 aprint_debug_dev(dv,
900 "pfr: [0]=%#x [1]=%#x\n", 900 "pfr: [0]=%#x [1]=%#x\n",
901 cpu_processor_features[0], cpu_processor_features[1]); 901 cpu_processor_features[0], cpu_processor_features[1]);
902} 902}
903 903
904#ifdef _ARM_ARCH_6 904#ifdef _ARM_ARCH_6
905int 905int
906cpu_maxproc_hook(int nmaxproc) 906cpu_maxproc_hook(int nmaxproc)
907{ 907{
908 908
909#ifdef ARM_MMU_EXTENDED 909#ifdef ARM_MMU_EXTENDED
910 return pmap_maxproc_set(nmaxproc); 910 return pmap_maxproc_set(nmaxproc);
911#else 911#else
912 return 0; 912 return 0;
913#endif 913#endif
914} 914}
915#endif 915#endif

cvs diff -r1.41 -r1.42 src/sys/arch/arm/fdt/cpu_fdt.c (switch to unified diff)

--- src/sys/arch/arm/fdt/cpu_fdt.c 2021/08/30 23:16:17 1.41
+++ src/sys/arch/arm/fdt/cpu_fdt.c 2022/03/03 06:26:05 1.42
@@ -1,387 +1,378 @@ @@ -1,387 +1,378 @@
1/* $NetBSD: cpu_fdt.c,v 1.41 2021/08/30 23:16:17 jmcneill Exp $ */ 1/* $NetBSD: cpu_fdt.c,v 1.42 2022/03/03 06:26:05 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
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 WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_multiprocessor.h" 29#include "opt_multiprocessor.h"
30#include "psci_fdt.h" 30#include "psci_fdt.h"
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.41 2021/08/30 23:16:17 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.42 2022/03/03 06:26:05 riastradh Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/atomic.h> 36#include <sys/atomic.h>
37#include <sys/bus.h> 37#include <sys/bus.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/lwp.h> 39#include <sys/lwp.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kernel.h> 41#include <sys/kernel.h>
42 42
43#include <dev/fdt/fdtvar.h> 43#include <dev/fdt/fdtvar.h>
44 44
45#include <arm/armreg.h> 45#include <arm/armreg.h>
46#include <arm/cpu.h> 46#include <arm/cpu.h>
47#include <arm/cpufunc.h> 47#include <arm/cpufunc.h>
48#include <arm/cpuvar.h> 48#include <arm/cpuvar.h>
49#include <arm/locore.h> 49#include <arm/locore.h>
50 50
51#include <arm/arm/psci.h> 51#include <arm/arm/psci.h>
52#include <arm/fdt/arm_fdtvar.h> 52#include <arm/fdt/arm_fdtvar.h>
53#include <arm/fdt/psci_fdtvar.h> 53#include <arm/fdt/psci_fdtvar.h>
54 54
55#include <uvm/uvm_extern.h> 55#include <uvm/uvm_extern.h>
56 56
57static int cpu_fdt_match(device_t, cfdata_t, void *); 57static int cpu_fdt_match(device_t, cfdata_t, void *);
58static void cpu_fdt_attach(device_t, device_t, void *); 58static void cpu_fdt_attach(device_t, device_t, void *);
59 59
60struct cpu_fdt_softc { 60CFATTACH_DECL_NEW(cpu_fdt, 0,
61 device_t sc_dev; 
62 int sc_phandle; 
63}; 
64 
65CFATTACH_DECL_NEW(cpu_fdt, sizeof(struct cpu_fdt_softc), 
66 cpu_fdt_match, cpu_fdt_attach, NULL, NULL); 61 cpu_fdt_match, cpu_fdt_attach, NULL, NULL);
67 62
68static int 63static int
69cpu_fdt_match(device_t parent, cfdata_t cf, void *aux) 64cpu_fdt_match(device_t parent, cfdata_t cf, void *aux)
70{ 65{
71 struct fdt_attach_args * const faa = aux; 66 struct fdt_attach_args * const faa = aux;
72 const int phandle = faa->faa_phandle; 67 const int phandle = faa->faa_phandle;
73 const char *device_type; 68 const char *device_type;
74 69
75 device_type = fdtbus_get_string(phandle, "device_type"); 70 device_type = fdtbus_get_string(phandle, "device_type");
76 71
77 return device_type != NULL && strcmp(device_type, "cpu") == 0; 72 return device_type != NULL && strcmp(device_type, "cpu") == 0;
78} 73}
79 74
80static void 75static void
81cpu_fdt_attach(device_t parent, device_t self, void *aux) 76cpu_fdt_attach(device_t parent, device_t self, void *aux)
82{ 77{
83 struct cpu_fdt_softc * const sc = device_private(self); 
84 struct fdt_attach_args * const faa = aux; 78 struct fdt_attach_args * const faa = aux;
85 const int phandle = faa->faa_phandle; 79 const int phandle = faa->faa_phandle;
86 bus_addr_t cpuid; 80 bus_addr_t cpuid;
87 const uint32_t *cap_ptr; 81 const uint32_t *cap_ptr;
88 int len; 82 int len;
89 83
90 sc->sc_dev = self; 
91 sc->sc_phandle = phandle; 
92 
93 cap_ptr = fdtbus_get_prop(phandle, "capacity-dmips-mhz", &len); 84 cap_ptr = fdtbus_get_prop(phandle, "capacity-dmips-mhz", &len);
94 if (cap_ptr && len == 4) { 85 if (cap_ptr && len == 4) {
95 prop_dictionary_t dict = device_properties(self); 86 prop_dictionary_t dict = device_properties(self);
96 uint32_t capacity_dmips_mhz = be32toh(*cap_ptr); 87 uint32_t capacity_dmips_mhz = be32toh(*cap_ptr);
97 88
98 prop_dictionary_set_uint32(dict, "capacity_dmips_mhz", 89 prop_dictionary_set_uint32(dict, "capacity_dmips_mhz",
99 capacity_dmips_mhz); 90 capacity_dmips_mhz);
100 } 91 }
101 92
102 if (fdtbus_get_reg(phandle, 0, &cpuid, NULL) != 0) 93 if (fdtbus_get_reg(phandle, 0, &cpuid, NULL) != 0)
103 cpuid = 0; 94 cpuid = 0;
104 95
105 /* Attach the CPU */ 96 /* Attach the CPU */
106 cpu_attach(self, cpuid); 97 cpu_attach(self, cpuid);
107 98
108 /* Attach CPU frequency scaling provider */ 99 /* Attach CPU frequency scaling provider */
109 config_found(self, faa, NULL, CFARGS_NONE); 100 config_found(self, faa, NULL, CFARGS_NONE);
110} 101}
111 102
112#if defined(MULTIPROCESSOR) && (NPSCI_FDT > 0 || defined(__aarch64__)) 103#if defined(MULTIPROCESSOR) && (NPSCI_FDT > 0 || defined(__aarch64__))
113static register_t 104static register_t
114cpu_fdt_mpstart_pa(void) 105cpu_fdt_mpstart_pa(void)
115{ 106{
116 bool ok __diagused; 107 bool ok __diagused;
117 paddr_t pa; 108 paddr_t pa;
118 109
119 ok = pmap_extract(pmap_kernel(), (vaddr_t)cpu_mpstart, &pa); 110 ok = pmap_extract(pmap_kernel(), (vaddr_t)cpu_mpstart, &pa);
120 KASSERT(ok); 111 KASSERT(ok);
121 112
122 return pa; 113 return pa;
123} 114}
124#endif 115#endif
125 116
126#ifdef MULTIPROCESSOR 117#ifdef MULTIPROCESSOR
127static bool 118static bool
128arm_fdt_cpu_okay(const int child) 119arm_fdt_cpu_okay(const int child)
129{ 120{
130 const char *s; 121 const char *s;
131 122
132 s = fdtbus_get_string(child, "device_type"); 123 s = fdtbus_get_string(child, "device_type");
133 if (!s || strcmp(s, "cpu") != 0) 124 if (!s || strcmp(s, "cpu") != 0)
134 return false; 125 return false;
135 126
136 s = fdtbus_get_string(child, "status"); 127 s = fdtbus_get_string(child, "status");
137 if (s) { 128 if (s) {
138 if (strcmp(s, "okay") == 0) 129 if (strcmp(s, "okay") == 0)
139 return false; 130 return false;
140 if (strcmp(s, "disabled") == 0) 131 if (strcmp(s, "disabled") == 0)
141 return of_hasprop(child, "enable-method"); 132 return of_hasprop(child, "enable-method");
142 return false; 133 return false;
143 } else { 134 } else {
144 return true; 135 return true;
145 } 136 }
146} 137}
147#endif /* MULTIPROCESSOR */ 138#endif /* MULTIPROCESSOR */
148 139
149void 140void
150arm_fdt_cpu_bootstrap(void) 141arm_fdt_cpu_bootstrap(void)
151{ 142{
152#ifdef MULTIPROCESSOR 143#ifdef MULTIPROCESSOR
153 uint64_t mpidr, bp_mpidr; 144 uint64_t mpidr, bp_mpidr;
154 u_int cpuindex; 145 u_int cpuindex;
155 int child; 146 int child;
156 147
157 const int cpus = OF_finddevice("/cpus"); 148 const int cpus = OF_finddevice("/cpus");
158 if (cpus == -1) { 149 if (cpus == -1) {
159 aprint_error("%s: no /cpus node found\n", __func__); 150 aprint_error("%s: no /cpus node found\n", __func__);
160 arm_cpu_max = 1; 151 arm_cpu_max = 1;
161 return; 152 return;
162 } 153 }
163 154
164 /* Count CPUs */ 155 /* Count CPUs */
165 arm_cpu_max = 0; 156 arm_cpu_max = 0;
166 157
167 /* MPIDR affinity levels of boot processor. */ 158 /* MPIDR affinity levels of boot processor. */
168 bp_mpidr = cpu_mpidr_aff_read(); 159 bp_mpidr = cpu_mpidr_aff_read();
169 160
170 /* Add APs to cpu_mpidr array */ 161 /* Add APs to cpu_mpidr array */
171 cpuindex = 1; 162 cpuindex = 1;
172 for (child = OF_child(cpus); child; child = OF_peer(child)) { 163 for (child = OF_child(cpus); child; child = OF_peer(child)) {
173 if (!arm_fdt_cpu_okay(child)) 164 if (!arm_fdt_cpu_okay(child))
174 continue; 165 continue;
175 166
176 arm_cpu_max++; 167 arm_cpu_max++;
177 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) 168 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0)
178 continue; 169 continue;
179 if (mpidr == bp_mpidr) 170 if (mpidr == bp_mpidr)
180 continue; /* BP already started */ 171 continue; /* BP already started */
181 172
182 KASSERT(cpuindex < MAXCPUS); 173 KASSERT(cpuindex < MAXCPUS);
183 cpu_mpidr[cpuindex] = mpidr; 174 cpu_mpidr[cpuindex] = mpidr;
184 cpu_dcache_wb_range((vaddr_t)&cpu_mpidr[cpuindex], 175 cpu_dcache_wb_range((vaddr_t)&cpu_mpidr[cpuindex],
185 sizeof(cpu_mpidr[cpuindex])); 176 sizeof(cpu_mpidr[cpuindex]));
186 177
187 cpuindex++; 178 cpuindex++;
188 } 179 }
189#endif 180#endif
190} 181}
191 182
192#ifdef MULTIPROCESSOR 183#ifdef MULTIPROCESSOR
193static struct arm_cpu_method * 184static struct arm_cpu_method *
194arm_fdt_cpu_enable_method_byname(const char *method) 185arm_fdt_cpu_enable_method_byname(const char *method)
195{ 186{
196 __link_set_decl(arm_cpu_methods, struct arm_cpu_method); 187 __link_set_decl(arm_cpu_methods, struct arm_cpu_method);
197 struct arm_cpu_method * const *acmp; 188 struct arm_cpu_method * const *acmp;
198 189
199 __link_set_foreach(acmp, arm_cpu_methods) { 190 __link_set_foreach(acmp, arm_cpu_methods) {
200 if (strcmp(method, (*acmp)->acm_compat) == 0) 191 if (strcmp(method, (*acmp)->acm_compat) == 0)
201 return *acmp; 192 return *acmp;
202 } 193 }
203 194
204 return NULL; 195 return NULL;
205} 196}
206 197
207static struct arm_cpu_method * 198static struct arm_cpu_method *
208arm_fdt_cpu_enable_method(int phandle) 199arm_fdt_cpu_enable_method(int phandle)
209{ 200{
210 const char *method; 201 const char *method;
211 202
212 method = fdtbus_get_string(phandle, "enable-method"); 203 method = fdtbus_get_string(phandle, "enable-method");
213 if (method == NULL) 204 if (method == NULL)
214 return NULL; 205 return NULL;
215 206
216 return arm_fdt_cpu_enable_method_byname(method); 207 return arm_fdt_cpu_enable_method_byname(method);
217} 208}
218 209
219static int 210static int
220arm_fdt_cpu_enable(int phandle, struct arm_cpu_method *acm) 211arm_fdt_cpu_enable(int phandle, struct arm_cpu_method *acm)
221{ 212{
222 return acm->acm_enable(phandle); 213 return acm->acm_enable(phandle);
223} 214}
224#endif 215#endif
225 216
226int 217int
227arm_fdt_cpu_mpstart(void) 218arm_fdt_cpu_mpstart(void)
228{ 219{
229 int ret = 0; 220 int ret = 0;
230#ifdef MULTIPROCESSOR 221#ifdef MULTIPROCESSOR
231 uint64_t mpidr, bp_mpidr; 222 uint64_t mpidr, bp_mpidr;
232 u_int cpuindex, i; 223 u_int cpuindex, i;
233 int child, error; 224 int child, error;
234 struct arm_cpu_method *acm; 225 struct arm_cpu_method *acm;
235 226
236 const int cpus = OF_finddevice("/cpus"); 227 const int cpus = OF_finddevice("/cpus");
237 if (cpus == -1) { 228 if (cpus == -1) {
238 aprint_error("%s: no /cpus node found\n", __func__); 229 aprint_error("%s: no /cpus node found\n", __func__);
239 return 0; 230 return 0;
240 } 231 }
241 232
242 /* MPIDR affinity levels of boot processor. */ 233 /* MPIDR affinity levels of boot processor. */
243 bp_mpidr = cpu_mpidr_aff_read(); 234 bp_mpidr = cpu_mpidr_aff_read();
244 235
245 /* Boot APs */ 236 /* Boot APs */
246 cpuindex = 1; 237 cpuindex = 1;
247 for (child = OF_child(cpus); child; child = OF_peer(child)) { 238 for (child = OF_child(cpus); child; child = OF_peer(child)) {
248 if (!arm_fdt_cpu_okay(child)) 239 if (!arm_fdt_cpu_okay(child))
249 continue; 240 continue;
250 241
251 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) 242 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0)
252 continue; 243 continue;
253 244
254 if (mpidr == bp_mpidr) 245 if (mpidr == bp_mpidr)
255 continue; /* BP already started */ 246 continue; /* BP already started */
256 247
257 acm = arm_fdt_cpu_enable_method(child); 248 acm = arm_fdt_cpu_enable_method(child);
258 if (acm == NULL) 249 if (acm == NULL)
259 acm = arm_fdt_cpu_enable_method(cpus); 250 acm = arm_fdt_cpu_enable_method(cpus);
260 if (acm == NULL) 251 if (acm == NULL)
261 acm = arm_fdt_cpu_enable_method_byname("psci"); 252 acm = arm_fdt_cpu_enable_method_byname("psci");
262 if (acm == NULL) 253 if (acm == NULL)
263 continue; 254 continue;
264 255
265 error = arm_fdt_cpu_enable(child, acm); 256 error = arm_fdt_cpu_enable(child, acm);
266 if (error != 0) { 257 if (error != 0) {
267 aprint_error("%s: failed to enable CPU %#" PRIx64 "\n", 258 aprint_error("%s: failed to enable CPU %#" PRIx64 "\n",
268 __func__, mpidr); 259 __func__, mpidr);
269 continue; 260 continue;
270 } 261 }
271 262
272 /* Wake up AP in case firmware has placed it in WFE state */ 263 /* Wake up AP in case firmware has placed it in WFE state */
273 sev(); 264 sev();
274 265
275 /* Wait for AP to start */ 266 /* Wait for AP to start */
276 for (i = 0x10000000; i > 0; i--) { 267 for (i = 0x10000000; i > 0; i--) {
277 if (cpu_hatched_p(cpuindex)) 268 if (cpu_hatched_p(cpuindex))
278 break; 269 break;
279 } 270 }
280 271
281 if (i == 0) { 272 if (i == 0) {
282 ret++; 273 ret++;
283 aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex); 274 aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex);
284 } 275 }
285 276
286 cpuindex++; 277 cpuindex++;
287 } 278 }
288#endif /* MULTIPROCESSOR */ 279#endif /* MULTIPROCESSOR */
289 return ret; 280 return ret;
290} 281}
291 282
292static int 283static int
293cpu_enable_nullop(int phandle) 284cpu_enable_nullop(int phandle)
294{ 285{
295 return ENXIO; 286 return ENXIO;
296} 287}
297ARM_CPU_METHOD(default, "", cpu_enable_nullop); 288ARM_CPU_METHOD(default, "", cpu_enable_nullop);
298 289
299#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0 290#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0
300static int 291static int
301cpu_enable_psci(int phandle) 292cpu_enable_psci(int phandle)
302{ 293{
303 static bool psci_probed, psci_p; 294 static bool psci_probed, psci_p;
304 uint64_t mpidr; 295 uint64_t mpidr;
305 int ret; 296 int ret;
306 297
307 if (!psci_probed) { 298 if (!psci_probed) {
308 psci_probed = true; 299 psci_probed = true;
309 psci_p = psci_fdt_preinit() == 0; 300 psci_p = psci_fdt_preinit() == 0;
310 } 301 }
311 if (!psci_p) 302 if (!psci_p)
312 return ENXIO; 303 return ENXIO;
313 304
314 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 305 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
315 306
316#if !defined(AARCH64) 307#if !defined(AARCH64)
317 /* 308 /*
318 * not necessary on AARCH64. beside there it hangs the system 309 * not necessary on AARCH64. beside there it hangs the system
319 * because cache ops are only functional after cpu_attach() 310 * because cache ops are only functional after cpu_attach()
320 * was called. 311 * was called.
321 */ 312 */
322 cpu_dcache_wbinv_all(); 313 cpu_dcache_wbinv_all();
323#endif 314#endif
324 ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0); 315 ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0);
325 if (ret != PSCI_SUCCESS) 316 if (ret != PSCI_SUCCESS)
326 return EIO; 317 return EIO;
327 318
328 return 0; 319 return 0;
329} 320}
330ARM_CPU_METHOD(psci, "psci", cpu_enable_psci); 321ARM_CPU_METHOD(psci, "psci", cpu_enable_psci);
331#endif 322#endif
332 323
333#if defined(MULTIPROCESSOR) && defined(__aarch64__) 324#if defined(MULTIPROCESSOR) && defined(__aarch64__)
334static int 325static int
335spintable_cpu_on(const int phandle, u_int cpuindex, 326spintable_cpu_on(const int phandle, u_int cpuindex,
336 paddr_t entry_point_address, paddr_t cpu_release_addr) 327 paddr_t entry_point_address, paddr_t cpu_release_addr)
337{ 328{
338 /* 329 /*
339 * we need devmap for cpu-release-addr in advance. 330 * we need devmap for cpu-release-addr in advance.
340 * __HAVE_MM_MD_DIRECT_MAPPED_PHYS nor pmap work at this point. 331 * __HAVE_MM_MD_DIRECT_MAPPED_PHYS nor pmap work at this point.
341 */ 332 */
342 if (pmap_devmap_find_pa(cpu_release_addr, sizeof(paddr_t)) == NULL) { 333 if (pmap_devmap_find_pa(cpu_release_addr, sizeof(paddr_t)) == NULL) {
343 aprint_error("%s: devmap for cpu-release-addr" 334 aprint_error("%s: devmap for cpu-release-addr"
344 " 0x%08"PRIxPADDR" required\n", __func__, cpu_release_addr); 335 " 0x%08"PRIxPADDR" required\n", __func__, cpu_release_addr);
345 return -1; 336 return -1;
346 } else { 337 } else {
347 extern struct bus_space arm_generic_bs_tag; 338 extern struct bus_space arm_generic_bs_tag;
348 bus_space_handle_t ioh; 339 bus_space_handle_t ioh;
349 340
350 const int parent = OF_parent(phandle); 341 const int parent = OF_parent(phandle);
351 const int addr_cells = fdtbus_get_addr_cells(parent); 342 const int addr_cells = fdtbus_get_addr_cells(parent);
352 343
353 bus_space_map(&arm_generic_bs_tag, cpu_release_addr, 344 bus_space_map(&arm_generic_bs_tag, cpu_release_addr,
354 sizeof(paddr_t), 0, &ioh); 345 sizeof(paddr_t), 0, &ioh);
355 if (addr_cells == 1) { 346 if (addr_cells == 1) {
356 bus_space_write_4(&arm_generic_bs_tag, ioh, 0, 347 bus_space_write_4(&arm_generic_bs_tag, ioh, 0,
357 entry_point_address); 348 entry_point_address);
358 } else { 349 } else {
359 bus_space_write_8(&arm_generic_bs_tag, ioh, 0, 350 bus_space_write_8(&arm_generic_bs_tag, ioh, 0,
360 entry_point_address); 351 entry_point_address);
361 } 352 }
362 bus_space_unmap(&arm_generic_bs_tag, ioh, sizeof(paddr_t)); 353 bus_space_unmap(&arm_generic_bs_tag, ioh, sizeof(paddr_t));
363 } 354 }
364 355
365 return 0; 356 return 0;
366} 357}
367 358
368static int 359static int
369cpu_enable_spin_table(int phandle) 360cpu_enable_spin_table(int phandle)
370{ 361{
371 uint64_t mpidr, addr; 362 uint64_t mpidr, addr;
372 int ret; 363 int ret;
373 364
374 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 365 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
375 366
376 if (of_getprop_uint64(phandle, "cpu-release-addr", &addr) != 0) 367 if (of_getprop_uint64(phandle, "cpu-release-addr", &addr) != 0)
377 return ENXIO; 368 return ENXIO;
378 369
379 ret = spintable_cpu_on(phandle, mpidr, cpu_fdt_mpstart_pa(), 370 ret = spintable_cpu_on(phandle, mpidr, cpu_fdt_mpstart_pa(),
380 (paddr_t)addr); 371 (paddr_t)addr);
381 if (ret != 0) 372 if (ret != 0)
382 return EIO; 373 return EIO;
383 374
384 return 0; 375 return 0;
385} 376}
386ARM_CPU_METHOD(spin_table, "spin-table", cpu_enable_spin_table); 377ARM_CPU_METHOD(spin_table, "spin-table", cpu_enable_spin_table);
387#endif 378#endif