arm:socfpga: Enable SMP for socfpga
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
From: Dinh Nguyen <[email protected]>
Enable SMP for the SOCFPGA platform.
--- arch/arm/boot/dts/socfpga.dtsi | 10 ++ arch/arm/configs/socfpga_defconfig | 9 +- arch/arm/mach-socfpga/Kconfig | 1 + arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/headsmp.S | 64 +++++++++++ arch/arm/mach-socfpga/include/mach/core.h | 33 ++++++ arch/arm/mach-socfpga/platsmp.c | 166 +++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga.c | 33 +++++- 8 files changed, 315 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-socfpga/headsmp.S create mode 100644 arch/arm/mach-socfpga/include/mach/core.h create mode 100644 arch/arm/mach-socfpga/platsmp.c
arch/arm/boot/dts/socfpga.dtsi +10 -0
@@ -143,5 +143,15 @@ reg-shift = <2>; reg-io-width = <4>; }; + + rstmgr at ffd05000 { + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; + }; + + sysmgr at ffd08000 { + compatible = "altr,sys-mgr"; + reg = <0xffd08000 0x4000>; + }; }; };
arch/arm/configs/socfpga_defconfig +6 -3
@@ -1,5 +1,5 @@ CONFIG_EXPERIMENTAL=y -CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14
@@ -16,10 +16,13 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_SOCFPGA=y -CONFIG_MACH_SOCFPGA_CYCLONE5=y -CONFIG_ARM_THUMBEE=y +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set # CONFIG_CACHE_L2X0 is not set CONFIG_HIGH_RES_TIMERS=y +CONFIG_SMP=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y CONFIG_VMSPLIT_2G=y CONFIG_NR_CPUS=2 CONFIG_AEABI=y
arch/arm/mach-socfpga/Kconfig +1 -0
@@ -12,5 +12,6 @@ config ARCH_SOCFPGA select GENERIC_CLOCKEVENTS select GPIO_PL061 if GPIOLIB select HAVE_ARM_SCU + select HAVE_SMP select SPARSE_IRQ select USE_OF
arch/arm/mach-socfpga/Makefile +3 -0
@@ -2,4 +2,7 @@ # Makefile for the linux kernel. # +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include + obj-y := socfpga.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.o
arch/arm/mach-socfpga/headsmp.S new file +64 -0
64 lines not on this page · raw message
arch/arm/mach-socfpga/include/mach/core.h new file +33 -0
@@ -0,0 +1,33 @@ +/* +* Copyright 2012 Pavel Machek <[email protected]> +* Copyright (C) 2012 Altera Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __MACH_CORE_H +#define __MACH_CORE_H + +extern void secondary_startup (void ); +extern void __iomem *socfpga_scu_base_addr; + +extern void socfpga_init_clocks (void ); +extern void socfpga_sysmgr_init (void ); + +extern struct smp_operations socfpga_smp_ops; + +#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 + +#endif
arch/arm/mach-socfpga/platsmp.c new file +166 -0
166 lines not on this page · raw message
arch/arm/mach-socfpga/socfpga.c +32 -1
@@ -21,8 +21,34 @@#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> #include <asm/mach/arch.h> +#include <asm/mach/map.h> -extern void socfpga_init_clocks (void ); +#include <mach/core.h> + +void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE )); + +static struct map_desc scu_io_desc__initdata = { + .virtual =SOCFPGA_SCU_VIRT_BASE , + .pfn =0 ,/* run-time */ + .length =SZ_8K , + .type =MT_DEVICE , +}; + +static void __init socfpga_scu_map_io (void ) +{ +unsigned long base; + +/* Get SCU base */ + asm("mrc p15, 4, %0, c15, c0, 0" :"=r" (base)); + + scu_io_desc.pfn =__phys_to_pfn (base); +iotable_init (&scu_io_desc,1 ); +} + +static void __init socfpga_map_io (void ) +{ +socfpga_scu_map_io (); +}const static struct of_device_id irq_match[] = { { .compatible ="arm,cortex-a9-gic" , .data = gic_of_init, },
@@ -32,6 +58,9 @@ const static struct of_device_id irq_match[] = {static void __init gic_init_irq (void ) {of_irq_init (irq_match); +#ifdef CONFIG_SMP +socfpga_sysmgr_init (); +#endif }static void socfpga_cyclone5_restart (char mode,const char *cmd)
@@ -53,6 +82,8 @@ static const char *altera_dt_match[] = { };DT_MACHINE_START (SOCFPGA ,"Altera SOCFPGA" ) + .smp = smp_ops(socfpga_smp_ops), + .map_io = socfpga_map_io, .init_irq = gic_init_irq, .handle_irq = gic_handle_irq, .timer = &dw_apb_timer,
Signature · 1 line
1.7.9.5
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
Quoted 9 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
Enable SMP for the SOCFPGA platform.
Signed-off-by Pavel Machek <[email protected]>Signed-off-by Dinh Nguyen <[email protected]>--- arch/arm/boot/dts/socfpga.dtsi | 10 ++ arch/arm/configs/socfpga_defconfig | 9 +-
Does the multi_v7_defconfig not work for you?
Quoted 4 lines
arch/arm/mach-socfpga/Kconfig | 1 + arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/headsmp.S | 64 +++++++++++ arch/arm/mach-socfpga/include/mach/core.h | 33 ++++++
Move core.h to mach-socfpga.
Quoted 15 lines
arch/arm/mach-socfpga/platsmp.c | 166 +++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga.c | 33 +++++- 8 files changed, 315 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-socfpga/headsmp.S create mode 100644 arch/arm/mach-socfpga/include/mach/core.h create mode 100644 arch/arm/mach-socfpga/platsmp.carch/arm/boot/dts/socfpga.dtsi +0
-0@@ -143,5 +143,15 @@ reg-shift = <2>; reg-io-width = <4>; };
arch/arm/boot/dts/socfpga.dtsi line 155
Quoted 10 lines
arch/arm/boot/dts/socfpga.dtsi +10
-0+ + rstmgr at ffd05000 { + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; + }; + + sysmgr at ffd08000 { + compatible = "altr,sys-mgr"; + reg = <0xffd08000 0x4000>; + };
Bindings need documentation.
Quoted 45 lines
arch/arm/boot/dts/socfpga.dtsi +0
-0}; };arch/arm/configs/socfpga_defconfig +6
-3@@ -1,5 +1,5 @@ CONFIG_EXPERIMENTAL=y -CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14@@ -16,10 +16,13 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_SOCFPGA=y -CONFIG_MACH_SOCFPGA_CYCLONE5=y -CONFIG_ARM_THUMBEE=y +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set # CONFIG_CACHE_L2X0 is not set CONFIG_HIGH_RES_TIMERS=y +CONFIG_SMP=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y CONFIG_VMSPLIT_2G=y CONFIG_NR_CPUS=2 CONFIG_AEABI=yarch/arm/mach-socfpga/Kconfig +1
-0@@ -12,5 +12,6 @@ config ARCH_SOCFPGA select GENERIC_CLOCKEVENTS select GPIO_PL061 if GPIOLIB select HAVE_ARM_SCU + select HAVE_SMP select SPARSE_IRQ select USE_OFarch/arm/mach-socfpga/Makefile +0
-0
arch/arm/mach-socfpga/Makefile line 6
Quoted 5 lines
arch/arm/mach-socfpga/Makefile +2
-0@@ -2,4 +2,7 @@ # Makefile for the linux kernel. # +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include +
This can be removed if core.h is moved.
Quoted 15 lines
arch/arm/mach-socfpga/Makefile +1
-0obj-y := socfpga.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.oarch/arm/mach-socfpga/headsmp.S new file +7
-0@@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 ARM Limited + * Copyright (c) u-boot contributors + * Copyright (c) 2012 Pavel Machek <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as
arch/arm/mach-socfpga/headsmp.S line 17
Quoted 10 lines
arch/arm/mach-socfpga/headsmp.S new file +10
-0+ * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include <linux/init.h> + + __INIT + +#define CPU1_START_ADDR 0xffd08010 + +ENTRY(secondary_trampoline)
This appears to be your reset code at phys addr 0. How does core 0 boot if you are copying this to 0?
Quoted 24 lines
arch/arm/mach-socfpga/headsmp.S new file +24
-0+ /* From u-boot: start.S */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr,r0 + +/************************************************************************* + * + * cpu_init_cp15 + ** Copyright (c) u-boot contributors + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless + * CONFIG_SYS_ICACHE_OFF is defined. + * + *************************************************************************/ +ENTRY(cpu_init_cp15) + /* + * Invalidate L1 I/D + */ + mov r0, #0 @ set up for MCR + mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB
arch/arm/mach-socfpga/headsmp.S line 51
Quoted 10 lines
arch/arm/mach-socfpga/headsmp.S new file +10
-0+ + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
All this should get done by v7_setup.
Quoted 148 lines
arch/arm/mach-socfpga/headsmp.S new file +13
-0+ mcr p15, 0, r0, c1, c0, 0 + + movw r0, #:lower16:CPU1_START_ADDR + movt r0, #:upper16:CPU1_START_ADDR + + ldr r1, [r0] + bx r1 + +ENTRY(secondary_trampoline_end) + + .align + .long pen_release +arch/arm/mach-socfpga/include/mach/core.h new file +33
-0@@ -0,0 +1,33 @@ +/* +* Copyright 2012 Pavel Machek <[email protected]> +* Copyright (C) 2012 Altera Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __MACH_CORE_H +#define __MACH_CORE_H + +extern void secondary_startup (void ); +extern void __iomem *socfpga_scu_base_addr; + +extern void socfpga_init_clocks (void ); +extern void socfpga_sysmgr_init (void ); + +extern struct smp_operations socfpga_smp_ops; + +#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 + +#endif arch/arm/mach-socfpga/platsmp.c new file +90
-0@@ -0,0 +1,166 @@ +/* +* Copyright 2010-2011 Calxeda, Inc. +* Copyright 2012 Pavel Machek <[email protected]> +* Based on platsmp.c, Copyright (C) 2002 ARM Ltd. +* Copyright (C) 2012 Altera Corporation +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/cacheflush.h> +#include <asm/hardware/gic.h> +#include <asm/smp_scu.h> +#include <asm/smp_plat.h> + +#include <mach/core.h> + +static void __iomem *sys_manager_base_addr; +static void __iomem *rst_manager_base_addr; + +static DEFINE_SPINLOCK (boot_lock); + +static void __cpuinit socfpga_secondary_init (unsigned int cpu) +{ +/* +* if any interrupts are already enabled for the primary +* core (e.g. timer irq), then they will not have been enabled +* for us: do so +*/ +gic_secondary_init (0 ); + +/* +* let the primary processor know we're out of the +* pen, then head off into the C entry point +*/ + pen_release =-1 ; +smp_wmb (); + +/* +* Synchronise with the boot thread. +*/ +spin_lock (&boot_lock); +spin_unlock (&boot_lock); +} + +static int __cpuinit socfpga_boot_secondary (unsigned int cpu,struct task_struct *idle) +{ +unsigned long timeout; +extern char secondary_trampoline, secondary_trampoline_end; + +int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + +/* +* Set synchronisation state between this boot processor +* and the secondary one +*/ +spin_lock (&boot_lock); + +memcpy (phys_to_virt (0 ), &secondary_trampoline, trampoline_size); + +__raw_writel (virt_to_phys (secondary_startup), (sys_manager_base_addr+0x10 )); + + pen_release =0 ; +flush_cache_all (); +smp_wmb (); +outer_clean_range (0 , trampoline_size); + +/* This will release CPU #1 out of reset.*/ +__raw_writel (0 , rst_manager_base_addr +0x10 ); + + timeout = jiffies + (1 *HZ ); +while (time_before (jiffies, timeout)) { +smp_rmb (); +if (pen_release ==-1 ) +break ;
arch/arm/mach-socfpga/platsmp.c line 100
Quoted 10 lines
arch/arm/mach-socfpga/platsmp.c new file +10
-0+ +udelay (10 ); + } + +/* +* now the secondary core is starting up let it run its +* calibrations, then wait for it to finish +*/ +spin_unlock (&boot_lock); +return pen_release !=-1 ? -ENOSYS :0 ;
You don't need any of this if you can reset secondary cores on hotplug.
Rob
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
Hi!
Quoted 11 lines
Quoted 4 lines
arch/arm/mach-socfpga/Kconfig | 1 + arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/headsmp.S | 64 +++++++++++ arch/arm/mach-socfpga/include/mach/core.h | 33 ++++++Move
core.hto mach-socfpga.Review
Quoted 2 lines
(quoted diff) +2
-0+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include +This can be removed if
core.his moved.
Ok, makes code nicer. Sorry for copying picoxcell too much.
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ __INIT + +#define CPU1_START_ADDR 0xffd08010 + +ENTRY(secondary_trampoline)This appears to be your reset code at phys addr 0. How does core 0 boot if you are copying this to 0?
Yes, this is reset code, goes at zero. Core 0 has already booted by the time we are trying to boot Core 1 (we don't support CPU hotplug, yet). Is that a problem?
Quoted 5 lines
Quoted 5 lines
(quoted diff) +5
-0+ /* From u-boot: start.S */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr,r0
...
Quoted 10 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cacheAll this should get done by
v7_setup.
It seems it is, as (emulated) system still boots with that code disabled.
Quoted 60 lines
Quoted 60 lines
(quoted diff) +60
-0+static DEFINE_SPINLOCK(boot_lock); + +static void __cpuinit socfpga_secondary_init(unsigned int cpu) +{ + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_secondary_init(0); + + /* + * let the primary processor know we're out of the + * pen, then head off into the C entry point + */ + pen_release = -1; + smp_wmb(); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + extern char secondary_trampoline, secondary_trampoline_end; + + int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); + + __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); + + pen_release = 0; + flush_cache_all(); + smp_wmb(); + outer_clean_range(0, trampoline_size); + + /* This will release CPU #1 out of reset.*/ + __raw_writel(0, rst_manager_base_addr + 0x10); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + smp_rmb(); + if (pen_release == -1) + break; + + udelay(10); + } + + /*
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + return pen_release != -1 ? -ENOSYS : 0;You don't need any of this if you can reset secondary cores on hotplug.
What exactly is unneccessary? I'd like to wait for secondary to come up so we can raise an error if it does not...?
Thanks,
Pavel
PS: I have this so far...
arch/arm/mach-socfpga/Makefile +0 -2
@@ -2,7 +2,5 @@ # Makefile for the linux kernel. # -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include - obj-y := socfpga.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o hotplug.o
arch/arm/mach-socfpga/core.h renamed from arch/arm/mach-socfpga/include/mach/core.h +0 -0
arch/arm/mach-socfpga/headsmp.S +0 -36
@@ -20,42 +20,6 @@ #define CONFIG_CPU1_START_ADDR (CONFIG_SYSTEM_MANAGER + 0x10) ENTRY(secondary_trampoline) - /* From u-boot: start.S */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0xd3 - msr cpsr,r0 - -/************************************************************************* - * - * cpu_init_cp15 - * - * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless - * CONFIG_SYS_ICACHE_OFF is defined. - * - *************************************************************************/ -ENTRY(cpu_init_cp15) - /* - * Invalidate L1 I/D - */ - mov r0, #0 @ set up for MCR - mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs - mcr p15, 0, r0, c7, c5, 0 @ invalidate icache - mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array - mcr p15, 0, r0, c7, c10, 4 @ DSB - mcr p15, 0, r0, c7, c5, 4 @ ISB - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002000 @ clear bits 13 (--V-) - bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) - orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align - orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB - orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache - mcr p15, 0, r0, c1, c0, 0 - movw r0, #:lower16:CONFIG_CPU1_START_ADDR movt r0, #:upper16:CONFIG_CPU1_START_ADDR
arch/arm/mach-socfpga/platsmp.c +1 -1
@@ -26,7 +26,7 @@#include <asm/smp_scu.h> #include <asm/smp_plat.h> -#include <mach/core.h> +#include "core.h" static void __iomem *sys_manager_base_addr;static void __iomem *rst_manager_base_addr;
arch/arm/mach-socfpga/socfpga.c +1 -1
@@ -23,7 +23,7 @@#include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/core.h> +#include "core.h" void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE ));void __iomem *rst_manager_base_addr = ((void __iomem *)(SOCFPGA_RST_MANAGER_VIRT_BASE ));
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
Quoted 25 lines · Pavel Machek
Hi!
Quoted 11 lines
Quoted 4 lines
arch/arm/mach-socfpga/Kconfig | 1 + arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/headsmp.S | 64 +++++++++++ arch/arm/mach-socfpga/include/mach/core.h | 33 ++++++Move
core.hto mach-socfpga.Review
Quoted 2 lines
(quoted diff) +2
-0+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include +This can be removed if
core.his moved.Ok, makes code nicer. Sorry for copying picoxcell too much.
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ __INIT + +#define CPU1_START_ADDR 0xffd08010 + +ENTRY(secondary_trampoline)This appears to be your reset code at phys addr 0. How does core 0 boot if you are copying this to 0?
Quoted 3 lines
Yes, this is reset code, goes at zero. Core 0 has already booted by the time we are trying to boot Core 1 (we don't support CPU hotplug, yet). Is that a problem?
It would be better to do both at the same time as the code is intertwined. More below on this...
Quoted 67 lines
Quoted 58 lines
Quoted 58 lines
(quoted diff) +58
-0+static void __cpuinit socfpga_secondary_init(unsigned int cpu) +{ + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_secondary_init(0); + + /* + * let the primary processor know we're out of the + * pen, then head off into the C entry point + */ + pen_release = -1; + smp_wmb(); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + extern char secondary_trampoline, secondary_trampoline_end; + + int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); + + __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); + + pen_release = 0; + flush_cache_all(); + smp_wmb(); + outer_clean_range(0, trampoline_size); + + /* This will release CPU #1 out of reset.*/ + __raw_writel(0, rst_manager_base_addr + 0x10); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + smp_rmb(); + if (pen_release == -1) + break; + + udelay(10); + } + + /*Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + return pen_release != -1 ? -ENOSYS : 0;You don't need any of this if you can reset secondary cores on hotplug.
Quoted 3 lines
What exactly is unneccessary? I'd like to wait for secondary to come up so we can raise an error if it does not...?
Look at the highbank code.
If hotplug will cause a reset of the core, then none of this pen code is needed. If hotplug just does a wfi and returns from the wfi when onlining the core like Versatile Express, then you need this pen code. There's been several prior discussions about this on the list.
If you will never support hotplug (and therefore suspend), then you don't need this pen code either.
Rob
Quoted 95 lines
Thanks,
PavelPS: I have this so far...
arch/arm/mach-socfpga/Makefile +0
-2@@ -2,7 +2,5 @@ # Makefile for the linux kernel. # -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include - obj-y := socfpga.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o hotplug.oarch/arm/mach-socfpga/core.h renamed from arch/arm/mach-socfpga/include/mach/core.h +0
-0arch/arm/mach-socfpga/headsmp.S +0
-36@@ -20,42 +20,6 @@ #define CONFIG_CPU1_START_ADDR (CONFIG_SYSTEM_MANAGER + 0x10) ENTRY(secondary_trampoline) - /* From u-boot: start.S */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0xd3 - msr cpsr,r0 - -/************************************************************************* - * - * cpu_init_cp15 - * - * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless - * CONFIG_SYS_ICACHE_OFF is defined. - * - *************************************************************************/ -ENTRY(cpu_init_cp15) - /* - * Invalidate L1 I/D - */ - mov r0, #0 @ set up for MCR - mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs - mcr p15, 0, r0, c7, c5, 0 @ invalidate icache - mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array - mcr p15, 0, r0, c7, c10, 4 @ DSB - mcr p15, 0, r0, c7, c5, 4 @ ISB - - /* - * disable MMU stuff and caches - */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x00002000 @ clear bits 13 (--V-) - bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) - orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align - orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB - orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache - mcr p15, 0, r0, c1, c0, 0 - movw r0, #:lower16:CONFIG_CPU1_START_ADDR movt r0, #:upper16:CONFIG_CPU1_START_ADDRarch/arm/mach-socfpga/platsmp.c +1
-1@@ -26,7 +26,7 @@#include <asm/smp_scu.h> #include <asm/smp_plat.h> -#include <mach/core.h> +#include "core.h" static void __iomem *sys_manager_base_addr;static void __iomem *rst_manager_base_addr;arch/arm/mach-socfpga/socfpga.c +1
-1@@ -23,7 +23,7 @@#include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/core.h> +#include "core.h" void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE ));void __iomem *rst_manager_base_addr = ((void __iomem *)(SOCFPGA_RST_MANAGER_VIRT_BASE ));
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
Hi!
Quoted 25 lines
Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +10
-0+ timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + smp_rmb(); + if (pen_release == -1) + break; + + udelay(10); + } + + /*Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + return pen_release != -1 ? -ENOSYS : 0;You don't need any of this if you can reset secondary cores on hotplug.
Quoted 3 lines
What exactly is unneccessary? I'd like to wait for secondary to come up so we can raise an error if it does not...?
Look at the highbank code.
Quoted 7 lines
If hotplug will cause a reset of the core, then none of this pen code is needed. If hotplug just does a wfi and returns from the wfi when onlining the core like Versatile Express, then you need this pen code. There's been several prior discussions about this on the list.
If you will never support hotplug (and therefore suspend), then you don't need this pen code either.
Ok, so I guess we should go with the simple code for now? Something like...
BTW... I wonder if I should put socfpga_smp_init_cpus(void) into the library somewhere? (Where?) Same code is used on highbank, imx, socfpga, spear13xx, tegra and ct-ca9x4...
arch/arm/mach-socfpga/headsmp.S +4 -9
@@ -1,5 +1,5 @@ /* - * linux/arch/arm/plat-socfpga5xs1/headsmp.S + * Trampoline to bring CPU from reset. * * Copyright (c) 2012 Pavel Machek <[email protected]> * Copyright (c) u-boot contributors
@@ -15,9 +15,9 @@ __INIT -#define HPS_SYSMGR_ADDRESS 0xffd08000 -#define CONFIG_SYSTEM_MANAGER HPS_SYSMGR_ADDRESS -#define CONFIG_CPU1_START_ADDR (CONFIG_SYSTEM_MANAGER + 0x10) +#define HPS_SYSMGR_ADDRESS 0xffd08000 +#define CONFIG_SYSTEM_MANAGER HPS_SYSMGR_ADDRESS +#define CONFIG_CPU1_START_ADDR (CONFIG_SYSTEM_MANAGER + 0x10) ENTRY(secondary_trampoline) movw r0, #:lower16:CONFIG_CPU1_START_ADDR
@@ -25,9 +25,4 @@ ENTRY(secondary_trampoline) ldr r1, [r0] bx r1 - ENTRY(secondary_trampoline_end) - - .align - .long pen_release -
arch/arm/mach-socfpga/platsmp.c +6 -40
80 lines not on this page · raw message
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
In reply to Rob HerringHi Rob,
Quoted 6 lines · Rob Herring
Quoted 4 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
Enable SMP for the SOCFPGA platform.
Quoted 7 lines
Quoted 5 lines
Signed-off-by Pavel Machek <[email protected]>Signed-off-by Dinh Nguyen <[email protected]>--- arch/arm/boot/dts/socfpga.dtsi | 10 ++ arch/arm/configs/socfpga_defconfig | 9 +-Does the
multi_v7_defconfignot work for you?
It does. Are you planning to remove the defconfigs the platforms that are part ofmulti_v7_defconfig soon? socfpga_defconfig is broken with SMP enabled because it needs +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set.
Quoted 7 lines
Quoted 5 lines
arch/arm/mach-socfpga/Kconfig | 1 + arch/arm/mach-socfpga/Makefile | 3 + arch/arm/mach-socfpga/headsmp.S | 64 +++++++++++ arch/arm/mach-socfpga/include/mach/core.h | 33 ++++++Move
core.hto mach-socfpga.
Will do.
Quoted 22 lines
Quoted 22 lines
arch/arm/mach-socfpga/platsmp.c | 166 +++++++++++++++++++++++++++++ arch/arm/mach-socfpga/socfpga.c | 33 +++++- 8 files changed, 315 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-socfpga/headsmp.S create mode 100644 arch/arm/mach-socfpga/include/mach/core.h create mode 100644 arch/arm/mach-socfpga/platsmp.carch/arm/boot/dts/socfpga.dtsi +4
-0@@ -143,5 +143,15 @@ reg-shift = <2>; reg-io-width = <4>; }; + + rstmgr at ffd05000 { + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>;
Quoted 8 lines
arch/arm/boot/dts/socfpga.dtsi line 155
Quoted 6 lines
arch/arm/boot/dts/socfpga.dtsi +6
-0+ }; + + sysmgr at ffd08000 { + compatible = "altr,sys-mgr"; + reg = <0xffd08000 0x4000>; + };Bindings need documentation.
Will add..
Quoted 290 lines
Quoted 49 lines
arch/arm/boot/dts/socfpga.dtsi +0
-0}; };arch/arm/configs/socfpga_defconfig +6
-3@@ -1,5 +1,5 @@ CONFIG_EXPERIMENTAL=y -CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14@@ -16,10 +16,13 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_SOCFPGA=y -CONFIG_MACH_SOCFPGA_CYCLONE5=y -CONFIG_ARM_THUMBEE=y +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set # CONFIG_CACHE_L2X0 is not set CONFIG_HIGH_RES_TIMERS=y +CONFIG_SMP=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y CONFIG_VMSPLIT_2G=y CONFIG_NR_CPUS=2 CONFIG_AEABI=yarch/arm/mach-socfpga/Kconfig +1
-0@@ -12,5 +12,6 @@ config ARCH_SOCFPGA select GENERIC_CLOCKEVENTS select GPIO_PL061 if GPIOLIB select HAVE_ARM_SCU + select HAVE_SMP select SPARSE_IRQ select USE_OFarch/arm/mach-socfpga/Makefile +0
-0arch/arm/mach-socfpga/Makefile line 6
Quoted 5 lines
arch/arm/mach-socfpga/Makefile +2
-0@@ -2,4 +2,7 @@ # Makefile for the linux kernel. # +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include +This can be removed if
core.his moved.Quoted 16 lines
arch/arm/mach-socfpga/Makefile +1
-0obj-y := socfpga.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.oarch/arm/mach-socfpga/headsmp.S new file +7
-0@@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 ARM Limited + * Copyright (c) u-boot contributors + * Copyright (c) 2012 Pavel Machek <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 asarch/arm/mach-socfpga/headsmp.S line 17
Quoted 10 lines
arch/arm/mach-socfpga/headsmp.S new file +10
-0+ * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include <linux/init.h> + + __INIT + +#define CPU1_START_ADDR 0xffd08010 + +ENTRY(secondary_trampoline)This appears to be your reset code at phys addr 0. How does core 0 boot if you are copying this to 0?
Quoted 27 lines
arch/arm/mach-socfpga/headsmp.S new file +11
-0+ /* From u-boot: start.S */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr,r0 + +/************************************************************************* + * + * cpu_init_cp15 + ** Copyright (c) u-boot contributors + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned onunless
+ *CONFIG_SYS_ICACHE_OFFis defined.
+ *
+ *************************************************************************/arch/arm/mach-socfpga/headsmp.S new file +10
-0+ENTRY(cpu_init_cp15) + /* + * Invalidate L1 I/D + */ + mov r0, #0 @ set up for MCR + mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISBarch/arm/mach-socfpga/headsmp.S line 51
Quoted 10 lines
arch/arm/mach-socfpga/headsmp.S new file +10
-0+ + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cacheAll this should get done by
v7_setup.Quoted 163 lines
arch/arm/mach-socfpga/headsmp.S new file +13
-0+ mcr p15, 0, r0, c1, c0, 0 + + movw r0, #:lower16:CPU1_START_ADDR + movt r0, #:upper16:CPU1_START_ADDR + + ldr r1, [r0] + bx r1 + +ENTRY(secondary_trampoline_end) + + .align + .long pen_release +arch/arm/mach-socfpga/include/mach/core.h new file +17
-0@@ -0,0 +1,33 @@ +/* +* Copyright 2012 Pavel Machek <[email protected]> +* Copyright (C) 2012 Altera Corporation +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */arch/arm/mach-socfpga/include/mach/core.h new file +15
-0+ +#ifndef __MACH_CORE_H +#define __MACH_CORE_H + +extern void secondary_startup (void ); +extern void __iomem *socfpga_scu_base_addr; + +extern void socfpga_init_clocks (void ); +extern void socfpga_sysmgr_init (void ); + +extern struct smp_operations socfpga_smp_ops; + +#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 + +#endif arch/arm/mach-socfpga/platsmp.c new file +7
-0@@ -0,0 +1,166 @@ +/* +* Copyright 2010-2011 Calxeda, Inc. +* Copyright 2012 Pavel Machek <[email protected]> +* Based on platsmp.c, Copyright (C) 2002 ARM Ltd. +* Copyright (C) 2012 Altera Corporation +* +* This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */arch/arm/mach-socfpga/platsmp.c new file +43
-0+#include <linux/delay.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/cacheflush.h> +#include <asm/hardware/gic.h> +#include <asm/smp_scu.h> +#include <asm/smp_plat.h> + +#include <mach/core.h> + +static void __iomem *sys_manager_base_addr; +static void __iomem *rst_manager_base_addr; + +static DEFINE_SPINLOCK (boot_lock); + +static void __cpuinit socfpga_secondary_init (unsigned int cpu) +{ +/* +* if any interrupts are already enabled for the primary +* core (e.g. timer irq), then they will not have been enabled +* for us: do so +*/ +gic_secondary_init (0 ); + +/* +* let the primary processor know we're out of the +* pen, then head off into the C entry point +*/ + pen_release =-1 ; +smp_wmb (); + +/* +* Synchronise with the boot thread. +*/ +spin_lock (&boot_lock); +spin_unlock (&boot_lock); +} + +static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct
task_struct*idle)arch/arm/mach-socfpga/platsmp.c new file +5
-0+{ +unsigned long timeout; +extern char secondary_trampoline, secondary_trampoline_end; + + int trampoline_size = &secondary_trampoline_end -
&secondary_trampoline;arch/arm/mach-socfpga/platsmp.c new file +10
-0+ +/* +* Set synchronisation state between this boot processor +* and the secondary one +*/ +spin_lock (&boot_lock); + +memcpy (phys_to_virt (0 ), &secondary_trampoline, trampoline_size); + + __raw_writel(virt_to_phys(secondary_startup),(
sys_manager_base_addr+0x10));arch/arm/mach-socfpga/platsmp.c new file +18
-0+ + pen_release =0 ; +flush_cache_all (); +smp_wmb (); +outer_clean_range (0 , trampoline_size); + +/* This will release CPU #1 out of reset.*/ +__raw_writel (0 , rst_manager_base_addr +0x10 ); + + timeout = jiffies + (1 *HZ ); +while (time_before (jiffies, timeout)) { +smp_rmb (); +if (pen_release ==-1 ) +break ; + +udelay (10 ); + } +
Quoted 8 lines
arch/arm/mach-socfpga/platsmp.c line 100
Quoted 6 lines
arch/arm/mach-socfpga/platsmp.c new file +6
-0+/* +* now the secondary core is starting up let it run its +* calibrations, then wait for it to finish +*/ +spin_unlock (&boot_lock); +return pen_release !=-1 ? -ENOSYS :0 ;You don't need any of this if you can reset secondary cores on hotplug.
Will investigate with your latest comments.
Thanks for the quick turnaround on the review.
Dinh
Quoted 3 lines
Rob
PATCH 1/1 arm:socfpga: Enable SMP for socfpga
Quoted 15 lines · Dinh Nguyen
Hi Rob,
Quoted 12 lines · Rob Herring
Quoted 9 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
Enable SMP for the SOCFPGA platform.
Signed-off-by Pavel Machek <[email protected]>Signed-off-by Dinh Nguyen <[email protected]>--- arch/arm/boot/dts/socfpga.dtsi | 10 ++ arch/arm/configs/socfpga_defconfig | 9 +-
Quoted 6 lines
Quoted 1 line
Does the
multi_v7_defconfignot work for you?It does. Are you planning to remove the defconfigs the platforms that are part of
multi_v7_defconfigsoon?socfpga_defconfigis broken with SMP enabled because it needs +#CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATAis not set.
I don't plan to remove them. I'll leave it up to the platform maintainers as the new multi_v7 config is not exactly the same selections.
That's strange that you care about the errata setting. I think it should work either way. We do need to scrub the errata list and enable all the ones which have no runtime impact and are conditioned on the core revision. I'm not sure what we'll do with the ones that could have a negative impact on performance of rev's without an errata.
Rob