Module Name: src Committed By: jmcneill Date: Tue Sep 11 10:06:53 UTC 2018
Modified Files: src/sys/arch/arm/samsung: exynos_platform.c files.exynos mct.c src/sys/arch/evbarm/conf: EXYNOS src/sys/arch/evbarm/exynos: exynos_start.S Log Message: Add Exynos5 SMP support. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/samsung/exynos_platform.c \ src/sys/arch/arm/samsung/mct.c cvs rdiff -u -r1.31 -r1.32 src/sys/arch/arm/samsung/files.exynos cvs rdiff -u -r1.32 -r1.33 src/sys/arch/evbarm/conf/EXYNOS cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/exynos/exynos_start.S 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/samsung/exynos_platform.c diff -u src/sys/arch/arm/samsung/exynos_platform.c:1.14 src/sys/arch/arm/samsung/exynos_platform.c:1.15 --- src/sys/arch/arm/samsung/exynos_platform.c:1.14 Wed Aug 22 07:43:02 2018 +++ src/sys/arch/arm/samsung/exynos_platform.c Tue Sep 11 10:06:53 2018 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ void exynos_platform_early_putchar(char) #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 @@ exynos5_platform_devmap(void) 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 }; Index: src/sys/arch/arm/samsung/mct.c diff -u src/sys/arch/arm/samsung/mct.c:1.14 src/sys/arch/arm/samsung/mct.c:1.15 --- src/sys/arch/arm/samsung/mct.c:1.14 Mon Jul 2 12:49:37 2018 +++ src/sys/arch/arm/samsung/mct.c Tue Sep 11 10:06:53 2018 @@ -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 @@ __KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.14 #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 @@ static struct timecounter mct_timecounte .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 @@ mct_write_global(struct mct_softc *sc, b 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_cpu_initclocks(void) 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 @@ mct_attach(device_t parent, device_t sel 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 Index: src/sys/arch/arm/samsung/files.exynos diff -u src/sys/arch/arm/samsung/files.exynos:1.31 src/sys/arch/arm/samsung/files.exynos:1.32 --- src/sys/arch/arm/samsung/files.exynos:1.31 Sun Aug 19 07:27:33 2018 +++ src/sys/arch/arm/samsung/files.exynos Tue Sep 11 10:06:53 2018 @@ -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 @@ attach exyortc at fdt with exynos_rtc 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 Index: src/sys/arch/evbarm/conf/EXYNOS diff -u src/sys/arch/evbarm/conf/EXYNOS:1.32 src/sys/arch/evbarm/conf/EXYNOS:1.33 --- src/sys/arch/evbarm/conf/EXYNOS:1.32 Sun Aug 19 07:27:33 2018 +++ src/sys/arch/evbarm/conf/EXYNOS Tue Sep 11 10:06:53 2018 @@ -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 @@ syscon* at fdt? pass 1 # Generic Syste # 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 Index: src/sys/arch/evbarm/exynos/exynos_start.S diff -u src/sys/arch/evbarm/exynos/exynos_start.S:1.7 src/sys/arch/evbarm/exynos/exynos_start.S:1.8 --- src/sys/arch/evbarm/exynos/exynos_start.S:1.7 Sun Aug 19 07:27:33 2018 +++ src/sys/arch/evbarm/exynos/exynos_start.S Tue Sep 11 10:06:53 2018 @@ -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 @@ mmu_init_table: 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_table: 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: