Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Add Exynos5 SMP support.



details:   https://anonhg.NetBSD.org/src/rev/0a65a8766023
branches:  trunk
changeset: 993441:0a65a8766023
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Tue Sep 11 10:06:53 2018 +0000

description:
Add Exynos5 SMP support.

diffstat:

 sys/arch/arm/samsung/exynos_platform.c |  69 +++++++++++++++++++++++++++++++++-
 sys/arch/arm/samsung/files.exynos      |   4 +-
 sys/arch/arm/samsung/mct.c             |  53 ++++++++++++++++++++-----
 sys/arch/evbarm/conf/EXYNOS            |   5 +-
 sys/arch/evbarm/exynos/exynos_start.S  |   6 +-
 5 files changed, 116 insertions(+), 21 deletions(-)

diffs (286 lines):

diff -r 22327791c086 -r 0a65a8766023 sys/arch/arm/samsung/exynos_platform.c
--- a/sys/arch/arm/samsung/exynos_platform.c    Tue Sep 11 10:05:31 2018 +0000
+++ b/sys/arch/arm/samsung/exynos_platform.c    Tue Sep 11 10:06:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_platform.c,v 1.14 2018/08/22 07:43:02 skrll Exp $ */
+/* $NetBSD: exynos_platform.c,v 1.15 2018/09/11 10:06:53 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -34,7 +34,7 @@
 #include "ukbd.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.14 2018/08/22 07:43:02 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.15 2018/09/11 10:06:53 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -65,11 +65,73 @@
 #define EXYNOS_IOPHYSTOVIRT(a) \
     ((vaddr_t)(((a) - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE))
 
+#define        EXYNOS5800_PMU_BASE             0x10040000
+#define        EXYNOS5800_PMU_SIZE             0x20000
+#define         EXYNOS5800_PMU_CORE_CONFIG(n)  (0x2000 + 0x80 * (n))
+#define         EXYNOS5800_PMU_CORE_STATUS(n)  (0x2004 + 0x80 * (n))
+#define         EXYNOS5800_PMU_CORE_POWER_EN   0x3
+#define        EXYNOS5800_SYSRAM_BASE          0x0207301c
+#define        EXYNOS5800_SYSRAM_SIZE          0x4
+
+static void
+exynos5800_mp_bootstrap(void)
+{
+#if defined(MULTIPROCESSOR)
+       extern void cortex_mpstart(void);
+       bus_space_tag_t bst = &armv7_generic_bs_tag;
+       bus_space_handle_t pmu_bsh, sysram_bsh;
+       uint32_t val, started = 0;
+       int n;
+
+       arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
+
+       bus_space_map(bst, EXYNOS5800_PMU_BASE, EXYNOS5800_PMU_SIZE, 0, &pmu_bsh);
+       bus_space_map(bst, EXYNOS5800_SYSRAM_BASE, EXYNOS5800_SYSRAM_SIZE, 0, &sysram_bsh);
+
+       bus_space_write_4(bst, sysram_bsh, 0, (uint32_t)cortex_mpstart);
+       bus_space_barrier(bst, sysram_bsh, 0, 4, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+
+       for (n = 1; n < arm_cpu_max; n++) {
+               bus_space_write_4(bst, pmu_bsh, EXYNOS5800_PMU_CORE_CONFIG(n),
+                   EXYNOS5800_PMU_CORE_POWER_EN);
+               for (u_int i = 0x01000000; i > 0; i--) {
+                       val = bus_space_read_4(bst, pmu_bsh, EXYNOS5800_PMU_CORE_STATUS(n));
+                       if ((val & EXYNOS5800_PMU_CORE_POWER_EN) == EXYNOS5800_PMU_CORE_POWER_EN) {
+                               started |= __BIT(n);
+                               break;
+                       }
+               }
+       }
+
+       for (u_int i = 0x10000000; i > 0; i--) {
+               arm_dmb();
+               if (arm_cpu_hatched == started)
+                       break;
+       }
+
+       bus_space_unmap(bst, sysram_bsh, EXYNOS5800_SYSRAM_SIZE);
+       bus_space_unmap(bst, pmu_bsh, EXYNOS5800_PMU_SIZE);
+#endif
+}
+
+static struct of_compat_data mp_compat_data[] = {
+       { "samsung,exynos5800",         (uintptr_t)exynos5800_mp_bootstrap },
+       { NULL }
+};
+
 static void
 exynos_platform_bootstrap(void)
 {
 
        exynos_bootstrap(EXYNOS_CORE_VBASE);
+
+       void (*mp_bootstrap)(void) = NULL;
+       const struct of_compat_data *cd = of_search_compatible(OF_finddevice("/"), mp_compat_data);
+       if (cd)
+               mp_bootstrap = (void (*)(void))cd->data;
+
+       if (mp_bootstrap)
+               mp_bootstrap();
 }
 
 static void
@@ -168,6 +230,9 @@
                DEVMAP_ENTRY(EXYNOS5_AUDIOCORE_VBASE,
                             EXYNOS5_AUDIOCORE_PBASE,
                             EXYNOS5_AUDIOCORE_SIZE),
+               DEVMAP_ENTRY(EXYNOS5_SYSRAM_VBASE,
+                            EXYNOS5_SYSRAM_PBASE,
+                            EXYNOS5_SYSRAM_SIZE),
                DEVMAP_ENTRY_END
        };
 
diff -r 22327791c086 -r 0a65a8766023 sys/arch/arm/samsung/files.exynos
--- a/sys/arch/arm/samsung/files.exynos Tue Sep 11 10:05:31 2018 +0000
+++ b/sys/arch/arm/samsung/files.exynos Tue Sep 11 10:06:53 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.exynos,v 1.31 2018/08/19 07:27:33 skrll Exp $
+#      $NetBSD: files.exynos,v 1.32 2018/09/11 10:06:53 jmcneill Exp $
 #
 # Configuration info for Samsung Exynos SoC ARM Peripherals
 #
@@ -55,7 +55,7 @@
 file    arch/arm/samsung/exynos_rtc.c          exynos_rtc
 
 # Multi Core timer
-device mct
+device mct : mpcorebus
 attach mct at fdt with exyo_mct
 file   arch/arm/samsung/mct.c                  exyo_mct
 
diff -r 22327791c086 -r 0a65a8766023 sys/arch/arm/samsung/mct.c
--- a/sys/arch/arm/samsung/mct.c        Tue Sep 11 10:05:31 2018 +0000
+++ b/sys/arch/arm/samsung/mct.c        Tue Sep 11 10:06:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mct.c,v 1.14 2018/07/02 12:49:37 jmcneill Exp $        */
+/*     $NetBSD: mct.c,v 1.15 2018/09/11 10:06:53 jmcneill Exp $        */
 
 /*-
  * Copyright (c) 2014-2018 The NetBSD Foundation, Inc.
@@ -29,9 +29,12 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_arm_timer.h"
+#include "opt_multiprocessor.h"
+
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.14 2018/07/02 12:49:37 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.15 2018/09/11 10:06:53 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -53,6 +56,15 @@
 #include <dev/fdt/fdtvar.h>
 #include <arm/fdt/arm_fdtvar.h>
 
+#if defined(MULTIPROCESSOR)
+#if !defined(__HAVE_GENERIC_CPU_INITCLOCKS)
+#error MULTIPROCESSOR kernels require __HAVE_GENERIC_CPU_INITCLOCKS
+#endif
+#include <arm/cortex/gtmr_intr.h>
+#include <arm/cortex/mpcore_var.h>
+#include <arm/cortex/gtmr_var.h>
+#endif
+
 static struct mct_softc mct_sc;
 
 static int  mct_match(device_t, cfdata_t, void *);
@@ -65,7 +77,7 @@
        .tc_counter_mask = ~0u,
        .tc_frequency = EXYNOS_F_IN_FREQ,
        .tc_name = "MCT",
-       .tc_quality = 500,
+       .tc_quality = 400,
        .tc_priv = &mct_sc,
 };
 
@@ -137,21 +149,16 @@
        panic("MCT hangs after writing %#x at %#x", v, (uint32_t) o);
 }
 
-static void
-mct_fdt_cpu_hatch(void *priv, struct cpu_info *ci)
-{
-       panic("%s: not implemented", __func__);
-}
-
 static int
 mct_intr(void *arg)
 {
        struct mct_softc * const sc = &mct_sc;
-       struct clockframe *frame = arg;
 
        mct_write_global(sc, MCT_G_INT_CSTAT, G_INT_CSTAT_CLEAR);
 
-       hardclock(frame);
+#if !defined(MULTIPROCESSOR)
+       hardclock(arg);
+#endif
 
        return 1;
 }
@@ -203,6 +210,19 @@
        mct_write_global(sc, MCT_G_COMP0_U, (uint32_t)(comp0 >> 32));
        mct_write_global(sc, MCT_G_INT_ENB, G_INT_ENB_ENABLE);
        mct_write_global(sc, MCT_G_TCON, G_TCON_START | G_TCON_COMP0_ENABLE | G_TCON_COMP0_AUTOINC);
+
+#if defined(MULTIPROCESSOR)
+       /* Initialize gtmr */
+       gtmr_cpu_initclocks();
+#endif
+}
+
+static void
+mct_fdt_cpu_hatch(void *priv, struct cpu_info *ci)
+{
+#if defined(MULTIPROCESSOR)
+       gtmr_init_cpu_clock(ci);
+#endif
 }
 
 static int
@@ -248,6 +268,17 @@
 
        arm_fdt_cpu_hatch_register(self, mct_fdt_cpu_hatch);
        arm_fdt_timer_register(mct_cpu_initclocks);
+
+#if defined(MULTIPROCESSOR)
+       /* Start the timer */
+       mct_write_global(sc, MCT_G_TCON, G_TCON_START);
+
+       struct mpcore_attach_args mpcaa = {
+               .mpcaa_name = "armgtmr",
+               .mpcaa_irq = IRQ_GTMR_PPI_VTIMER,
+       };
+       config_found(self, &mpcaa, NULL);
+#endif
 }
 
 void
diff -r 22327791c086 -r 0a65a8766023 sys/arch/evbarm/conf/EXYNOS
--- a/sys/arch/evbarm/conf/EXYNOS       Tue Sep 11 10:05:31 2018 +0000
+++ b/sys/arch/evbarm/conf/EXYNOS       Tue Sep 11 10:06:53 2018 +0000
@@ -1,5 +1,5 @@
 #
-#      $NetBSD: EXYNOS,v 1.32 2018/08/19 07:27:33 skrll Exp $
+#      $NetBSD: EXYNOS,v 1.33 2018/09/11 10:06:53 jmcneill Exp $
 #
 #      Samsung Exynos SoC kernel
 #
@@ -54,8 +54,9 @@
 
 # Timer
 mct*           at fdt? pass 2          # Exynos Multi Core Timer (MCT)
+armgtmr*       at mct?
 gtmr*          at fdt? pass 2
-armgtmr0       at gtmr?
+armgtmr*       at gtmr?
 
 # Interrupt controller
 exyointr*      at fdt? pass 1
diff -r 22327791c086 -r 0a65a8766023 sys/arch/evbarm/exynos/exynos_start.S
--- a/sys/arch/evbarm/exynos/exynos_start.S     Tue Sep 11 10:05:31 2018 +0000
+++ b/sys/arch/evbarm/exynos/exynos_start.S     Tue Sep 11 10:06:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exynos_start.S,v 1.7 2018/08/19 07:27:33 skrll Exp $   */
+/*     $NetBSD: exynos_start.S,v 1.8 2018/09/11 10:06:53 jmcneill Exp $        */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
 
 #include <evbarm/exynos/platform.h>
 
-RCSID("$NetBSD: exynos_start.S,v 1.7 2018/08/19 07:27:33 skrll Exp $")
+RCSID("$NetBSD: exynos_start.S,v 1.8 2018/09/11 10:06:53 jmcneill Exp $")
 
 #if defined(KERNEL_BASES_EQUAL)
 #define CALL(f)                bl      _C_LABEL(f)
@@ -242,7 +242,6 @@
                EXYNOS_CORE_SIZE / L1_S_SIZE,
                L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
 
-#if 0
        /* Map EXYNOS AUDIOBASE */
        MMU_INIT(EXYNOS5_AUDIOCORE_VBASE, EXYNOS5_AUDIOCORE_VBASE,
                EXYNOS5_AUDIOCORE_SIZE / L1_S_SIZE,
@@ -262,7 +261,6 @@
        MMU_INIT(EXYNOS5_SYSRAM_PBASE, EXYNOS5_SYSRAM_PBASE,
                EXYNOS5_SYSRAM_SIZE / L1_S_SIZE,
                L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
-#endif
 
        /* Map DTB location in SDRAM, patched in later */
 .Lmmu_init_table_dtb:



Home | Main Index | Thread Index | Old Index