[PATCHv1] arm:socfpga: Enable SMP for socfpga

Pavel Machek pavel at denx.de
Wed Oct 17 19:02:16 EDT 2012


Hi!

> >  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.

> > +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
> > +
> 
> This can be removed if core.h is moved.

Ok, makes code nicer. Sorry for copying picoxcell too much.

> > +	__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?
 
> > +	/* From u-boot: start.S */
> > +	mrs     r0, cpsr
> > +	bic     r0, r0, #0x1f
> > +	orr     r0, r0, #0xd3
> > +	msr     cpsr,r0
...
> > +	 * 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.

It seems it is, as (emulated) system still boots with that code
disabled.

> > +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);
> > +	}
> > +
> > +	/*
> > +	 * 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...

diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 659fd27..a0fc372 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -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
diff --git a/arch/arm/mach-socfpga/include/mach/core.h b/arch/arm/mach-socfpga/core.h
similarity index 100%
rename from arch/arm/mach-socfpga/include/mach/core.h
rename to arch/arm/mach-socfpga/core.h
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S
index 9597ff7..081b4d1 100644
--- a/arch/arm/mach-socfpga/headsmp.S
+++ b/arch/arm/mach-socfpga/headsmp.S
@@ -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
 
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 34440aa..60c2b4a 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -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;
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 68d32cd..741b9ba 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -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));

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html



More information about the linux-arm-kernel mailing list