diff options
author | Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> | 2015-11-04 11:08:37 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-11-16 13:34:38 -0500 |
commit | a4124e7296000242243996e1ae2601cfadf276a5 (patch) | |
tree | 93b53a9c4bedc358c6c53ec0a7b98344bf612c53 | |
parent | 440ee365d30adbcd9a97fba9cd629cedb7e9b7cb (diff) |
ARM: 8451/1: v7-M: Set an early stack for __v7m_setup
On ARM v7-M, when PROCINFO_INITFUNC (__v7m_setup) is called,
a stack is needed before calling the supervisor call (SVC),
which is used by the supervisor call to save the context.
Currently, __v7m_setup() prepares a temporary stack in the .text.init
section, which is is broken if the kernel is executing directly from
read-only memory.
In particular, this is the case for LPC43xx, which allows
to execute the kernel in-place from a serial flash through its SPIFI
controller.
This commit fixes the issue by seting an early stack to its usual location.
Also, __v7m_setup() is currently saving and restoring the previous
stack. That was bogus, because there's no stack previously set,
so this commit removes it.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mm/proc-v7m.S | 14 |
1 files changed, 5 insertions, 9 deletions
diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index 67d9209077c6..7229d8d0be1a 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <asm/assembler.h> | 14 | #include <asm/assembler.h> |
15 | #include <asm/memory.h> | ||
15 | #include <asm/v7m.h> | 16 | #include <asm/v7m.h> |
16 | #include "proc-macros.S" | 17 | #include "proc-macros.S" |
17 | 18 | ||
@@ -97,19 +98,19 @@ __v7m_setup: | |||
97 | mov r5, #0x00800000 | 98 | mov r5, #0x00800000 |
98 | str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority | 99 | str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority |
99 | 100 | ||
100 | @ SVC to run the kernel in this mode | 101 | @ SVC to switch to handler mode. Notice that this requires sp to |
102 | @ point to writeable memory because the processor saves | ||
103 | @ some registers to the stack. | ||
101 | badr r1, 1f | 104 | badr r1, 1f |
102 | ldr r5, [r12, #11 * 4] @ read the SVC vector entry | 105 | ldr r5, [r12, #11 * 4] @ read the SVC vector entry |
103 | str r1, [r12, #11 * 4] @ write the temporary SVC vector entry | 106 | str r1, [r12, #11 * 4] @ write the temporary SVC vector entry |
104 | mov r6, lr @ save LR | 107 | mov r6, lr @ save LR |
105 | mov r7, sp @ save SP | 108 | ldr sp, =init_thread_union + THREAD_START_SP |
106 | ldr sp, =__v7m_setup_stack_top | ||
107 | cpsie i | 109 | cpsie i |
108 | svc #0 | 110 | svc #0 |
109 | 1: cpsid i | 111 | 1: cpsid i |
110 | str r5, [r12, #11 * 4] @ restore the original SVC vector entry | 112 | str r5, [r12, #11 * 4] @ restore the original SVC vector entry |
111 | mov lr, r6 @ restore LR | 113 | mov lr, r6 @ restore LR |
112 | mov sp, r7 @ restore SP | ||
113 | 114 | ||
114 | @ Special-purpose control register | 115 | @ Special-purpose control register |
115 | mov r1, #1 | 116 | mov r1, #1 |
@@ -123,11 +124,6 @@ __v7m_setup: | |||
123 | ret lr | 124 | ret lr |
124 | ENDPROC(__v7m_setup) | 125 | ENDPROC(__v7m_setup) |
125 | 126 | ||
126 | .align 2 | ||
127 | __v7m_setup_stack: | ||
128 | .space 4 * 8 @ 8 registers | ||
129 | __v7m_setup_stack_top: | ||
130 | |||
131 | define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 | 127 | define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 |
132 | 128 | ||
133 | .section ".rodata" | 129 | .section ".rodata" |