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);