* BERI startup conforms to the spin-table start method defined in the * ePAPR 1.0 spec. The initial spin waiting for an address is started * by the CPU firmware. */
| 255 | * by the CPU firmware. |
| 256 | */ |
| 257 | int |
| 258 | platform_start_ap(int cpuid) |
| 259 | { |
| 260 | phandle_t cpu; |
| 261 | char prop[16]; |
| 262 | struct spin_entry *se; |
| 263 | |
| 264 | KASSERT(cpuid != 0, ("%s: can't start CPU 0!\n", __func__)); |
| 265 | KASSERT((cpuid > 0 && cpuid < MAXCPU), |
| 266 | ("%s: invalid CPU id %d", __func__, cpuid)); |
| 267 | |
| 268 | cpu = cpu_of_nodes[cpuid]; |
| 269 | if (OF_getprop(cpu, "status", &prop, sizeof(prop)) <= 0) { |
| 270 | if (bootverbose) |
| 271 | printf("%s: CPU %d has no status property, " |
| 272 | "trying parent\n", __func__, cpuid); |
| 273 | if (OF_getprop(OF_parent(cpu), "status", &prop, |
| 274 | sizeof(prop)) <= 0) |
| 275 | panic("%s: CPU %d has no status property", __func__, |
| 276 | cpuid); |
| 277 | } |
| 278 | if (strcmp("disabled", prop) != 0) |
| 279 | panic("%s: CPU %d status is '%s' not 'disabled'", |
| 280 | __func__, cpuid, prop); |
| 281 | |
| 282 | if (OF_getprop(cpu, "enable-method", &prop, sizeof(prop)) <= 0) { |
| 283 | if (bootverbose) |
| 284 | printf("%s: CPU %d has no enable-method, " |
| 285 | "trying parent\n", __func__, cpuid); |
| 286 | if (OF_getprop(OF_parent(cpu), "enable-method", &prop, |
| 287 | sizeof(prop)) <= 0) |
| 288 | panic("%s: CPU %d has no enable-method property", |
| 289 | __func__, cpuid); |
| 290 | } |
| 291 | if (strcmp("spin-table", prop) != 0) |
| 292 | panic("%s: CPU %d enable-method is '%s' not " |
| 293 | "'spin-table'", __func__, cpuid, prop); |
| 294 | |
| 295 | if (OF_getprop(cpu, "cpu-release-addr", &se, sizeof(se)) <= 0) |
| 296 | panic("%s: CPU %d has missing or invalid cpu-release-addr", |
| 297 | __func__, cpuid); |
| 298 | se->pir = cpuid; |
| 299 | if (bootverbose) |
| 300 | printf("%s: writing %p to %p\n", __func__, mpentry, |
| 301 | &se->entry_addr); |
| 302 | |
| 303 | mips_sync(); /* Ordering. */ |
| 304 | se->entry_addr = (intptr_t)mpentry; |
| 305 | mips_sync(); /* Liveness. */ |
| 306 | |
| 307 | return (0); |
| 308 | } |