Fri May 10 14:42:21 2024 UTC (36d)
arm/fdt/cpu_fdt.c: Use `cpu' iattr to attach cpufreq.

Now that cpu has an explicit interface attribute, cpufeaturebus,
_all_ children of cpu must use an explicit interface attribute to
disambiguate.  For children that weren't previously attached using an
explicit interface attribute, the name of the parent, `cpu', serves
as the iattr.

XXX I think we should either
(a) not use cpufreqbus, since in the aarch64 case it doesn't seem to
    be passing any information through attach args, or
(b) create another iattr like cpufdtbus for use by cpufreq_dt.c,
    which does rely on attach args, if it has to attach differently
    from the rest of fdtbus.
But for now this should get aarch64 on fdt booting again.


(riastradh)
diff -r1.43 -r1.44 src/sys/arch/arm/fdt/cpu_fdt.c

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

--- src/sys/arch/arm/fdt/cpu_fdt.c 2024/05/09 12:41:08 1.43
+++ src/sys/arch/arm/fdt/cpu_fdt.c 2024/05/10 14:42:21 1.44
@@ -1,379 +1,379 @@ @@ -1,379 +1,379 @@
1/* $NetBSD: cpu_fdt.c,v 1.43 2024/05/09 12:41:08 pho Exp $ */ 1/* $NetBSD: cpu_fdt.c,v 1.44 2024/05/10 14:42:21 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.43 2024/05/09 12:41:08 pho Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.44 2024/05/10 14:42:21 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
60CFATTACH_DECL2_NEW(cpu_fdt, 0, 60CFATTACH_DECL2_NEW(cpu_fdt, 0,
61 cpu_fdt_match, cpu_fdt_attach, NULL, NULL, 61 cpu_fdt_match, cpu_fdt_attach, NULL, NULL,
62 cpu_rescan, cpu_childdetached); 62 cpu_rescan, cpu_childdetached);
63 63
64static int 64static int
65cpu_fdt_match(device_t parent, cfdata_t cf, void *aux) 65cpu_fdt_match(device_t parent, cfdata_t cf, void *aux)
66{ 66{
67 struct fdt_attach_args * const faa = aux; 67 struct fdt_attach_args * const faa = aux;
68 const int phandle = faa->faa_phandle; 68 const int phandle = faa->faa_phandle;
69 const char *device_type; 69 const char *device_type;
70 70
71 device_type = fdtbus_get_string(phandle, "device_type"); 71 device_type = fdtbus_get_string(phandle, "device_type");
72 72
73 return device_type != NULL && strcmp(device_type, "cpu") == 0; 73 return device_type != NULL && strcmp(device_type, "cpu") == 0;
74} 74}
75 75
76static void 76static void
77cpu_fdt_attach(device_t parent, device_t self, void *aux) 77cpu_fdt_attach(device_t parent, device_t self, void *aux)
78{ 78{
79 struct fdt_attach_args * const faa = aux; 79 struct fdt_attach_args * const faa = aux;
80 const int phandle = faa->faa_phandle; 80 const int phandle = faa->faa_phandle;
81 bus_addr_t cpuid; 81 bus_addr_t cpuid;
82 const uint32_t *cap_ptr; 82 const uint32_t *cap_ptr;
83 int len; 83 int len;
84 84
85 cap_ptr = fdtbus_get_prop(phandle, "capacity-dmips-mhz", &len); 85 cap_ptr = fdtbus_get_prop(phandle, "capacity-dmips-mhz", &len);
86 if (cap_ptr && len == 4) { 86 if (cap_ptr && len == 4) {
87 prop_dictionary_t dict = device_properties(self); 87 prop_dictionary_t dict = device_properties(self);
88 uint32_t capacity_dmips_mhz = be32toh(*cap_ptr); 88 uint32_t capacity_dmips_mhz = be32toh(*cap_ptr);
89 89
90 prop_dictionary_set_uint32(dict, "capacity_dmips_mhz", 90 prop_dictionary_set_uint32(dict, "capacity_dmips_mhz",
91 capacity_dmips_mhz); 91 capacity_dmips_mhz);
92 } 92 }
93 93
94 if (fdtbus_get_reg(phandle, 0, &cpuid, NULL) != 0) 94 if (fdtbus_get_reg(phandle, 0, &cpuid, NULL) != 0)
95 cpuid = 0; 95 cpuid = 0;
96 96
97 /* Attach the CPU */ 97 /* Attach the CPU */
98 cpu_attach(self, cpuid); 98 cpu_attach(self, cpuid);
99 99
100 /* Attach CPU frequency scaling provider */ 100 /* Attach CPU frequency scaling provider */
101 config_found(self, faa, NULL, CFARGS_NONE); 101 config_found(self, faa, NULL, CFARGS(.iattr = "cpu"));
102} 102}
103 103
104#if defined(MULTIPROCESSOR) && (NPSCI_FDT > 0 || defined(__aarch64__)) 104#if defined(MULTIPROCESSOR) && (NPSCI_FDT > 0 || defined(__aarch64__))
105static register_t 105static register_t
106cpu_fdt_mpstart_pa(void) 106cpu_fdt_mpstart_pa(void)
107{ 107{
108 bool ok __diagused; 108 bool ok __diagused;
109 paddr_t pa; 109 paddr_t pa;
110 110
111 ok = pmap_extract(pmap_kernel(), (vaddr_t)cpu_mpstart, &pa); 111 ok = pmap_extract(pmap_kernel(), (vaddr_t)cpu_mpstart, &pa);
112 KASSERT(ok); 112 KASSERT(ok);
113 113
114 return pa; 114 return pa;
115} 115}
116#endif 116#endif
117 117
118#ifdef MULTIPROCESSOR 118#ifdef MULTIPROCESSOR
119static bool 119static bool
120arm_fdt_cpu_okay(const int child) 120arm_fdt_cpu_okay(const int child)
121{ 121{
122 const char *s; 122 const char *s;
123 123
124 s = fdtbus_get_string(child, "device_type"); 124 s = fdtbus_get_string(child, "device_type");
125 if (!s || strcmp(s, "cpu") != 0) 125 if (!s || strcmp(s, "cpu") != 0)
126 return false; 126 return false;
127 127
128 s = fdtbus_get_string(child, "status"); 128 s = fdtbus_get_string(child, "status");
129 if (s) { 129 if (s) {
130 if (strcmp(s, "okay") == 0) 130 if (strcmp(s, "okay") == 0)
131 return false; 131 return false;
132 if (strcmp(s, "disabled") == 0) 132 if (strcmp(s, "disabled") == 0)
133 return of_hasprop(child, "enable-method"); 133 return of_hasprop(child, "enable-method");
134 return false; 134 return false;
135 } else { 135 } else {
136 return true; 136 return true;
137 } 137 }
138} 138}
139#endif /* MULTIPROCESSOR */ 139#endif /* MULTIPROCESSOR */
140 140
141void 141void
142arm_fdt_cpu_bootstrap(void) 142arm_fdt_cpu_bootstrap(void)
143{ 143{
144#ifdef MULTIPROCESSOR 144#ifdef MULTIPROCESSOR
145 uint64_t mpidr, bp_mpidr; 145 uint64_t mpidr, bp_mpidr;
146 u_int cpuindex; 146 u_int cpuindex;
147 int child; 147 int child;
148 148
149 const int cpus = OF_finddevice("/cpus"); 149 const int cpus = OF_finddevice("/cpus");
150 if (cpus == -1) { 150 if (cpus == -1) {
151 aprint_error("%s: no /cpus node found\n", __func__); 151 aprint_error("%s: no /cpus node found\n", __func__);
152 arm_cpu_max = 1; 152 arm_cpu_max = 1;
153 return; 153 return;
154 } 154 }
155 155
156 /* Count CPUs */ 156 /* Count CPUs */
157 arm_cpu_max = 0; 157 arm_cpu_max = 0;
158 158
159 /* MPIDR affinity levels of boot processor. */ 159 /* MPIDR affinity levels of boot processor. */
160 bp_mpidr = cpu_mpidr_aff_read(); 160 bp_mpidr = cpu_mpidr_aff_read();
161 161
162 /* Add APs to cpu_mpidr array */ 162 /* Add APs to cpu_mpidr array */
163 cpuindex = 1; 163 cpuindex = 1;
164 for (child = OF_child(cpus); child; child = OF_peer(child)) { 164 for (child = OF_child(cpus); child; child = OF_peer(child)) {
165 if (!arm_fdt_cpu_okay(child)) 165 if (!arm_fdt_cpu_okay(child))
166 continue; 166 continue;
167 167
168 arm_cpu_max++; 168 arm_cpu_max++;
169 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) 169 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0)
170 continue; 170 continue;
171 if (mpidr == bp_mpidr) 171 if (mpidr == bp_mpidr)
172 continue; /* BP already started */ 172 continue; /* BP already started */
173 173
174 KASSERT(cpuindex < MAXCPUS); 174 KASSERT(cpuindex < MAXCPUS);
175 cpu_mpidr[cpuindex] = mpidr; 175 cpu_mpidr[cpuindex] = mpidr;
176 cpu_dcache_wb_range((vaddr_t)&cpu_mpidr[cpuindex], 176 cpu_dcache_wb_range((vaddr_t)&cpu_mpidr[cpuindex],
177 sizeof(cpu_mpidr[cpuindex])); 177 sizeof(cpu_mpidr[cpuindex]));
178 178
179 cpuindex++; 179 cpuindex++;
180 } 180 }
181#endif 181#endif
182} 182}
183 183
184#ifdef MULTIPROCESSOR 184#ifdef MULTIPROCESSOR
185static struct arm_cpu_method * 185static struct arm_cpu_method *
186arm_fdt_cpu_enable_method_byname(const char *method) 186arm_fdt_cpu_enable_method_byname(const char *method)
187{ 187{
188 __link_set_decl(arm_cpu_methods, struct arm_cpu_method); 188 __link_set_decl(arm_cpu_methods, struct arm_cpu_method);
189 struct arm_cpu_method * const *acmp; 189 struct arm_cpu_method * const *acmp;
190 190
191 __link_set_foreach(acmp, arm_cpu_methods) { 191 __link_set_foreach(acmp, arm_cpu_methods) {
192 if (strcmp(method, (*acmp)->acm_compat) == 0) 192 if (strcmp(method, (*acmp)->acm_compat) == 0)
193 return *acmp; 193 return *acmp;
194 } 194 }
195 195
196 return NULL; 196 return NULL;
197} 197}
198 198
199static struct arm_cpu_method * 199static struct arm_cpu_method *
200arm_fdt_cpu_enable_method(int phandle) 200arm_fdt_cpu_enable_method(int phandle)
201{ 201{
202 const char *method; 202 const char *method;
203 203
204 method = fdtbus_get_string(phandle, "enable-method"); 204 method = fdtbus_get_string(phandle, "enable-method");
205 if (method == NULL) 205 if (method == NULL)
206 return NULL; 206 return NULL;
207 207
208 return arm_fdt_cpu_enable_method_byname(method); 208 return arm_fdt_cpu_enable_method_byname(method);
209} 209}
210 210
211static int 211static int
212arm_fdt_cpu_enable(int phandle, struct arm_cpu_method *acm) 212arm_fdt_cpu_enable(int phandle, struct arm_cpu_method *acm)
213{ 213{
214 return acm->acm_enable(phandle); 214 return acm->acm_enable(phandle);
215} 215}
216#endif 216#endif
217 217
218int 218int
219arm_fdt_cpu_mpstart(void) 219arm_fdt_cpu_mpstart(void)
220{ 220{
221 int ret = 0; 221 int ret = 0;
222#ifdef MULTIPROCESSOR 222#ifdef MULTIPROCESSOR
223 uint64_t mpidr, bp_mpidr; 223 uint64_t mpidr, bp_mpidr;
224 u_int cpuindex, i; 224 u_int cpuindex, i;
225 int child, error; 225 int child, error;
226 struct arm_cpu_method *acm; 226 struct arm_cpu_method *acm;
227 227
228 const int cpus = OF_finddevice("/cpus"); 228 const int cpus = OF_finddevice("/cpus");
229 if (cpus == -1) { 229 if (cpus == -1) {
230 aprint_error("%s: no /cpus node found\n", __func__); 230 aprint_error("%s: no /cpus node found\n", __func__);
231 return 0; 231 return 0;
232 } 232 }
233 233
234 /* MPIDR affinity levels of boot processor. */ 234 /* MPIDR affinity levels of boot processor. */
235 bp_mpidr = cpu_mpidr_aff_read(); 235 bp_mpidr = cpu_mpidr_aff_read();
236 236
237 /* Boot APs */ 237 /* Boot APs */
238 cpuindex = 1; 238 cpuindex = 1;
239 for (child = OF_child(cpus); child; child = OF_peer(child)) { 239 for (child = OF_child(cpus); child; child = OF_peer(child)) {
240 if (!arm_fdt_cpu_okay(child)) 240 if (!arm_fdt_cpu_okay(child))
241 continue; 241 continue;
242 242
243 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) 243 if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0)
244 continue; 244 continue;
245 245
246 if (mpidr == bp_mpidr) 246 if (mpidr == bp_mpidr)
247 continue; /* BP already started */ 247 continue; /* BP already started */
248 248
249 acm = arm_fdt_cpu_enable_method(child); 249 acm = arm_fdt_cpu_enable_method(child);
250 if (acm == NULL) 250 if (acm == NULL)
251 acm = arm_fdt_cpu_enable_method(cpus); 251 acm = arm_fdt_cpu_enable_method(cpus);
252 if (acm == NULL) 252 if (acm == NULL)
253 acm = arm_fdt_cpu_enable_method_byname("psci"); 253 acm = arm_fdt_cpu_enable_method_byname("psci");
254 if (acm == NULL) 254 if (acm == NULL)
255 continue; 255 continue;
256 256
257 error = arm_fdt_cpu_enable(child, acm); 257 error = arm_fdt_cpu_enable(child, acm);
258 if (error != 0) { 258 if (error != 0) {
259 aprint_error("%s: failed to enable CPU %#" PRIx64 "\n", 259 aprint_error("%s: failed to enable CPU %#" PRIx64 "\n",
260 __func__, mpidr); 260 __func__, mpidr);
261 continue; 261 continue;
262 } 262 }
263 263
264 /* Wake up AP in case firmware has placed it in WFE state */ 264 /* Wake up AP in case firmware has placed it in WFE state */
265 sev(); 265 sev();
266 266
267 /* Wait for AP to start */ 267 /* Wait for AP to start */
268 for (i = 0x10000000; i > 0; i--) { 268 for (i = 0x10000000; i > 0; i--) {
269 if (cpu_hatched_p(cpuindex)) 269 if (cpu_hatched_p(cpuindex))
270 break; 270 break;
271 } 271 }
272 272
273 if (i == 0) { 273 if (i == 0) {
274 ret++; 274 ret++;
275 aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex); 275 aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex);
276 } 276 }
277 277
278 cpuindex++; 278 cpuindex++;
279 } 279 }
280#endif /* MULTIPROCESSOR */ 280#endif /* MULTIPROCESSOR */
281 return ret; 281 return ret;
282} 282}
283 283
284static int 284static int
285cpu_enable_nullop(int phandle) 285cpu_enable_nullop(int phandle)
286{ 286{
287 return ENXIO; 287 return ENXIO;
288} 288}
289ARM_CPU_METHOD(default, "", cpu_enable_nullop); 289ARM_CPU_METHOD(default, "", cpu_enable_nullop);
290 290
291#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0 291#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0
292static int 292static int
293cpu_enable_psci(int phandle) 293cpu_enable_psci(int phandle)
294{ 294{
295 static bool psci_probed, psci_p; 295 static bool psci_probed, psci_p;
296 uint64_t mpidr; 296 uint64_t mpidr;
297 int ret; 297 int ret;
298 298
299 if (!psci_probed) { 299 if (!psci_probed) {
300 psci_probed = true; 300 psci_probed = true;
301 psci_p = psci_fdt_preinit() == 0; 301 psci_p = psci_fdt_preinit() == 0;
302 } 302 }
303 if (!psci_p) 303 if (!psci_p)
304 return ENXIO; 304 return ENXIO;
305 305
306 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 306 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
307 307
308#if !defined(AARCH64) 308#if !defined(AARCH64)
309 /* 309 /*
310 * not necessary on AARCH64. beside there it hangs the system 310 * not necessary on AARCH64. beside there it hangs the system
311 * because cache ops are only functional after cpu_attach() 311 * because cache ops are only functional after cpu_attach()
312 * was called. 312 * was called.
313 */ 313 */
314 cpu_dcache_wbinv_all(); 314 cpu_dcache_wbinv_all();
315#endif 315#endif
316 ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0); 316 ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0);
317 if (ret != PSCI_SUCCESS) 317 if (ret != PSCI_SUCCESS)
318 return EIO; 318 return EIO;
319 319
320 return 0; 320 return 0;
321} 321}
322ARM_CPU_METHOD(psci, "psci", cpu_enable_psci); 322ARM_CPU_METHOD(psci, "psci", cpu_enable_psci);
323#endif 323#endif
324 324
325#if defined(MULTIPROCESSOR) && defined(__aarch64__) 325#if defined(MULTIPROCESSOR) && defined(__aarch64__)
326static int 326static int
327spintable_cpu_on(const int phandle, u_int cpuindex, 327spintable_cpu_on(const int phandle, u_int cpuindex,
328 paddr_t entry_point_address, paddr_t cpu_release_addr) 328 paddr_t entry_point_address, paddr_t cpu_release_addr)
329{ 329{
330 /* 330 /*
331 * we need devmap for cpu-release-addr in advance. 331 * we need devmap for cpu-release-addr in advance.
332 * __HAVE_MM_MD_DIRECT_MAPPED_PHYS nor pmap work at this point. 332 * __HAVE_MM_MD_DIRECT_MAPPED_PHYS nor pmap work at this point.
333 */ 333 */
334 if (pmap_devmap_find_pa(cpu_release_addr, sizeof(paddr_t)) == NULL) { 334 if (pmap_devmap_find_pa(cpu_release_addr, sizeof(paddr_t)) == NULL) {
335 aprint_error("%s: devmap for cpu-release-addr" 335 aprint_error("%s: devmap for cpu-release-addr"
336 " 0x%08"PRIxPADDR" required\n", __func__, cpu_release_addr); 336 " 0x%08"PRIxPADDR" required\n", __func__, cpu_release_addr);
337 return -1; 337 return -1;
338 } else { 338 } else {
339 extern struct bus_space arm_generic_bs_tag; 339 extern struct bus_space arm_generic_bs_tag;
340 bus_space_handle_t ioh; 340 bus_space_handle_t ioh;
341 341
342 const int parent = OF_parent(phandle); 342 const int parent = OF_parent(phandle);
343 const int addr_cells = fdtbus_get_addr_cells(parent); 343 const int addr_cells = fdtbus_get_addr_cells(parent);
344 344
345 bus_space_map(&arm_generic_bs_tag, cpu_release_addr, 345 bus_space_map(&arm_generic_bs_tag, cpu_release_addr,
346 sizeof(paddr_t), 0, &ioh); 346 sizeof(paddr_t), 0, &ioh);
347 if (addr_cells == 1) { 347 if (addr_cells == 1) {
348 bus_space_write_4(&arm_generic_bs_tag, ioh, 0, 348 bus_space_write_4(&arm_generic_bs_tag, ioh, 0,
349 entry_point_address); 349 entry_point_address);
350 } else { 350 } else {
351 bus_space_write_8(&arm_generic_bs_tag, ioh, 0, 351 bus_space_write_8(&arm_generic_bs_tag, ioh, 0,
352 entry_point_address); 352 entry_point_address);
353 } 353 }
354 bus_space_unmap(&arm_generic_bs_tag, ioh, sizeof(paddr_t)); 354 bus_space_unmap(&arm_generic_bs_tag, ioh, sizeof(paddr_t));
355 } 355 }
356 356
357 return 0; 357 return 0;
358} 358}
359 359
360static int 360static int
361cpu_enable_spin_table(int phandle) 361cpu_enable_spin_table(int phandle)
362{ 362{
363 uint64_t mpidr, addr; 363 uint64_t mpidr, addr;
364 int ret; 364 int ret;
365 365
366 fdtbus_get_reg64(phandle, 0, &mpidr, NULL); 366 fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
367 367
368 if (of_getprop_uint64(phandle, "cpu-release-addr", &addr) != 0) 368 if (of_getprop_uint64(phandle, "cpu-release-addr", &addr) != 0)
369 return ENXIO; 369 return ENXIO;
370 370
371 ret = spintable_cpu_on(phandle, mpidr, cpu_fdt_mpstart_pa(), 371 ret = spintable_cpu_on(phandle, mpidr, cpu_fdt_mpstart_pa(),
372 (paddr_t)addr); 372 (paddr_t)addr);
373 if (ret != 0) 373 if (ret != 0)
374 return EIO; 374 return EIO;
375 375
376 return 0; 376 return 0;
377} 377}
378ARM_CPU_METHOD(spin_table, "spin-table", cpu_enable_spin_table); 378ARM_CPU_METHOD(spin_table, "spin-table", cpu_enable_spin_table);
379#endif 379#endif