Index: head/sys/arm/allwinner/a20/a20_mp.c =================================================================== --- head/sys/arm/allwinner/a20/a20_mp.c +++ head/sys/arm/allwinner/a20/a20_mp.c @@ -1,138 +0,0 @@ -/*- - * Copyright (c) 2014 Ganbold Tsagaankhuu - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#define CPUCFG_BASE 0x01c25c00 -#define CPUCFG_SIZE 0x400 - -#define CPU0_RST_CTL 0x40 -#define CPU0_CTL 0x44 -#define CPU0_STATUS 0x48 -#define CPU1_RST_CTL 0x80 -#define CPU1_CTL 0x84 -#define CPU1_STATUS 0x88 -#define CPUCFG_GENCTL 0x184 -#define CPUCFG_P_REG0 0x1a4 -#define CPU1_PWR_CLAMP 0x1b0 -#define CPU1_PWROFF_REG 0x1b4 -#define CPUCFG_DBGCTL0 0x1e0 -#define CPUCFG_DBGCTL1 0x1e4 - -void -platform_mp_setmaxid(void) -{ - int ncpu; - - if (mp_ncpus != 0) - return; - - /* Read the number of cores from the CP15 L2 Control Register. */ - __asm __volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (ncpu)); - ncpu = ((ncpu >> 24) & 0x3) + 1; - - mp_ncpus = ncpu; - mp_maxid = ncpu - 1; -} - -void -platform_mp_start_ap(void) -{ - bus_space_handle_t cpucfg; - - uint32_t val; - - if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, 0, - &cpucfg) != 0) - panic("Couldn't map the CPUCFG\n"); - - dcache_wbinv_poc_all(); - - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0, - pmap_kextract((vm_offset_t)mpentry)); - - /* - * Assert nCOREPORESET low and set L1RSTDISABLE low. - * Ensure DBGPWRDUP is set to LOW to prevent any external - * debug access to the processor. - */ - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 0); - - /* Set L1RSTDISABLE low */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL); - val &= ~(1 << 1); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val); - - /* Set DBGPWRDUP low */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); - val &= ~(1 << 1); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); - - /* Release power clamp */ - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0xff); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x7f); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x3f); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x1f); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x0f); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x07); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x03); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x01); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x00); - DELAY(10000); - - /* Clear power-off gating */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG); - val &= ~(1 << 0); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG, val); - DELAY(1000); - - /* De-assert cpu core reset */ - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3); - - /* Assert DBGPWRDUP signal */ - val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); - val |= (1 << 1); - bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); - - armv7_sev(); - bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); -} Index: head/sys/arm/allwinner/a20/files.a20 =================================================================== --- head/sys/arm/allwinner/a20/files.a20 +++ head/sys/arm/allwinner/a20/files.a20 @@ -1,5 +1,5 @@ # $FreeBSD$ arm/allwinner/a20/a20_padconf.c standard -arm/allwinner/a20/a20_mp.c optional smp +arm/allwinner/aw_mp.c optional smp arm/allwinner/a20/a20_if_dwc.c optional dwc Index: head/sys/arm/allwinner/allwinner_machdep.c =================================================================== --- head/sys/arm/allwinner/allwinner_machdep.c +++ head/sys/arm/allwinner/allwinner_machdep.c @@ -50,6 +50,7 @@ #include +#include #include #include @@ -152,6 +153,10 @@ PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr), PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init), +#ifdef SMP + PLATFORMMETHOD(platform_mp_start_ap, a20_mp_start_ap), + PLATFORMMETHOD(platform_mp_setmaxid, aw_mp_setmaxid), +#endif PLATFORMMETHOD_END, }; @@ -160,6 +165,10 @@ PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr), PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init), +#ifdef SMP + PLATFORMMETHOD(platform_mp_start_ap, a31_mp_start_ap), + PLATFORMMETHOD(platform_mp_setmaxid, aw_mp_setmaxid), +#endif PLATFORMMETHOD_END, }; @@ -168,6 +177,10 @@ PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr), PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init), +#ifdef SMP + PLATFORMMETHOD(platform_mp_start_ap, a31_mp_start_ap), + PLATFORMMETHOD(platform_mp_setmaxid, aw_mp_setmaxid), +#endif PLATFORMMETHOD_END, }; Index: head/sys/arm/allwinner/aw_mp.h =================================================================== --- head/sys/arm/allwinner/aw_mp.h +++ head/sys/arm/allwinner/aw_mp.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _AW_MP_H_ +#define _AW_MP_H_ + +void aw_mp_setmaxid(platform_t plat); +void a20_mp_start_ap(platform_t plat); +void a31_mp_start_ap(platform_t plat); + +#endif /* _AW_MP_H_ */ Index: head/sys/arm/allwinner/aw_mp.c =================================================================== --- head/sys/arm/allwinner/aw_mp.c +++ head/sys/arm/allwinner/aw_mp.c @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2014 Ganbold Tsagaankhuu + * Copyright (c) 2016 Emmanuel Vadot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Register for all dual-core SoC */ +#define A20_CPUCFG_BASE 0x01c25c00 +/* Register for all quad-core SoC */ +#define CPUCFG_BASE 0x01f01c00 +#define CPUCFG_SIZE 0x400 +#define PRCM_BASE 0x01f01400 +#define PRCM_SIZE 0x800 + +#define CPU_OFFSET 0x40 +#define CPU_OFFSET_CTL 0x04 +#define CPU_OFFSET_STATUS 0x08 +#define CPU_RST_CTL(cpuid) ((cpuid + 1) * CPU_OFFSET) +#define CPU_CTL(cpuid) (((cpuid + 1) * CPU_OFFSET) + CPU_OFFSET_CTL) +#define CPU_STATUS(cpuid) (((cpuid + 1) * CPU_OFFSET) + CPU_OFFSET_STATUS) + +#define CPU_RESET (1 << 0) +#define CPU_CORE_RESET (1 << 1) + +#define CPUCFG_GENCTL 0x184 +#define CPUCFG_P_REG0 0x1a4 + +#define A20_CPU1_PWR_CLAMP 0x1b0 +#define CPU_PWR_CLAMP_REG 0x140 +#define CPU_PWR_CLAMP(cpu) ((cpu * 4) + CPU_PWR_CLAMP_REG) +#define CPU_PWR_CLAMP_STEPS 8 + +#define A20_CPU1_PWROFF_REG 0x1b4 +#define CPU_PWROFF 0x100 + +#define CPUCFG_DBGCTL0 0x1e0 +#define CPUCFG_DBGCTL1 0x1e4 + +void +aw_mp_setmaxid(platform_t plat) +{ + int ncpu; + uint32_t reg; + + if (mp_ncpus != 0) + return; + + reg = cp15_l2ctlr_get(); + ncpu = CPUV7_L2CTLR_NPROC(reg); + + mp_ncpus = ncpu; + mp_maxid = ncpu - 1; +} + +static void +aw_common_mp_start_ap(bus_space_handle_t cpucfg, bus_space_handle_t prcm) +{ + int i, j; + uint32_t val; + + dcache_wbinv_poc_all(); + + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0, + pmap_kextract((vm_offset_t)mpentry)); + + /* + * Assert nCOREPORESET low and set L1RSTDISABLE low. + * Ensure DBGPWRDUP is set to LOW to prevent any external + * debug access to the processor. + */ + for (i = 1; i < mp_ncpus; i++) + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i), 0); + + /* Set L1RSTDISABLE low */ + val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL); + for (i = 1; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val); + + /* Set DBGPWRDUP low */ + val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); + for (i = 1; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); + + /* Release power clamp */ + for (i = 1; i < mp_ncpus; i++) + for (j = 0; j <= CPU_PWR_CLAMP_STEPS; j++) { + if (prcm) { + bus_space_write_4(fdtbus_bs_tag, prcm, + CPU_PWR_CLAMP(i), 0xff >> j); + } else { + bus_space_write_4(fdtbus_bs_tag, + cpucfg, A20_CPU1_PWR_CLAMP, 0xff >> j); + } + } + DELAY(10000); + + /* Clear power-off gating */ + if (prcm) { + val = bus_space_read_4(fdtbus_bs_tag, prcm, CPU_PWROFF); + for (i = 0; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, prcm, CPU_PWROFF, val); + } else { + val = bus_space_read_4(fdtbus_bs_tag, + cpucfg, A20_CPU1_PWROFF_REG); + val &= ~(1 << 0); + bus_space_write_4(fdtbus_bs_tag, cpucfg, + A20_CPU1_PWROFF_REG, val); + } + DELAY(1000); + + /* De-assert cpu core reset */ + for (i = 1; i < mp_ncpus; i++) + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU_RST_CTL(i), + CPU_RESET | CPU_CORE_RESET); + + /* Assert DBGPWRDUP signal */ + val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1); + for (i = 1; i < mp_ncpus; i++) + val |= (1 << i); + bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val); + + armv7_sev(); + bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); +} + +void +a20_mp_start_ap(platform_t plat) +{ + bus_space_handle_t cpucfg; + + if (bus_space_map(fdtbus_bs_tag, A20_CPUCFG_BASE, CPUCFG_SIZE, + 0, &cpucfg) != 0) + panic("Couldn't map the CPUCFG\n"); + + aw_common_mp_start_ap(cpucfg, 0); + armv7_sev(); + bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); +} + +void +a31_mp_start_ap(platform_t plat) +{ + bus_space_handle_t cpucfg; + bus_space_handle_t prcm; + + if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, + 0, &cpucfg) != 0) + panic("Couldn't map the CPUCFG\n"); + if (bus_space_map(fdtbus_bs_tag, PRCM_BASE, PRCM_SIZE, 0, + &prcm) != 0) + panic("Couldn't map the PRCM\n"); + + aw_common_mp_start_ap(cpucfg, prcm); + armv7_sev(); + bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE); + bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE); +} Index: head/sys/arm/conf/A20 =================================================================== --- head/sys/arm/conf/A20 +++ head/sys/arm/conf/A20 @@ -31,6 +31,7 @@ options SCHED_ULE # ULE scheduler options SMP # Enable multiple cores options PLATFORM +options PLATFORM_SMP # Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols