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 */

Reply via email to