Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Fri, Apr 19, 2013 at 10:09 PM, Russell King - ARM Linux wrote: > On Sat, Apr 13, 2013 at 09:08:12PM +0800, Haojian Zhuang wrote: >> On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang wrote: >> > + /* >> > +* Synchronise with the boot thread. >> > +*/ >> > + spin_lock(_lock); >> > + spin_unlock(_lock); >> Lock & unlock without protecting anything. If so, you can remove this. > > ... which means you don't understand what is going on in this code, > and probably didn't read the comment above this fragment. The above > is to synchronise with the code below - again, read the comment at > the spin unlock in this function, remembering that the above code > and the code below runs concurrently on two different CPUs: > Yes, I misunderstood it. Thanks for your correction. Regards Haojian -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Sat, Apr 13, 2013 at 09:08:12PM +0800, Haojian Zhuang wrote: > On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang wrote: > > + /* > > +* Synchronise with the boot thread. > > +*/ > > + spin_lock(_lock); > > + spin_unlock(_lock); > Lock & unlock without protecting anything. If so, you can remove this. ... which means you don't understand what is going on in this code, and probably didn't read the comment above this fragment. The above is to synchronise with the code below - again, read the comment at the spin unlock in this function, remembering that the above code and the code below runs concurrently on two different CPUs: > > +static int __cpuinit mmp_boot_secondary(unsigned int cpu, struct > > task_struct *idle) > > +{ > > + unsigned long timeout; > > + > > + /* > > +* Avoid timer calibration on slave cpus. Use the value calibrated > > +* on master cpu. Referenced from tegra3 > > +*/ > > + preset_lpj = loops_per_jiffy; > > + > > + /* > > +* set synchronisation state between this boot processor > > +* and the secondary one > > +*/ > > + > > + spin_lock(_lock); > > + > > + /* > > +* The secondary processor is waiting to be released from > > +* the holding pen - release it, then wait for it to flag > > +* that it has been released by resetting pen_release. > > +* > > +* Note that "pen_release" is the hardware CPU ID, whereas > > +* "cpu" is Linux's internal ID. > > +*/ > > + write_pen_release(cpu); > > + > > + /* reset the cpu, let it branch to the kernel entry */ > > + mmp_cpu_power_up(cpu); > > + > > + 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(_lock); > > + > > + return pen_release != -1 ? -ENOSYS : 0; > > +} -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Sat, Apr 13, 2013 at 09:08:12PM +0800, Haojian Zhuang wrote: On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang zhan...@marvell.com wrote: + /* +* Synchronise with the boot thread. +*/ + spin_lock(boot_lock); + spin_unlock(boot_lock); Lock unlock without protecting anything. If so, you can remove this. ... which means you don't understand what is going on in this code, and probably didn't read the comment above this fragment. The above is to synchronise with the code below - again, read the comment at the spin unlock in this function, remembering that the above code and the code below runs concurrently on two different CPUs: +static int __cpuinit mmp_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + + /* +* Avoid timer calibration on slave cpus. Use the value calibrated +* on master cpu. Referenced from tegra3 +*/ + preset_lpj = loops_per_jiffy; + + /* +* set synchronisation state between this boot processor +* and the secondary one +*/ + + spin_lock(boot_lock); + + /* +* The secondary processor is waiting to be released from +* the holding pen - release it, then wait for it to flag +* that it has been released by resetting pen_release. +* +* Note that pen_release is the hardware CPU ID, whereas +* cpu is Linux's internal ID. +*/ + write_pen_release(cpu); + + /* reset the cpu, let it branch to the kernel entry */ + mmp_cpu_power_up(cpu); + + 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; +} -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Fri, Apr 19, 2013 at 10:09 PM, Russell King - ARM Linux li...@arm.linux.org.uk wrote: On Sat, Apr 13, 2013 at 09:08:12PM +0800, Haojian Zhuang wrote: On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang zhan...@marvell.com wrote: + /* +* Synchronise with the boot thread. +*/ + spin_lock(boot_lock); + spin_unlock(boot_lock); Lock unlock without protecting anything. If so, you can remove this. ... which means you don't understand what is going on in this code, and probably didn't read the comment above this fragment. The above is to synchronise with the code below - again, read the comment at the spin unlock in this function, remembering that the above code and the code below runs concurrently on two different CPUs: Yes, I misunderstood it. Thanks for your correction. Regards Haojian -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
> -Original Message- > From: Haojian Zhuang [mailto:haojian.zhu...@gmail.com] > Sent: 2013年4月13日 21:08 > To: Neil Zhang > Cc: Grant Likely; linux-arm-ker...@lists.infradead.org; > linux-kernel@vger.kernel.org; Chao Xie > Subject: Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988 > > On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang > wrote: > > Add SMP support for pxa988. > > > > Signed-off-by: Neil Zhang > > Signed-off-by: Chao Xie > > --- > > arch/arm/mach-mmp/Makefile |4 + > > arch/arm/mach-mmp/common.h |2 + > > arch/arm/mach-mmp/headsmp.S | 104 > ++ > > arch/arm/mach-mmp/mmpx-dt.c |1 + > > arch/arm/mach-mmp/platsmp.c | 170 > +++ > > arch/arm/mach-mmp/reset.c | 66 + > > arch/arm/mach-mmp/reset.h | 29 +++ > > 7 files changed, 376 insertions(+), 0 deletions(-) create mode > > 100644 arch/arm/mach-mmp/headsmp.S create mode 100644 > > arch/arm/mach-mmp/platsmp.c create mode 100644 > > arch/arm/mach-mmp/reset.c create mode 100644 > > arch/arm/mach-mmp/reset.h > > > > diff --git a/arch/arm/mach-mmp/Makefile > b/arch/arm/mach-mmp/Makefile > > index b60065f..e7b6173 100644 > > --- a/arch/arm/mach-mmp/Makefile > > +++ b/arch/arm/mach-mmp/Makefile > > @@ -9,6 +9,10 @@ obj-$(CONFIG_CPU_PXA168) += pxa168.o > > obj-$(CONFIG_CPU_PXA910) += pxa910.o > > obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o > > > > +ifeq ($(CONFIG_SMP),y) > > +obj-$(CONFIG_CPU_PXA988) += platsmp.o headsmp.o reset.o > > +endif > > + > You already select CONFIG_SMP if PXA988 is selected. There's no reason to > check CONFIG_SMP in Makefile again. CPU_PXA988 only select HAVE_SMP, we can still not enable SMP. > > > ifeq ($(CONFIG_COMMON_CLK), ) > > obj-y += clock.o > > obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o > > diff --git a/arch/arm/mach-mmp/common.h > b/arch/arm/mach-mmp/common.h > > index 8c9b510..7496cd0 100644 > > --- a/arch/arm/mach-mmp/common.h > > +++ b/arch/arm/mach-mmp/common.h > > @@ -1,5 +1,7 @@ > > #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) > > > > +extern struct smp_operations mmp_smp_ops; > > + > > extern void timer_init(int irq); > > > > extern void __init icu_init_irq(void); diff --git > > a/arch/arm/mach-mmp/headsmp.S b/arch/arm/mach-mmp/headsmp.S > new file > > mode 100644 index 000..2b6177e > > --- /dev/null > > +++ b/arch/arm/mach-mmp/headsmp.S > > @@ -0,0 +1,104 @@ > > +/* > > + * linux/arch/arm/mach-mmp/headsmp.S > > + * > > + * Copyright (C) 2012 Marvell, Inc. > > + * > > + * Author: Neil Zhang > > + * > > + * This software is licensed under the terms of the GNU General > > +Public > > + * License version 2, as published by the Free Software Foundation, > > +and > > + * may be copied, distributed, and modified under those terms. > > + * > > + * 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. > > + * > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > + __CPUINIT > > + > > +/* > > + * Marvell specific entry point for secondary CPUs. > > + * The secondary kernel init calls v7_flush_dcache_all before it > > +enables > > + * the L1; however, the L1 comes out of reset in an undefined state, > > +so > > + * the clean + invalidate performed by v7_flush_dcache_all causes a > > +bunch > > + * of cache lines with uninitialized data and uninitialized tags to > > +get > > + * written out to memory, which does really unpleasant things to the > > +main > > + * processor. We fix this by performing an invalidate, rather than a > > + * clean + invalidate for secondary core, before jumping into the kernel. > > + * > > + * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and > > +needs > > + * to be called for both secondary cores startup and primary core > > +resume > > + * procedures. > > + */ > > + .align L1_CACHE_SHIFT > > + > > + > > +/* > > + * PXA specific entry point for secondary CPUs. This provides > > + * a "holding pen" into which all secondary cores are he
RE: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
-Original Message- From: Haojian Zhuang [mailto:haojian.zhu...@gmail.com] Sent: 2013年4月13日 21:08 To: Neil Zhang Cc: Grant Likely; linux-arm-ker...@lists.infradead.org; linux-kernel@vger.kernel.org; Chao Xie Subject: Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988 On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang zhan...@marvell.com wrote: Add SMP support for pxa988. Signed-off-by: Neil Zhang zhan...@marvell.com Signed-off-by: Chao Xie chao@marvell.com --- arch/arm/mach-mmp/Makefile |4 + arch/arm/mach-mmp/common.h |2 + arch/arm/mach-mmp/headsmp.S | 104 ++ arch/arm/mach-mmp/mmpx-dt.c |1 + arch/arm/mach-mmp/platsmp.c | 170 +++ arch/arm/mach-mmp/reset.c | 66 + arch/arm/mach-mmp/reset.h | 29 +++ 7 files changed, 376 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mmp/headsmp.S create mode 100644 arch/arm/mach-mmp/platsmp.c create mode 100644 arch/arm/mach-mmp/reset.c create mode 100644 arch/arm/mach-mmp/reset.h diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index b60065f..e7b6173 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -9,6 +9,10 @@ obj-$(CONFIG_CPU_PXA168) += pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_CPU_PXA988) += platsmp.o headsmp.o reset.o +endif + You already select CONFIG_SMP if PXA988 is selected. There's no reason to check CONFIG_SMP in Makefile again. CPU_PXA988 only select HAVE_SMP, we can still not enable SMP. ifeq ($(CONFIG_COMMON_CLK), ) obj-y += clock.o obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h index 8c9b510..7496cd0 100644 --- a/arch/arm/mach-mmp/common.h +++ b/arch/arm/mach-mmp/common.h @@ -1,5 +1,7 @@ #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) +extern struct smp_operations mmp_smp_ops; + extern void timer_init(int irq); extern void __init icu_init_irq(void); diff --git a/arch/arm/mach-mmp/headsmp.S b/arch/arm/mach-mmp/headsmp.S new file mode 100644 index 000..2b6177e --- /dev/null +++ b/arch/arm/mach-mmp/headsmp.S @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/mach-mmp/headsmp.S + * + * Copyright (C) 2012 Marvell, Inc. + * + * Author: Neil Zhang zhan...@marvell.com + * + * This software is licensed under the terms of the GNU General +Public + * License version 2, as published by the Free Software Foundation, +and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#include linux/linkage.h +#include linux/init.h +#include asm/memory.h +#include asm/cache.h +#include asm/assembler.h +#include mach/addr-map.h + + __CPUINIT + +/* + * Marvell specific entry point for secondary CPUs. + * The secondary kernel init calls v7_flush_dcache_all before it +enables + * the L1; however, the L1 comes out of reset in an undefined state, +so + * the clean + invalidate performed by v7_flush_dcache_all causes a +bunch + * of cache lines with uninitialized data and uninitialized tags to +get + * written out to memory, which does really unpleasant things to the +main + * processor. We fix this by performing an invalidate, rather than a + * clean + invalidate for secondary core, before jumping into the kernel. + * + * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and +needs + * to be called for both secondary cores startup and primary core +resume + * procedures. + */ + .align L1_CACHE_SHIFT + + +/* + * PXA specific entry point for secondary CPUs. This provides + * a holding pen into which all secondary cores are held until +we're + * ready for them to initialise. + */ +ENTRY(mmp_secondary_startup) + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #15 + adr r4, 1f + ldmia r4, {r5, r6} + sub r4, r4, r5 + add r6, r6, r4 +pen: ldr r7, [r6] + cmp r7, r0 + bne pen + + /* +* we've been released from the holding pen: secondary_stack +* should now contain the SVC stack for this core +*/ + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(mmp_secondary_startup) + + .align 2 +1: .long . + .long pen_release + + +/* + * Note: The following code is located into the .data
Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang wrote: > Add SMP support for pxa988. > > Signed-off-by: Neil Zhang > Signed-off-by: Chao Xie > --- > arch/arm/mach-mmp/Makefile |4 + > arch/arm/mach-mmp/common.h |2 + > arch/arm/mach-mmp/headsmp.S | 104 ++ > arch/arm/mach-mmp/mmpx-dt.c |1 + > arch/arm/mach-mmp/platsmp.c | 170 > +++ > arch/arm/mach-mmp/reset.c | 66 + > arch/arm/mach-mmp/reset.h | 29 +++ > 7 files changed, 376 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-mmp/headsmp.S > create mode 100644 arch/arm/mach-mmp/platsmp.c > create mode 100644 arch/arm/mach-mmp/reset.c > create mode 100644 arch/arm/mach-mmp/reset.h > > diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile > index b60065f..e7b6173 100644 > --- a/arch/arm/mach-mmp/Makefile > +++ b/arch/arm/mach-mmp/Makefile > @@ -9,6 +9,10 @@ obj-$(CONFIG_CPU_PXA168) += pxa168.o > obj-$(CONFIG_CPU_PXA910) += pxa910.o > obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o > > +ifeq ($(CONFIG_SMP),y) > +obj-$(CONFIG_CPU_PXA988) += platsmp.o headsmp.o reset.o > +endif > + You already select CONFIG_SMP if PXA988 is selected. There's no reason to check CONFIG_SMP in Makefile again. > ifeq ($(CONFIG_COMMON_CLK), ) > obj-y += clock.o > obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o > diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h > index 8c9b510..7496cd0 100644 > --- a/arch/arm/mach-mmp/common.h > +++ b/arch/arm/mach-mmp/common.h > @@ -1,5 +1,7 @@ > #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) > > +extern struct smp_operations mmp_smp_ops; > + > extern void timer_init(int irq); > > extern void __init icu_init_irq(void); > diff --git a/arch/arm/mach-mmp/headsmp.S b/arch/arm/mach-mmp/headsmp.S > new file mode 100644 > index 000..2b6177e > --- /dev/null > +++ b/arch/arm/mach-mmp/headsmp.S > @@ -0,0 +1,104 @@ > +/* > + * linux/arch/arm/mach-mmp/headsmp.S > + * > + * Copyright (C) 2012 Marvell, Inc. > + * > + * Author: Neil Zhang > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * 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. > + * > + */ > +#include > +#include > +#include > +#include > +#include > +#include > + > + __CPUINIT > + > +/* > + * Marvell specific entry point for secondary CPUs. > + * The secondary kernel init calls v7_flush_dcache_all before it enables > + * the L1; however, the L1 comes out of reset in an undefined state, so > + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch > + * of cache lines with uninitialized data and uninitialized tags to get > + * written out to memory, which does really unpleasant things to the main > + * processor. We fix this by performing an invalidate, rather than a > + * clean + invalidate for secondary core, before jumping into the kernel. > + * > + * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs > + * to be called for both secondary cores startup and primary core resume > + * procedures. > + */ > + .align L1_CACHE_SHIFT > + > + > +/* > + * PXA specific entry point for secondary CPUs. This provides > + * a "holding pen" into which all secondary cores are held until we're > + * ready for them to initialise. > + */ > +ENTRY(mmp_secondary_startup) > + mrc p15, 0, r0, c0, c0, 5 > + and r0, r0, #15 > + adr r4, 1f > + ldmia r4, {r5, r6} > + sub r4, r4, r5 > + add r6, r6, r4 > +pen: ldr r7, [r6] > + cmp r7, r0 > + bne pen > + > + /* > +* we've been released from the holding pen: secondary_stack > +* should now contain the SVC stack for this core > +*/ > + bl v7_invalidate_l1 > + b secondary_startup > +ENDPROC(mmp_secondary_startup) > + > + .align 2 > +1: .long . > + .long pen_release > + > + > +/* > + * Note: The following code is located into the .data section. This is to > + * allow sw_reset_flag and cpu_plugin_handler to be accessed with a > + * relative load while we can't rely on any MMU translation. > + * Reference from: arch/arm/kernel/sleep.S > + */ > + > + .data > + .align > + > +/* > + * ROM code jumps to this function while waking up from CPU > + * OFF or software reset state. Physical address of the function is > + * stored at CA9_WARM_RESET_VECTOR while system is bring up. > + */ > +ENTRY(mmp_cpu_reset_entry) > + adr r1, mmp_entry_vectors
Re: [PATCH 4/4] ARM: mmp: add SMP support for pxa988
On Thu, Apr 11, 2013 at 11:39 AM, Neil Zhang zhan...@marvell.com wrote: Add SMP support for pxa988. Signed-off-by: Neil Zhang zhan...@marvell.com Signed-off-by: Chao Xie chao@marvell.com --- arch/arm/mach-mmp/Makefile |4 + arch/arm/mach-mmp/common.h |2 + arch/arm/mach-mmp/headsmp.S | 104 ++ arch/arm/mach-mmp/mmpx-dt.c |1 + arch/arm/mach-mmp/platsmp.c | 170 +++ arch/arm/mach-mmp/reset.c | 66 + arch/arm/mach-mmp/reset.h | 29 +++ 7 files changed, 376 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-mmp/headsmp.S create mode 100644 arch/arm/mach-mmp/platsmp.c create mode 100644 arch/arm/mach-mmp/reset.c create mode 100644 arch/arm/mach-mmp/reset.h diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index b60065f..e7b6173 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -9,6 +9,10 @@ obj-$(CONFIG_CPU_PXA168) += pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_CPU_PXA988) += platsmp.o headsmp.o reset.o +endif + You already select CONFIG_SMP if PXA988 is selected. There's no reason to check CONFIG_SMP in Makefile again. ifeq ($(CONFIG_COMMON_CLK), ) obj-y += clock.o obj-$(CONFIG_CPU_PXA168) += clock-pxa168.o diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h index 8c9b510..7496cd0 100644 --- a/arch/arm/mach-mmp/common.h +++ b/arch/arm/mach-mmp/common.h @@ -1,5 +1,7 @@ #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) +extern struct smp_operations mmp_smp_ops; + extern void timer_init(int irq); extern void __init icu_init_irq(void); diff --git a/arch/arm/mach-mmp/headsmp.S b/arch/arm/mach-mmp/headsmp.S new file mode 100644 index 000..2b6177e --- /dev/null +++ b/arch/arm/mach-mmp/headsmp.S @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/mach-mmp/headsmp.S + * + * Copyright (C) 2012 Marvell, Inc. + * + * Author: Neil Zhang zhan...@marvell.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ +#include linux/linkage.h +#include linux/init.h +#include asm/memory.h +#include asm/cache.h +#include asm/assembler.h +#include mach/addr-map.h + + __CPUINIT + +/* + * Marvell specific entry point for secondary CPUs. + * The secondary kernel init calls v7_flush_dcache_all before it enables + * the L1; however, the L1 comes out of reset in an undefined state, so + * the clean + invalidate performed by v7_flush_dcache_all causes a bunch + * of cache lines with uninitialized data and uninitialized tags to get + * written out to memory, which does really unpleasant things to the main + * processor. We fix this by performing an invalidate, rather than a + * clean + invalidate for secondary core, before jumping into the kernel. + * + * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs + * to be called for both secondary cores startup and primary core resume + * procedures. + */ + .align L1_CACHE_SHIFT + + +/* + * PXA specific entry point for secondary CPUs. This provides + * a holding pen into which all secondary cores are held until we're + * ready for them to initialise. + */ +ENTRY(mmp_secondary_startup) + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #15 + adr r4, 1f + ldmia r4, {r5, r6} + sub r4, r4, r5 + add r6, r6, r4 +pen: ldr r7, [r6] + cmp r7, r0 + bne pen + + /* +* we've been released from the holding pen: secondary_stack +* should now contain the SVC stack for this core +*/ + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(mmp_secondary_startup) + + .align 2 +1: .long . + .long pen_release + + +/* + * Note: The following code is located into the .data section. This is to + * allow sw_reset_flag and cpu_plugin_handler to be accessed with a + * relative load while we can't rely on any MMU translation. + * Reference from: arch/arm/kernel/sleep.S + */ + + .data + .align + +/* + * ROM code jumps to this function while waking up from CPU + * OFF or software reset state. Physical address of the function is + * stored at CA9_WARM_RESET_VECTOR while system is bring up. + */ +ENTRY(mmp_cpu_reset_entry) + adr r1,