Module Name:    src
Committed By:   jmcneill
Date:           Thu Jan  3 12:52:40 UTC 2019

Modified Files:
        src/sys/arch/arm/broadcom: bcm283x_platform.c
        src/sys/arch/arm/fdt: arm_fdtvar.h cpu_fdt.c
        src/sys/arch/arm/nvidia: tegra_platform.c
        src/sys/arch/arm/sunxi: sunxi_mc_smp.c sunxi_platform.c

Log Message:
Add a link set for cpu enable methods.


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/broadcom/bcm283x_platform.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/fdt/arm_fdtvar.h
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/fdt/cpu_fdt.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/nvidia/tegra_platform.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_mc_smp.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/arm/sunxi/sunxi_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/arm/broadcom/bcm283x_platform.c
diff -u src/sys/arch/arm/broadcom/bcm283x_platform.c:1.22 src/sys/arch/arm/broadcom/bcm283x_platform.c:1.23
--- src/sys/arch/arm/broadcom/bcm283x_platform.c:1.22	Tue Oct 30 16:41:52 2018
+++ src/sys/arch/arm/broadcom/bcm283x_platform.c	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm283x_platform.c,v 1.22 2018/10/30 16:41:52 skrll Exp $	*/
+/*	$NetBSD: bcm283x_platform.c,v 1.23 2019/01/03 12:52:40 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <[email protected]>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.22 2018/10/30 16:41:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.23 2019/01/03 12:52:40 jmcneill Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_bcm283x.h"
@@ -724,60 +724,25 @@ bcm2836_bootparams(void)
 	bcm283x_bootparams(iot, ioh);
 }
 
-static void
-bcm2836_mpstart(void)
+#if defined(MULTIPROCESSOR)
+static int
+cpu_enable_bcm2836(int phandle)
 {
-#ifdef MULTIPROCESSOR
-#ifdef __arm__
-	/* implementation dependent string "brcm,bcm2836-smp" for ARM 32-bit */
-	const char *method;
-
-	const int cpus = OF_finddevice("/cpus");
-	if (cpus == -1) {
-		aprint_error("%s: no /cpus node found\n", __func__);
-		arm_cpu_max = 1;
-		return;
-	}
-
-	method = fdtbus_get_string(cpus, "enable-method");
-	if ((method != NULL) && (strcmp(method, "brcm,bcm2836-smp") == 0)) {
-		arm_cpu_max = RPI_CPU_MAX;
-		VPRINTF("%s: %d cpus present\n", __func__, arm_cpu_max);
-
-		extern void cpu_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),
-			    KERN_VTOPHYS((vaddr_t)cpu_mpstart));
-		}
+	bus_space_tag_t iot = &bcm2836_bs_tag;
+	bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE;
+	uint64_t mpidr;
 
-		/* Wake up AP in case firmware has placed it in WFE state */
-		__asm __volatile("sev" ::: "memory");
+	fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
 
-		for (int loop = 0; loop < 16; loop++) {
-			if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
-				break;
-			gtmr_delay(10000);
-		}
+	const u_int cpuno = __SHIFTOUT(mpidr, MPIDR_AFF0);
 
-		for (size_t i = 1; i < arm_cpu_max; i++) {
-			if ((arm_cpu_hatched & __BIT(i)) == 0) {
-				printf("%s: warning: cpu%zu failed to hatch\n",
-				    __func__, i);
-			}
-		}
-		return;
-	}
-#endif /* __arm__ */
+	bus_space_write_4(iot, ioh, BCM2836_LOCAL_MAILBOX3_SETN(cpuno),
+	    KERN_VTOPHYS((vaddr_t)cpu_mpstart));
 
-	/* try enable-method each cpus */
-	arm_fdt_cpu_mpstart();
-#endif /* MULTIPROCESSOR */
+	return 0;
 }
+ARM_CPU_METHOD(bcm2836, "brcm,bcm2836-smp", cpu_enable_bcm2836);
+#endif
 
 #endif	/* SOC_BCM2836 */
 
@@ -1374,7 +1339,7 @@ static const struct arm_platform bcm2836
 	.ap_reset = bcm2835_system_reset,
 	.ap_delay = gtmr_delay,
 	.ap_uart_freq = bcm283x_platform_uart_freq,
-	.ap_mpstart = bcm2836_mpstart,
+	.ap_mpstart = arm_fdt_cpu_mpstart,
 };
 
 static const struct arm_platform bcm2837_platform = {
@@ -1385,7 +1350,7 @@ static const struct arm_platform bcm2837
 	.ap_reset = bcm2835_system_reset,
 	.ap_delay = gtmr_delay,
 	.ap_uart_freq = bcm2837_platform_uart_freq,
-	.ap_mpstart = bcm2836_mpstart,
+	.ap_mpstart = arm_fdt_cpu_mpstart,
 };
 
 ARM_PLATFORM(bcm2836, "brcm,bcm2836", &bcm2836_platform);

Index: src/sys/arch/arm/fdt/arm_fdtvar.h
diff -u src/sys/arch/arm/fdt/arm_fdtvar.h:1.12 src/sys/arch/arm/fdt/arm_fdtvar.h:1.13
--- src/sys/arch/arm/fdt/arm_fdtvar.h:1.12	Tue Oct 30 16:41:52 2018
+++ src/sys/arch/arm/fdt/arm_fdtvar.h	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: arm_fdtvar.h,v 1.12 2018/10/30 16:41:52 skrll Exp $ */
+/* $NetBSD: arm_fdtvar.h,v 1.13 2019/01/03 12:52:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <[email protected]>
@@ -29,12 +29,12 @@
 #ifndef _ARM_ARM_FDTVAR_H
 #define _ARM_ARM_FDTVAR_H
 
+struct fdt_attach_args;
+
 /*
  * Platform-specific data
  */
 
-struct fdt_attach_args;
-
 struct arm_platform {
 	const struct pmap_devmap * (*ap_devmap)(void);
 	void			(*ap_bootstrap)(void);
@@ -66,6 +66,25 @@ TAILQ_HEAD(arm_platlist, arm_platform_in
 
 const struct arm_platform *	arm_fdt_platform(void);
 
+/*
+ * CPU enable methods
+ */
+
+struct arm_cpu_method {
+	const char *		acm_compat;
+	int			(*acm_enable)(int);
+};
+
+#define	_ARM_CPU_METHOD_REGISTER(_name)	\
+	__link_set_add_rodata(arm_cpu_methods, __CONCAT(_name,_cpu_method));
+
+#define	ARM_CPU_METHOD(_name, _compat, _enable)				\
+static const struct arm_cpu_method __CONCAT(_name,_cpu_method) = {	\
+	.acm_compat = (_compat),					\
+	.acm_enable = (_enable)						\
+};									\
+_ARM_CPU_METHOD_REGISTER(_name)
+
 void	arm_fdt_cpu_bootstrap(void);
 void	arm_fdt_cpu_mpstart(void);
 void    arm_fdt_cpu_hatch_register(void *, void (*)(void *, struct cpu_info *));

Index: src/sys/arch/arm/fdt/cpu_fdt.c
diff -u src/sys/arch/arm/fdt/cpu_fdt.c:1.18 src/sys/arch/arm/fdt/cpu_fdt.c:1.19
--- src/sys/arch/arm/fdt/cpu_fdt.c:1.18	Thu Jan  3 10:26:41 2019
+++ src/sys/arch/arm/fdt/cpu_fdt.c	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_fdt.c,v 1.18 2019/01/03 10:26:41 skrll Exp $ */
+/* $NetBSD: cpu_fdt.c,v 1.19 2019/01/03 12:52:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -30,7 +30,7 @@
 #include "psci_fdt.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.18 2019/01/03 10:26:41 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.19 2019/01/03 12:52:40 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -258,17 +258,28 @@ arm_fdt_cpu_bootstrap(void)
 #endif
 }
 
+#ifdef MULTIPROCESSOR
+static int
+arm_fdt_cpu_enable(int phandle, const char *method)
+{
+	__link_set_decl(arm_cpu_methods, struct arm_cpu_method);
+	struct arm_cpu_method * const *acm;
+	__link_set_foreach(acm, arm_cpu_methods) {
+		if (strcmp(method, (*acm)->acm_compat) == 0)
+			return (*acm)->acm_enable(phandle);
+	}
+	return ENOSYS;
+}
+#endif
+
 void
 arm_fdt_cpu_mpstart(void)
 {
 #ifdef MULTIPROCESSOR
 	uint64_t mpidr, bp_mpidr;
-	u_int cpuindex;
-	int child, ret;
+	u_int cpuindex, i;
+	int child, error;
 	const char *method;
-#if NPSCI_FDT > 0
-	bool psci_p = true;
-#endif
 
 	const int cpus = OF_finddevice("/cpus");
 	if (cpus == -1) {
@@ -276,17 +287,10 @@ arm_fdt_cpu_mpstart(void)
 		return;
 	}
 
-#if NPSCI_FDT > 0
-	if (psci_fdt_preinit() != 0)
-		psci_p = false;
-#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 (!arm_fdt_cpu_okay(child))
@@ -300,44 +304,85 @@ arm_fdt_cpu_mpstart(void)
 
 		method = fdtbus_get_string(child, "enable-method");
 		if (method == NULL)
+			method = fdtbus_get_string(cpus, "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 (psci_p && (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);
+		error = arm_fdt_cpu_enable(child, method);
+		if (error != 0) {
+			aprint_error("%s: %s: unsupported enable-method\n", __func__, method);
 			continue;
 		}
 
-		started |= __BIT(cpuindex);
+		/* Wake up AP in case firmware has placed it in WFE state */
+		__asm __volatile("sev" ::: "memory");
+
+		/* Wait for AP to start */
+		for (i = 0x100000; i > 0; i--) {
+			membar_consumer();
+			if (arm_cpu_hatched & __BIT(cpuindex))
+				break;
+		}
+		if (i == 0)
+			aprint_error("cpu%d: WARNING: AP failed to start\n", cpuindex);
+
 		cpuindex++;
 	}
+#endif /* MULTIPROCESSOR */
+}
 
-	/* Wake up AP in case firmware has placed it in WFE state */
-	__asm __volatile("sev" ::: "memory");
+static int
+cpu_enable_nullop(int phandle)
+{
+	return ENXIO;
+}
+ARM_CPU_METHOD(default, "", cpu_enable_nullop);
 
-	/* Wait for APs to start */
-	for (u_int i = 0x10000000; i > 0; i--) {
-		membar_consumer();
-		if (arm_cpu_hatched == started)
-			break;
+#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0
+static int
+cpu_enable_psci(int phandle)
+{
+	static bool psci_probed, psci_p;
+	uint64_t mpidr;
+	int ret;
+
+	if (!psci_probed) {
+		psci_probed = true;
+		psci_p = psci_fdt_preinit() == 0;
 	}
-#endif /* MULTIPROCESSOR */
+	if (!psci_p)
+		return ENXIO;
+
+	fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
+
+	ret = psci_cpu_on(mpidr, cpu_fdt_mpstart_pa(), 0);
+	if (ret != PSCI_SUCCESS)
+		return EIO;
+
+	return 0;
 }
+ARM_CPU_METHOD(psci, "psci", cpu_enable_psci);
+#endif
+
+#if defined(MULTIPROCESSOR)
+static int
+cpu_enable_spin_table(int phandle)
+{
+	uint64_t mpidr, data;
+	paddr_t cpu_release_addr;
+	int ret;
+
+	fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
+
+	if (of_getprop_uint64(phandle, "cpu-release-addr", &data) != 0)
+		return ENXIO;
+
+	cpu_release_addr = (paddr_t)be64toh(data);
+	ret = spintable_cpu_on(mpidr, cpu_fdt_mpstart_pa(), cpu_release_addr);
+	if (ret != 0)
+		return EIO;
+
+	return 0;
+}
+ARM_CPU_METHOD(spin_table, "spin-table", cpu_enable_spin_table);
+#endif

Index: src/sys/arch/arm/nvidia/tegra_platform.c
diff -u src/sys/arch/arm/nvidia/tegra_platform.c:1.19 src/sys/arch/arm/nvidia/tegra_platform.c:1.20
--- src/sys/arch/arm/nvidia/tegra_platform.c:1.19	Sat Dec 15 13:17:12 2018
+++ src/sys/arch/arm/nvidia/tegra_platform.c	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_platform.c,v 1.19 2018/12/15 13:17:12 jmcneill Exp $ */
+/* $NetBSD: tegra_platform.c,v 1.20 2019/01/03 12:52:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <[email protected]>
@@ -34,7 +34,7 @@
 #include "ukbd.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.19 2018/12/15 13:17:12 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.20 2019/01/03 12:52:40 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -131,15 +131,6 @@ tegra210_platform_bootstrap(void)
 	arm_fdt_cpu_bootstrap();
 #endif
 }
-
-static void
-tegra210_platform_mpstart(void)
-{
-
-#if defined(MULTIPROCESSOR) && defined(__aarch64__)
-	arm_fdt_cpu_mpstart();
-#endif
-}
 #endif
 
 static void
@@ -246,7 +237,7 @@ static const struct arm_platform tegra21
 	.ap_reset = tegra_platform_reset,
 	.ap_delay = tegra_platform_delay,
 	.ap_uart_freq = tegra_platform_uart_freq,
-	.ap_mpstart = tegra210_platform_mpstart,
+	.ap_mpstart = arm_fdt_cpu_mpstart,
 };
 
 ARM_PLATFORM(tegra210, "nvidia,tegra210", &tegra210_platform);

Index: src/sys/arch/arm/sunxi/sunxi_mc_smp.c
diff -u src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.1 src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.2
--- src/sys/arch/arm/sunxi/sunxi_mc_smp.c:1.1	Thu Jan  3 11:01:59 2019
+++ src/sys/arch/arm/sunxi/sunxi_mc_smp.c	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_mc_smp.c,v 1.1 2019/01/03 11:01:59 jmcneill Exp $ */
+/* $NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.1 2019/01/03 11:01:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_mc_smp.c,v 1.2 2019/01/03 12:52:40 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -201,9 +201,3 @@ sunxi_mc_smp_enable(u_int mpidr)
 
 	return error;
 }
-
-int
-sunxi_mc_smp_match(const char *enable_method)
-{
-	return strcmp(enable_method, A83T_SMP_ENABLE_METHOD) == 0;
-}

Index: src/sys/arch/arm/sunxi/sunxi_platform.c
diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.32 src/sys/arch/arm/sunxi/sunxi_platform.c:1.33
--- src/sys/arch/arm/sunxi/sunxi_platform.c:1.32	Thu Jan  3 11:01:59 2019
+++ src/sys/arch/arm/sunxi/sunxi_platform.c	Thu Jan  3 12:52:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_platform.c,v 1.32 2019/01/03 11:01:59 jmcneill Exp $ */
+/* $NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -31,7 +31,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.32 2019/01/03 11:01:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.33 2019/01/03 12:52:40 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -235,55 +235,18 @@ sunxi_platform_bootstrap(void)
 	}
 }
 
-static void
-sunxi_mc_platform_mpstart(void)
+#if defined(SOC_SUNXI_MC)
+static int
+cpu_enable_sunxi_mc(int phandle)
 {
-	uint32_t started = 0;
-
-#if defined(MULTIPROCESSOR) && defined(SOC_SUNXI_MC)
-	const char *method;
-	uint64_t mpidr, bp_mpidr;
-	u_int cpuindex;
-	int child;
-
-	const int cpus = OF_finddevice("/cpus");
-	if (cpus == -1)
-		return;
-
-	/* MPIDR affinity levels of boot processor. */
-	bp_mpidr = cpu_mpidr_aff_read();
+	uint64_t mpidr;
 
-	cpuindex = 1;
-	for (child = OF_child(cpus); child; child = OF_peer(child)) {
-		if (fdtbus_get_reg64(child, 0, &mpidr, NULL) != 0)
-			continue;
-		if (mpidr == bp_mpidr)
-			continue;
-
-		method = fdtbus_get_string(child, "enable-method");
-		if (method == NULL)
-			method = fdtbus_get_string(cpus, "enable-method");
-		if (method == NULL)
-			continue;
-
-		if (sunxi_mc_smp_match(method) != 0) {
-			if (sunxi_mc_smp_enable(mpidr) != 0)
-				continue;
-
-			started |= __BIT(cpuindex);
-			cpuindex++;
-			for (u_int i = 0x100000; i > 0; i--) {
-				membar_consumer();
-				if (arm_cpu_hatched & __BIT(cpuindex))
-					break;
-			}
-		}
-	}
-#endif
+	fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
 
-	if (started == 0)
-		arm_fdt_cpu_mpstart();
+	return sunxi_mc_smp_enable(mpidr);
 }
+ARM_CPU_METHOD(sun8i_a83t, "allwinner,sun8i-a83t-smp", cpu_enable_sunxi_mc);
+#endif
 
 static void
 sun4i_platform_reset(void)
@@ -442,7 +405,7 @@ static const struct arm_platform sun8i_a
 	.ap_reset = sun6i_platform_reset,
 	.ap_delay = gtmr_delay,
 	.ap_uart_freq = sunxi_platform_uart_freq,
-	.ap_mpstart = sunxi_mc_platform_mpstart,
+	.ap_mpstart = arm_fdt_cpu_mpstart,
 };
 
 ARM_PLATFORM(sun8i_a83t, "allwinner,sun8i-a83t", &sun8i_a83t_platform);

Reply via email to