ARM: mpu: add MPU initialisation for secondary cores
authorJonathan Austin <jonathan.austin@arm.com>
Fri, 22 Feb 2013 18:51:30 +0000 (18:51 +0000)
committerJonathan Austin <jonathan.austin@arm.com>
Fri, 7 Jun 2013 16:02:53 +0000 (17:02 +0100)
The MPU initialisation on the primary core is performed in two stages, one
minimal stage to ensure the CPU can boot and a second one after
sanity_check_meminfo. As the memory configuration is known by the time we
boot secondary cores only a single step is necessary, provided the values
for DRSR are passed to secondaries.

This patch implements this arrangement. The configuration generated for the
MPU regions is made available to the secondary core, which can then use the
asm MPU intialisation code to program a complete region configuration.

This is necessary for SMP configurations without an MMU, as the MPU
initialisation is the only way to ensure that memory is specified as
'shared'.

Signed-off-by: Jonathan Austin <jonathan.austin@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
CC: Nicolas Pitre <nico@linaro.org>
arch/arm/include/asm/smp.h
arch/arm/kernel/head-nommu.S
arch/arm/kernel/smp.c

index d3a22bebe6ce415c952cbb631929aa1a37157ea6..a8cae71caceb3fb89c1ec949063b7a0d621dbdca 100644 (file)
@@ -65,7 +65,10 @@ asmlinkage void secondary_start_kernel(void);
  * Initial data for bringing up a secondary CPU.
  */
 struct secondary_data {
-       unsigned long pgdir;
+       union {
+               unsigned long mpu_rgn_szr;
+               unsigned long pgdir;
+       };
        unsigned long swapper_pg_dir;
        void *stack;
 };
index 659912c495710e0391f6e604618081fdad17a808..13741d004de5c9b1c5706f72f7e44714c1e5c748 100644 (file)
@@ -107,6 +107,13 @@ ENTRY(secondary_startup)
 
        adr     r4, __secondary_data
        ldmia   r4, {r7, r12}
+
+#ifdef CONFIG_ARM_MPU
+       /* Use MPU region info supplied by __cpu_up */
+       ldr     r6, [r7]                        @ get secondary_data.mpu_szr
+       bl      __setup_mpu                     @ Initialize the MPU
+#endif
+
        adr     lr, BSYM(__after_proc_init)     @ return address
        mov     r13, r12                        @ __secondary_switched address
  ARM(  add     pc, r10, #PROCINFO_INITFUNC     )
index 44d1c00dc45f1a000817902b49109f0a7c616658..e17d9346baee6977f4e11fdcf65533994b521d62 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/smp_plat.h>
 #include <asm/virt.h>
 #include <asm/mach/arch.h>
+#include <asm/mpu.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
@@ -87,6 +88,10 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
         * its stack and the page tables.
         */
        secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
+#ifdef CONFIG_ARM_MPU
+       secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr;
+#endif
+
 #ifdef CONFIG_MMU
        secondary_data.pgdir = virt_to_phys(idmap_pgd);
        secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
@@ -114,9 +119,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
                pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
        }
 
-       secondary_data.stack = NULL;
-       secondary_data.pgdir = 0;
 
+       memset(&secondary_data, 0, sizeof(secondary_data));
        return ret;
 }