aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Austin <jonathan.austin@arm.com>2013-02-22 13:51:30 -0500
committerJonathan Austin <jonathan.austin@arm.com>2013-06-07 12:02:53 -0400
commiteb08375ea66e63c5e11dea69b43c5633d531ce81 (patch)
treecb15407c3e6c2a2eaced0a9662c947136ed7a1b3
parent9a271567fe9980a7e7ded0c6250d56200c3678ee (diff)
ARM: mpu: add MPU initialisation for secondary cores
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>
-rw-r--r--arch/arm/include/asm/smp.h5
-rw-r--r--arch/arm/kernel/head-nommu.S7
-rw-r--r--arch/arm/kernel/smp.c8
3 files changed, 17 insertions, 3 deletions
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index d3a22bebe6ce..a8cae71caceb 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -65,7 +65,10 @@ asmlinkage void secondary_start_kernel(void);
65 * Initial data for bringing up a secondary CPU. 65 * Initial data for bringing up a secondary CPU.
66 */ 66 */
67struct secondary_data { 67struct secondary_data {
68 unsigned long pgdir; 68 union {
69 unsigned long mpu_rgn_szr;
70 unsigned long pgdir;
71 };
69 unsigned long swapper_pg_dir; 72 unsigned long swapper_pg_dir;
70 void *stack; 73 void *stack;
71}; 74};
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 659912c49571..13741d004de5 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -107,6 +107,13 @@ ENTRY(secondary_startup)
107 107
108 adr r4, __secondary_data 108 adr r4, __secondary_data
109 ldmia r4, {r7, r12} 109 ldmia r4, {r7, r12}
110
111#ifdef CONFIG_ARM_MPU
112 /* Use MPU region info supplied by __cpu_up */
113 ldr r6, [r7] @ get secondary_data.mpu_szr
114 bl __setup_mpu @ Initialize the MPU
115#endif
116
110 adr lr, BSYM(__after_proc_init) @ return address 117 adr lr, BSYM(__after_proc_init) @ return address
111 mov r13, r12 @ __secondary_switched address 118 mov r13, r12 @ __secondary_switched address
112 ARM( add pc, r10, #PROCINFO_INITFUNC ) 119 ARM( add pc, r10, #PROCINFO_INITFUNC )
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 44d1c00dc45f..e17d9346baee 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -45,6 +45,7 @@
45#include <asm/smp_plat.h> 45#include <asm/smp_plat.h>
46#include <asm/virt.h> 46#include <asm/virt.h>
47#include <asm/mach/arch.h> 47#include <asm/mach/arch.h>
48#include <asm/mpu.h>
48 49
49/* 50/*
50 * as from 2.5, kernels no longer have an init_tasks structure 51 * 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)
87 * its stack and the page tables. 88 * its stack and the page tables.
88 */ 89 */
89 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; 90 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
91#ifdef CONFIG_ARM_MPU
92 secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr;
93#endif
94
90#ifdef CONFIG_MMU 95#ifdef CONFIG_MMU
91 secondary_data.pgdir = virt_to_phys(idmap_pgd); 96 secondary_data.pgdir = virt_to_phys(idmap_pgd);
92 secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); 97 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)
114 pr_err("CPU%u: failed to boot: %d\n", cpu, ret); 119 pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
115 } 120 }
116 121
117 secondary_data.stack = NULL;
118 secondary_data.pgdir = 0;
119 122
123 memset(&secondary_data, 0, sizeof(secondary_data));
120 return ret; 124 return ret;
121} 125}
122 126