Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm Add a link set for cpu enable methods.



details:   https://anonhg.NetBSD.org/src/rev/5b2b4a832e85
branches:  trunk
changeset: 447185:5b2b4a832e85
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Jan 03 12:52:40 2019 +0000

description:
Add a link set for cpu enable methods.

diffstat:

 sys/arch/arm/broadcom/bcm283x_platform.c |   69 +++-----------
 sys/arch/arm/fdt/arm_fdtvar.h            |   25 +++++-
 sys/arch/arm/fdt/cpu_fdt.c               |  135 ++++++++++++++++++++----------
 sys/arch/arm/nvidia/tegra_platform.c     |   15 +--
 sys/arch/arm/sunxi/sunxi_mc_smp.c        |   10 +-
 sys/arch/arm/sunxi/sunxi_platform.c      |   59 ++-----------
 6 files changed, 145 insertions(+), 168 deletions(-)

diffs (truncated from 510 to 300 lines):

diff -r 991954d7bba4 -r 5b2b4a832e85 sys/arch/arm/broadcom/bcm283x_platform.c
--- a/sys/arch/arm/broadcom/bcm283x_platform.c  Thu Jan 03 11:01:59 2019 +0000
+++ b/sys/arch/arm/broadcom/bcm283x_platform.c  Thu Jan 03 12:52:40 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
        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;
+       bus_space_tag_t iot = &bcm2836_bs_tag;
+       bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE;
+       uint64_t mpidr;
 
-       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;
+       fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
 
-                       bus_space_write_4(iot, ioh,
-                           BCM2836_LOCAL_MAILBOX3_SETN(i),
-                           KERN_VTOPHYS((vaddr_t)cpu_mpstart));
-               }
+       const u_int cpuno = __SHIFTOUT(mpidr, MPIDR_AFF0);
 
-               /* Wake up AP in case firmware has placed it in WFE state */
-               __asm __volatile("sev" ::: "memory");
-
-               for (int loop = 0; loop < 16; loop++) {
-                       if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
-                               break;
-                       gtmr_delay(10000);
-               }
+       bus_space_write_4(iot, ioh, BCM2836_LOCAL_MAILBOX3_SETN(cpuno),
+           KERN_VTOPHYS((vaddr_t)cpu_mpstart));
 
-               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__ */
-
-       /* 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 @@
        .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 @@
        .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);
diff -r 991954d7bba4 -r 5b2b4a832e85 sys/arch/arm/fdt/arm_fdtvar.h
--- a/sys/arch/arm/fdt/arm_fdtvar.h     Thu Jan 03 11:01:59 2019 +0000
+++ b/sys/arch/arm/fdt/arm_fdtvar.h     Thu Jan 03 12:52:40 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 
 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 *));
diff -r 991954d7bba4 -r 5b2b4a832e85 sys/arch/arm/fdt/cpu_fdt.c
--- a/sys/arch/arm/fdt/cpu_fdt.c        Thu Jan 03 11:01:59 2019 +0000
+++ b/sys/arch/arm/fdt/cpu_fdt.c        Thu Jan 03 12:52:40 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 #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 @@
                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 @@
 
                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);
-               cpuindex++;
-       }
+               /* Wake up AP in case firmware has placed it in WFE state */
+               __asm __volatile("sev" ::: "memory");
 
-       /* 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);
 
-       /* Wait for APs to start */
-       for (u_int i = 0x10000000; i > 0; i--) {
-               membar_consumer();
-               if (arm_cpu_hatched == started)
-                       break;
+               cpuindex++;
        }
 #endif /* MULTIPROCESSOR */
 }
+
+static int
+cpu_enable_nullop(int phandle)
+{
+       return ENXIO;
+}
+ARM_CPU_METHOD(default, "", cpu_enable_nullop);
+
+#if defined(MULTIPROCESSOR) && NPSCI_FDT > 0



Home | Main Index | Thread Index | Old Index