Module Name: src Committed By: ryo Date: Mon Sep 10 11:05:12 UTC 2018
Modified Files: src/sys/arch/aarch64/aarch64: cpu.c locore.S pmap.c src/sys/arch/aarch64/include: cpu.h src/sys/arch/arm/broadcom: bcm2835reg.h bcm283x_platform.c bcm283x_platform.h src/sys/arch/arm/fdt: arm_fdtvar.h cpu_fdt.c files.fdt psci_fdt.c src/sys/arch/arm/nvidia: tegra_platform.c src/sys/arch/arm/rockchip: rk_platform.c src/sys/arch/arm/sunxi: sunxi_platform.c src/sys/arch/arm/virt: virt_platform.c Added Files: src/sys/arch/arm/fdt: psci_fdtvar.h Removed Files: src/sys/arch/arm/fdt: psci_fdt.h Log Message: cleanup aarch64 mpstart and fdt bootstrap * arm_cpu_hatch_arg is a bad idea. avoid serializing CPU startup, and eliminate arm_cpu_hatch_arg. in mpstart, resolve own cpu index using array of cpu_mpidr[] (aarch64) * add support fdt enable-method "spin-table" * add support fdt enable-method "brcm,bcm2836-smp" (for 32bit RaspberryPi) * use arm_fdt_cpu_bootstrap() instead of psci_fdt_bootstrap() * rename "arm/fdt/psci_fdt.h" to "arm/fdt/psci_fdtvar.h" because of conflict of include file for needs-flag * add devmap for cpu spin-table of raspberrypi3/aarch64 * no need to force hatch APs for raspberrypi3/arm32 ifndef MULTIPROCESSOR. * fix to work pmap_extract(kerneltext/data/bss) even if before calling pmap_bootstrap idea to use cpu_mpidr[] by jmcneill@. reviewd by skrll@. thanks. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/aarch64/cpu.c cvs rdiff -u -r1.24 -r1.25 src/sys/arch/aarch64/aarch64/locore.S cvs rdiff -u -r1.20 -r1.21 src/sys/arch/aarch64/aarch64/pmap.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/aarch64/include/cpu.h cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/broadcom/bcm2835reg.h cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/broadcom/bcm283x_platform.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/broadcom/bcm283x_platform.h cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/fdt/arm_fdtvar.h cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/fdt/cpu_fdt.c cvs rdiff -u -r1.24 -r1.25 src/sys/arch/arm/fdt/files.fdt cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/fdt/psci_fdt.c cvs rdiff -u -r1.2 -r0 src/sys/arch/arm/fdt/psci_fdt.h cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/fdt/psci_fdtvar.h cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/nvidia/tegra_platform.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/rockchip/rk_platform.c cvs rdiff -u -r1.25 -r1.26 src/sys/arch/arm/sunxi/sunxi_platform.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/virt/virt_platform.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/aarch64/aarch64/cpu.c diff -u src/sys/arch/aarch64/aarch64/cpu.c:1.6 src/sys/arch/aarch64/aarch64/cpu.c:1.7 --- src/sys/arch/aarch64/aarch64/cpu.c:1.6 Sun Aug 26 18:15:49 2018 +++ src/sys/arch/aarch64/aarch64/cpu.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.6 2018/08/26 18:15:49 ryo Exp $ */ +/* $NetBSD: cpu.c,v 1.7 2018/09/10 11:05:12 ryo Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.6 2018/08/26 18:15:49 ryo Exp $"); +__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.7 2018/09/10 11:05:12 ryo Exp $"); #include "locators.h" #include "opt_arm_debug.h" @@ -63,8 +63,9 @@ static void cpu_identify1(device_t self, static void cpu_identify2(device_t self, struct cpu_info *); #ifdef MULTIPROCESSOR +uint64_t cpu_mpidr[MAXCPUS]; + volatile u_int arm_cpu_hatched __cacheline_aligned = 0; -volatile u_int arm_cpu_hatch_arg __cacheline_aligned; volatile uint32_t arm_cpu_mbox __cacheline_aligned = 0; u_int arm_cpu_max = 1; Index: src/sys/arch/aarch64/aarch64/locore.S diff -u src/sys/arch/aarch64/aarch64/locore.S:1.24 src/sys/arch/aarch64/aarch64/locore.S:1.25 --- src/sys/arch/aarch64/aarch64/locore.S:1.24 Mon Sep 10 07:30:33 2018 +++ src/sys/arch/aarch64/aarch64/locore.S Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.24 2018/09/10 07:30:33 skrll Exp $ */ +/* $NetBSD: locore.S,v 1.25 2018/09/10 11:05:12 ryo Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org> @@ -35,7 +35,7 @@ #include <aarch64/hypervisor.h> #include "assym.h" -RCSID("$NetBSD: locore.S,v 1.24 2018/09/10 07:30:33 skrll Exp $") +RCSID("$NetBSD: locore.S,v 1.25 2018/09/10 11:05:12 ryo Exp $") /* #define DEBUG_LOCORE */ /* #define DEBUG_MMU */ @@ -299,14 +299,26 @@ END(printcpu) ENTRY_NP(aarch64_mpstart) ENTRY_NP(cortex_mpstart) /* compat arm */ - ADDR x0, arm_cpu_hatch_arg /* from cpu0 */ - ldr w27, [x0] /* x27 = cpuindex */ + mrs x3, mpidr_el1 + ldr x0, =(MPIDR_AFF0|MPIDR_AFF1|MPIDR_AFF2|MPIDR_AFF3) + and x3, x3, x0 + + ADDR x0, cpu_mpidr + mov x1, xzr +1: + add x1, x1, #1 + cmp x1, MAXCPUS /* cpuindex >= MAXCPUS ? */ + bge toomanycpus + ldr x2, [x0, x1, lsl #3] /* cpu_mpidr[cpunidex] */ + cmp x2, x3 /* == mpidr_el1 & MPIDR_AFF ? */ + bne 1b + + mov x27, x1 /* x27 = cpuindex */ + mov x0, #1 lsl x28, x0, x27 /* x28 = 1 << cpuindex */ /* x27 = cpuindex, x28 = (1 << cpuindex) */ - cmp x27, MAXCPUS - bge toomanycpus /* set stack pointer for boot */ #define BOOT_STACKSIZE 256 @@ -477,7 +489,7 @@ END(aarch64_mpstart) toomanycpus: PRINTCPU() - PRINT("too many cpus\r\n") + PRINT("too many cpus, or MPIDR not exists in cpu_mpidr[]\r\n") 1: wfi b 1b Index: src/sys/arch/aarch64/aarch64/pmap.c diff -u src/sys/arch/aarch64/aarch64/pmap.c:1.20 src/sys/arch/aarch64/aarch64/pmap.c:1.21 --- src/sys/arch/aarch64/aarch64/pmap.c:1.20 Mon Aug 27 15:43:37 2018 +++ src/sys/arch/aarch64/aarch64/pmap.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.20 2018/08/27 15:43:37 ryo Exp $ */ +/* $NetBSD: pmap.c,v 1.21 2018/09/10 11:05:12 ryo Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.20 2018/08/27 15:43:37 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.21 2018/09/10 11:05:12 ryo Exp $"); #include "opt_arm_debug.h" #include "opt_ddb.h" @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.2 #include <aarch64/pte.h> #include <aarch64/armreg.h> #include <aarch64/cpufunc.h> +#include <aarch64/machdep.h> //#define PMAP_DEBUG //#define PMAP_PV_DEBUG @@ -683,7 +684,12 @@ pmap_extract(struct pmap *pm, vaddr_t va return false; #endif - if (AARCH64_KSEG_START <= va && va < AARCH64_KSEG_END) { + extern char __kernel_text[]; + extern char _end[]; + if ((vaddr_t)__kernel_text <= va && va < (vaddr_t)_end) { + pa = KERN_VTOPHYS(va); + found = true; + } else if (AARCH64_KSEG_START <= va && va < AARCH64_KSEG_END) { pa = AARCH64_KVA_TO_PA(va); found = true; } else { Index: src/sys/arch/aarch64/include/cpu.h diff -u src/sys/arch/aarch64/include/cpu.h:1.7 src/sys/arch/aarch64/include/cpu.h:1.8 --- src/sys/arch/aarch64/include/cpu.h:1.7 Sun Aug 26 18:15:49 2018 +++ src/sys/arch/aarch64/include/cpu.h Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.7 2018/08/26 18:15:49 ryo Exp $ */ +/* $NetBSD: cpu.h,v 1.8 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -111,7 +111,7 @@ void cpu_hatch(struct cpu_info *); extern struct cpu_info *cpu_info[]; extern volatile u_int arm_cpu_hatched; /* MULTIPROCESSOR */ -extern volatile u_int arm_cpu_hatch_arg;/* MULTIPROCESSOR */ +extern uint64_t cpu_mpidr[]; /* MULTIPROCESSOR */ #define CPU_INFO_ITERATOR cpuid_t #ifdef MULTIPROCESSOR Index: src/sys/arch/arm/broadcom/bcm2835reg.h diff -u src/sys/arch/arm/broadcom/bcm2835reg.h:1.22 src/sys/arch/arm/broadcom/bcm2835reg.h:1.23 --- src/sys/arch/arm/broadcom/bcm2835reg.h:1.22 Sun Apr 1 04:35:03 2018 +++ src/sys/arch/arm/broadcom/bcm2835reg.h Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835reg.h,v 1.22 2018/04/01 04:35:03 ryo Exp $ */ +/* $NetBSD: bcm2835reg.h,v 1.23 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -245,4 +245,7 @@ #define BCM2836_LOCAL_MAILBOX2_CLRN(n) (0xc8 + 0x10 * (n)) #define BCM2836_LOCAL_MAILBOX3_CLRN(n) (0xcc + 0x10 * (n)) +#define BCM2836_ARM_SMP_BASE 0x00000000 +#define BCM2836_ARM_SMP_SIZE 0x00001000 /* 4KBytes */ + #endif /* _BCM2835REG_H_ */ Index: src/sys/arch/arm/broadcom/bcm283x_platform.c diff -u src/sys/arch/arm/broadcom/bcm283x_platform.c:1.17 src/sys/arch/arm/broadcom/bcm283x_platform.c:1.18 --- src/sys/arch/arm/broadcom/bcm283x_platform.c:1.17 Mon Sep 3 16:29:23 2018 +++ src/sys/arch/arm/broadcom/bcm283x_platform.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm283x_platform.c,v 1.17 2018/09/03 16:29:23 riastradh Exp $ */ +/* $NetBSD: bcm283x_platform.c,v 1.18 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.17 2018/09/03 16:29:23 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.18 2018/09/10 11:05:12 ryo Exp $"); #include "opt_arm_debug.h" #include "opt_bcm283x.h" @@ -253,7 +253,11 @@ bcm2836_platform_devmap(void) DEVMAP_ENTRY(BCM2836_ARM_LOCAL_VBASE, BCM2836_ARM_LOCAL_BASE, BCM2836_ARM_LOCAL_SIZE), - +#if defined(MULTIPROCESSOR) && defined(__aarch64__) + /* for fdt cpu spin-table */ + DEVMAP_ENTRY(BCM2836_ARM_SMP_VBASE, BCM2836_ARM_SMP_BASE, + BCM2836_ARM_SMP_SIZE), +#endif DEVMAP_ENTRY_END }; @@ -720,7 +724,8 @@ bcm2836_bootparams(void) static void bcm2836_bootstrap(void) { -#define RPI_CPU_MAX 4 +#ifdef MULTIPROCESSOR +#ifdef __arm__ #ifdef VERBOSE_INIT_ARM #define DPRINTF(...) printf(__VA_ARGS__) @@ -728,97 +733,56 @@ bcm2836_bootstrap(void) #define DPRINTF(...) #endif -#ifdef MULTIPROCESSOR - arm_cpu_max = RPI_CPU_MAX; - DPRINTF("%s: %d cpus present\n", __func__, arm_cpu_max); -#ifdef __arm__ - extern int cortex_mmuinfo; - cortex_mmuinfo = armreg_ttbr_read(); - DPRINTF("%s: cortex_mmuinfo %x\n", __func__, cortex_mmuinfo); -#endif -#endif /* MULTIPROCESSOR */ +#define RPI_CPU_MAX 4 - /* - * XXX: TODO: - * should make cpu_fdt_bootstrap() that support spin-table and use it - * to share with arm/aarch64. - */ -#ifdef __aarch64__ - extern void aarch64_mpstart(void); - for (int i = 1; i < RPI_CPU_MAX; i++) { - /* argument for mpstart() */ - arm_cpu_hatch_arg = i; - cpu_dcache_wb_range((vaddr_t)&arm_cpu_hatch_arg, - sizeof(arm_cpu_hatch_arg)); - - /* - * Reference: - * armstubs/armstub8.S - * in https://github.com/raspberrypi/tools - */ - volatile uint64_t *cpu_release_addr; -#define RPI3_ARMSTUB8_SPINADDR_BASE 0x000000d8 - cpu_release_addr = (void *) - AARCH64_PA_TO_KVA(RPI3_ARMSTUB8_SPINADDR_BASE + i * 8); - *cpu_release_addr = - aarch64_kern_vtophys((vaddr_t)aarch64_mpstart); - - /* need flush cache. secondary processors are cache disabled */ - cpu_dcache_wb_range((vaddr_t)cpu_release_addr, - sizeof(cpu_release_addr)); - /* Wake up AP in case firmware has placed it in WFE state */ - __asm __volatile("sev" ::: "memory"); + const char *method; - /* Wait for APs to start */ - for (int loop = 0; loop < 16; loop++) { - membar_consumer(); - if (arm_cpu_hatched & __BIT(i)) - break; - gtmr_delay(10000); - } + const int cpus = OF_finddevice("/cpus"); + if (cpus == -1) { + aprint_error("%s: no /cpus node found\n", __func__); + arm_cpu_max = 1; + return; } -#endif /* __aarch64__ */ -#ifdef __arm__ - /* - * Even if no options MULTIPROCESSOR, - * It is need to initialize the secondary CPU, - * and go into wfi loop (cortex_mpstart), - * otherwise system would be freeze... - * (because netbsd will use the spinning address) - */ - extern void cortex_mpstart(void); + /* implementation dependent string "brcm,bcm2836-smp" for ARM 32-bit */ + method = fdtbus_get_string(cpus, "enable-method"); + if ((method != NULL) && (strcmp(method, "brcm,bcm2836-smp") == 0)) { + arm_cpu_max = RPI_CPU_MAX; + DPRINTF("%s: %d cpus present\n", __func__, arm_cpu_max); + + extern void cortex_mpstart(void); + + for (size_t i = 1; i < RPI_CPU_MAX; i++) { + bus_space_tag_t iot = &bcm2836_bs_tag; + bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE; + + bus_space_write_4(iot, ioh, + BCM2836_LOCAL_MAILBOX3_SETN(i), + (uint32_t)cortex_mpstart); + } - for (size_t i = 1; i < RPI_CPU_MAX; i++) { - bus_space_tag_t iot = &bcm2836_bs_tag; - bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE; - - bus_space_write_4(iot, ioh, - BCM2836_LOCAL_MAILBOX3_SETN(i), - (uint32_t)cortex_mpstart); /* Wake up AP in case firmware has placed it in WFE state */ __asm __volatile("sev" ::: "memory"); -#ifdef MULTIPROCESSOR - /* Wait for APs to start */ for (int loop = 0; loop < 16; loop++) { - membar_consumer(); - if (arm_cpu_hatched & __BIT(i)) + if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1)) break; gtmr_delay(10000); } -#endif - } -#endif -#ifdef MULTIPROCESSOR - for (size_t i = 1; i < arm_cpu_max; i++) { - if ((arm_cpu_hatched & (1 << i)) == 0) { - printf("%s: warning: cpu%zu failed to hatch\n", - __func__, i); + for (size_t i = 1; i < arm_cpu_max; i++) { + if ((arm_cpu_hatched & (1 << i)) == 0) { + printf("%s: warning: cpu%zu failed to hatch\n", + __func__, i); + } } + return; } -#endif +#endif /* __arm__ */ + + /* try enable-method each cpus */ + arm_fdt_cpu_bootstrap(); +#endif /* MULTIPROCESSOR */ } #endif /* SOC_BCM2836 */ Index: src/sys/arch/arm/broadcom/bcm283x_platform.h diff -u src/sys/arch/arm/broadcom/bcm283x_platform.h:1.1 src/sys/arch/arm/broadcom/bcm283x_platform.h:1.2 --- src/sys/arch/arm/broadcom/bcm283x_platform.h:1.1 Sun Apr 1 04:35:03 2018 +++ src/sys/arch/arm/broadcom/bcm283x_platform.h Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm283x_platform.h,v 1.1 2018/04/01 04:35:03 ryo Exp $ */ +/* $NetBSD: bcm283x_platform.h,v 1.2 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -46,4 +46,7 @@ #define BCM2836_ARM_LOCAL_VBASE \ BCM2835_IOPHYSTOVIRT(BCM2836_ARM_LOCAL_BASE) +#define BCM2836_ARM_SMP_VBASE \ + BCM2835_IOPHYSTOVIRT(BCM2836_ARM_SMP_BASE) + #endif /* _ARM_BCM2835REG_PLATFORM_H_ */ Index: src/sys/arch/arm/fdt/arm_fdtvar.h diff -u src/sys/arch/arm/fdt/arm_fdtvar.h:1.8 src/sys/arch/arm/fdt/arm_fdtvar.h:1.9 --- src/sys/arch/arm/fdt/arm_fdtvar.h:1.8 Sun Aug 5 14:02:35 2018 +++ src/sys/arch/arm/fdt/arm_fdtvar.h Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: arm_fdtvar.h,v 1.8 2018/08/05 14:02:35 skrll Exp $ */ +/* $NetBSD: arm_fdtvar.h,v 1.9 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca> @@ -65,6 +65,7 @@ TAILQ_HEAD(arm_platlist, arm_platform_in const struct arm_platform * arm_fdt_platform(void); +void arm_fdt_cpu_bootstrap(void); void arm_fdt_cpu_hatch_register(void *, void (*)(void *, struct cpu_info *)); void arm_fdt_cpu_hatch(struct cpu_info *); Index: src/sys/arch/arm/fdt/cpu_fdt.c diff -u src/sys/arch/arm/fdt/cpu_fdt.c:1.11 src/sys/arch/arm/fdt/cpu_fdt.c:1.12 --- src/sys/arch/arm/fdt/cpu_fdt.c:1.11 Sun Sep 9 13:22:50 2018 +++ src/sys/arch/arm/fdt/cpu_fdt.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu_fdt.c,v 1.11 2018/09/09 13:22:50 jmcneill Exp $ */ +/* $NetBSD: cpu_fdt.c,v 1.12 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -26,10 +26,14 @@ * SUCH DAMAGE. */ +#include "opt_multiprocessor.h" +#include "psci_fdt.h" + #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.11 2018/09/09 13:22:50 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.12 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> +#include <sys/atomic.h> #include <sys/bus.h> #include <sys/device.h> #include <sys/lwp.h> @@ -41,6 +45,13 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v #include <arm/armreg.h> #include <arm/cpu.h> #include <arm/cpufunc.h> +#include <arm/locore.h> + +#include <arm/arm/psci.h> +#include <arm/fdt/arm_fdtvar.h> +#include <arm/fdt/psci_fdtvar.h> + +#include <uvm/uvm_extern.h> static int cpu_fdt_match(device_t, cfdata_t, void *); static void cpu_fdt_attach(device_t, device_t, void *); @@ -154,3 +165,142 @@ cpu_fdt_attach(device_t parent, device_t /* Attach CPU frequency scaling provider */ config_found(self, faa, NULL); } + +#ifdef MULTIPROCESSOR +static register_t +cpu_fdt_mpstart_pa(void) +{ +#ifdef __aarch64__ + extern void aarch64_mpstart(void); + return (register_t)aarch64_kern_vtophys((vaddr_t)aarch64_mpstart); +#else + extern void cortex_mpstart(void); + return (register_t)cortex_mpstart; +#endif +} + +static int +spintable_cpu_on(u_int cpuindex, paddr_t entry_point_address, paddr_t cpu_release_addr) +{ + /* + * we need devmap for cpu-release-addr in advance. + * __HAVE_MM_MD_DIRECT_MAPPED_PHYS nor pmap didn't work at this point. + */ + if (pmap_devmap_find_pa(cpu_release_addr, sizeof(paddr_t)) == NULL) { + aprint_error("%s: devmap for cpu-release-addr" + " 0x%08"PRIxPADDR" required\n", __func__, cpu_release_addr); + return -1; + } else { + extern struct bus_space arm_generic_bs_tag; + bus_space_handle_t ioh; + + bus_space_map(&arm_generic_bs_tag, cpu_release_addr, + sizeof(paddr_t), 0, &ioh); + bus_space_write_4(&arm_generic_bs_tag, ioh, 0, + entry_point_address); + bus_space_unmap(&arm_generic_bs_tag, ioh, sizeof(paddr_t)); + } + + return 0; +} +#endif /* MULTIPROCESSOR */ + + +void +arm_fdt_cpu_bootstrap(void) +{ +#ifdef MULTIPROCESSOR + uint64_t mpidr, bp_mpidr; + u_int cpuindex; + int child, ret; + const char *devtype, *method; + + const int cpus = OF_finddevice("/cpus"); + if (cpus == -1) { + aprint_error("%s: no /cpus node found\n", __func__); + arm_cpu_max = 1; + return; + } + + /* Count CPUs */ + arm_cpu_max = 0; + for (child = OF_child(cpus); child; child = OF_peer(child)) + if (fdtbus_status_okay(child) && ((devtype = + fdtbus_get_string(child, "device_type")) != NULL) && + (strcmp(devtype, "cpu") == 0)) + arm_cpu_max++; + +#if NPSCI_FDT > 0 + if (psci_fdt_preinit() != 0) + return; +#endif + + /* MPIDR affinity levels of boot processor. */ + bp_mpidr = cpu_mpidr_aff_read(); + + /* Boot APs */ + uint32_t started = 0; + cpuindex = 1; + for (child = OF_child(cpus); child; child = OF_peer(child)) { + if (!fdtbus_status_okay(child)) + continue; + if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) + continue; + if (mpidr == bp_mpidr) + continue; /* BP already started */ + +#ifdef __arm__ + /* XXX NetBSD/arm requires all CPUs to be in the same cluster */ + if ((mpidr & ~MPIDR_AFF0) != (bp_mpidr & ~MPIDR_AFF0)) + continue; +#endif + +#ifdef __aarch64__ + KASSERT(cpuindex < MAXCPUS); + cpu_mpidr[cpuindex] = mpidr; + cpu_dcache_wb_range((vaddr_t)&cpu_mpidr[cpuindex], sizeof(cpu_mpidr[cpuindex])); +#endif + + method = fdtbus_get_string(child, "enable-method"); + if (method == NULL) + continue; + + if (strcmp(method, "spin-table") == 0) { + uint64_t data; + paddr_t cpu_release_addr; + + if (OF_getprop(child, "cpu-release-addr", &data, + sizeof(data)) != sizeof(data)) + continue; + + cpu_release_addr = (paddr_t)be64toh(data); + ret = spintable_cpu_on(mpidr, cpu_fdt_mpstart_pa(), cpu_release_addr); + if (ret != 0) + continue; + +#if NPSCI_FDT > 0 + } else if (strcmp(method, "psci") == 0) { + ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0); + if (ret != PSCI_SUCCESS) + continue; +#endif + } else { + aprint_error("%s: %s: unsupported method\n", __func__, method); + continue; + } + + started |= __BIT(cpuindex); + cpuindex++; + } + + /* Wake up AP in case firmware has placed it in WFE state */ + __asm __volatile("sev" ::: "memory"); + + /* Wait for APs to start */ + for (u_int i = 0x10000000; i > 0; i--) { + membar_consumer(); + if (arm_cpu_hatched == started) + break; + } +#endif /* MULTIPROCESSOR */ +} Index: src/sys/arch/arm/fdt/files.fdt diff -u src/sys/arch/arm/fdt/files.fdt:1.24 src/sys/arch/arm/fdt/files.fdt:1.25 --- src/sys/arch/arm/fdt/files.fdt:1.24 Sat Sep 8 00:40:57 2018 +++ src/sys/arch/arm/fdt/files.fdt Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -# $NetBSD: files.fdt,v 1.24 2018/09/08 00:40:57 jmcneill Exp $ +# $NetBSD: files.fdt,v 1.25 2018/09/10 11:05:12 ryo Exp $ include "dev/pckbport/files.pckbport" @@ -51,7 +51,7 @@ attach plrtc at fdt with plrtc_fdt file arch/arm/fdt/plrtc_fdt.c plrtc_fdt attach psci at fdt with psci_fdt -file arch/arm/fdt/psci_fdt.c psci_fdt +file arch/arm/fdt/psci_fdt.c psci_fdt needs-flag # Generic PCI host controller device pcihost: pcibus Index: src/sys/arch/arm/fdt/psci_fdt.c diff -u src/sys/arch/arm/fdt/psci_fdt.c:1.17 src/sys/arch/arm/fdt/psci_fdt.c:1.18 --- src/sys/arch/arm/fdt/psci_fdt.c:1.17 Sun Sep 9 21:16:05 2018 +++ src/sys/arch/arm/fdt/psci_fdt.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: psci_fdt.c,v 1.17 2018/09/09 21:16:05 jmcneill Exp $ */ +/* $NetBSD: psci_fdt.c,v 1.18 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: psci_fdt.c,v 1.17 2018/09/09 21:16:05 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: psci_fdt.c,v 1.18 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -40,12 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: psci_fdt.c,v #include <dev/fdt/fdtvar.h> -#include <arm/locore.h> -#include <arm/armreg.h> -#include <arm/cpufunc.h> - #include <arm/arm/psci.h> -#include <arm/fdt/psci_fdt.h> +#include <arm/fdt/psci_fdtvar.h> static int psci_fdt_match(device_t, cfdata_t, void *); static void psci_fdt_attach(device_t, device_t, void *); @@ -142,7 +138,7 @@ psci_fdt_init(const int phandle) return 0; } -static int +int psci_fdt_preinit(void) { const int phandle = OF_finddevice("/psci"); @@ -154,105 +150,6 @@ psci_fdt_preinit(void) return psci_fdt_init(phandle); } -#ifdef MULTIPROCESSOR - -static register_t -psci_fdt_mpstart_pa(void) -{ -#ifdef __aarch64__ - extern void aarch64_mpstart(void); - return (register_t)aarch64_kern_vtophys((vaddr_t)aarch64_mpstart); -#else - extern void cortex_mpstart(void); - return (register_t)cortex_mpstart; -#endif -} -#endif - -static bool -psci_fdt_cpu_okay(const int child) -{ - const char *s; - - s = fdtbus_get_string(child, "device_type"); - if (!s || strcmp(s, "cpu") != 0) - return false; - - s = fdtbus_get_string(child, "status"); - if (s) { - if (strcmp(s, "okay") == 0) - return false; - if (strcmp(s, "disabled") == 0) - return of_hasprop(child, "enable-method"); - return false; - } else { - return true; - } -} - -void -psci_fdt_bootstrap(void) -{ -#ifdef MULTIPROCESSOR - uint64_t mpidr, bp_mpidr; - u_int cpuindex; - int child; - const char *devtype; - - const int cpus = OF_finddevice("/cpus"); - if (cpus == -1) { - aprint_error("PSCI: no /cpus node found\n"); - arm_cpu_max = 1; - return; - } - - /* Count CPUs */ - arm_cpu_max = 0; - for (child = OF_child(cpus); child; child = OF_peer(child)) - if (fdtbus_status_okay(child) && ((devtype = - fdtbus_get_string(child, "device_type")) != NULL) && - (strcmp(devtype, "cpu") == 0)) - arm_cpu_max++; - - if (psci_fdt_preinit() != 0) - return; - - /* MPIDR affinity levels of boot processor. */ - bp_mpidr = cpu_mpidr_aff_read(); - - /* Boot APs */ - cpuindex = 1; - for (child = OF_child(cpus); child; child = OF_peer(child)) { - if (!psci_fdt_cpu_okay(child)) - continue; - if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0) - continue; - if (mpidr == bp_mpidr) - continue; /* BP already started */ - -#ifdef __aarch64__ - /* argument for mpstart() */ - arm_cpu_hatch_arg = cpuindex; - cpu_dcache_wb_range((vaddr_t)&arm_cpu_hatch_arg, - sizeof(arm_cpu_hatch_arg)); -#endif - - int ret = psci_cpu_on(mpidr, psci_fdt_mpstart_pa(), 0); - if (ret != PSCI_SUCCESS) - continue; - - /* Wait for APs to start */ - for (u_int i = 0x4000000; i > 0; i--) { - membar_consumer(); - if (arm_cpu_hatched & __BIT(cpuindex)) - break; - } - - cpuindex++; - } -#endif -} - void psci_fdt_reset(void) { Index: src/sys/arch/arm/nvidia/tegra_platform.c diff -u src/sys/arch/arm/nvidia/tegra_platform.c:1.14 src/sys/arch/arm/nvidia/tegra_platform.c:1.15 --- src/sys/arch/arm/nvidia/tegra_platform.c:1.14 Sun Aug 5 14:02:35 2018 +++ src/sys/arch/arm/nvidia/tegra_platform.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_platform.c,v 1.14 2018/08/05 14:02:35 skrll Exp $ */ +/* $NetBSD: tegra_platform.c,v 1.15 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca> @@ -33,7 +33,7 @@ #include "ukbd.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.14 2018/08/05 14:02:35 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.15 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -55,7 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_platfo #include <arm/fdt/arm_fdtvar.h> #include <arm/arm/psci.h> -#include <arm/fdt/psci_fdt.h> +#include <arm/fdt/psci_fdtvar.h> #if NUKBD > 0 #include <dev/usb/ukbdvar.h> @@ -109,7 +109,7 @@ tegra210_platform_bootstrap(void) tegra_bootstrap(); #if defined(MULTIPROCESSOR) && defined(__aarch64__) - psci_fdt_bootstrap(); + arm_fdt_cpu_bootstrap(); #endif } #endif Index: src/sys/arch/arm/rockchip/rk_platform.c diff -u src/sys/arch/arm/rockchip/rk_platform.c:1.3 src/sys/arch/arm/rockchip/rk_platform.c:1.4 --- src/sys/arch/arm/rockchip/rk_platform.c:1.3 Sun Aug 12 16:48:05 2018 +++ src/sys/arch/arm/rockchip/rk_platform.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: rk_platform.c,v 1.3 2018/08/12 16:48:05 jmcneill Exp $ */ +/* $NetBSD: rk_platform.c,v 1.4 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_fdt_arm.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.3 2018/08/12 16:48:05 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.4 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -53,7 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: rk_platform. #include <dev/ic/comreg.h> #include <arm/arm/psci.h> -#include <arm/fdt/psci_fdt.h> +#include <arm/fdt/psci_fdtvar.h> #include <libfdt.h> @@ -79,7 +79,7 @@ rk_platform_bootstrap(void) { void *fdt_data = __UNCONST(fdtbus_get_data()); - psci_fdt_bootstrap(); + arm_fdt_cpu_bootstrap(); const int chosen_off = fdt_path_offset(fdt_data, "/chosen"); if (chosen_off < 0) Index: src/sys/arch/arm/sunxi/sunxi_platform.c diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.25 src/sys/arch/arm/sunxi/sunxi_platform.c:1.26 --- src/sys/arch/arm/sunxi/sunxi_platform.c:1.25 Sun Aug 5 14:02:35 2018 +++ src/sys/arch/arm/sunxi/sunxi_platform.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_platform.c,v 1.25 2018/08/05 14:02:35 skrll Exp $ */ +/* $NetBSD: sunxi_platform.c,v 1.26 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_fdt_arm.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.25 2018/08/05 14:02:35 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.26 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -54,7 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_platfo #include <dev/ic/comreg.h> #include <arm/arm/psci.h> -#include <arm/fdt/psci_fdt.h> +#include <arm/fdt/psci_fdtvar.h> #include <arm/sunxi/sunxi_platform.h> @@ -201,7 +201,7 @@ sunxi_platform_bootstrap(void) static void sunxi_platform_psci_bootstrap(void) { - psci_fdt_bootstrap(); + arm_fdt_cpu_bootstrap(); sunxi_platform_bootstrap(); } Index: src/sys/arch/arm/virt/virt_platform.c diff -u src/sys/arch/arm/virt/virt_platform.c:1.5 src/sys/arch/arm/virt/virt_platform.c:1.6 --- src/sys/arch/arm/virt/virt_platform.c:1.5 Sun Aug 5 14:02:35 2018 +++ src/sys/arch/arm/virt/virt_platform.c Mon Sep 10 11:05:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: virt_platform.c,v 1.5 2018/08/05 14:02:35 skrll Exp $ */ +/* $NetBSD: virt_platform.c,v 1.6 2018/09/10 11:05:12 ryo Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_fdt_arm.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: virt_platform.c,v 1.5 2018/08/05 14:02:35 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: virt_platform.c,v 1.6 2018/09/10 11:05:12 ryo Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -57,7 +57,7 @@ __KERNEL_RCSID(0, "$NetBSD: virt_platfor #include <arm/cortex/gtmr_var.h> #include <arm/arm/psci.h> -#include <arm/fdt/psci_fdt.h> +#include <arm/fdt/psci_fdtvar.h> #include <arm/virt/virt_platform.h> @@ -120,7 +120,7 @@ virt_platform_uart_freq(void) static const struct arm_platform virt_platform = { .ap_devmap = virt_platform_devmap, - .ap_bootstrap = psci_fdt_bootstrap, + .ap_bootstrap = arm_fdt_cpu_bootstrap, .ap_init_attach_args = virt_platform_init_attach_args, .ap_early_putchar = virt_platform_early_putchar, .ap_device_register = virt_platform_device_register, Added files: Index: src/sys/arch/arm/fdt/psci_fdtvar.h diff -u /dev/null src/sys/arch/arm/fdt/psci_fdtvar.h:1.1 --- /dev/null Mon Sep 10 11:05:12 2018 +++ src/sys/arch/arm/fdt/psci_fdtvar.h Mon Sep 10 11:05:12 2018 @@ -0,0 +1,37 @@ +/* $NetBSD: psci_fdtvar.h,v 1.1 2018/09/10 11:05:12 ryo Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM_PSCI_FDTVAR_H +#define _ARM_PSCI_FDTVAR_H + +int psci_fdt_preinit(void); + +/* Board reset */ +void psci_fdt_reset(void); + +#endif /* !_ARM_PSCI_FDTVAR_H */