[PATCH] arm: 8-byte align stack to avoid LDRD/STRD problems
Sascha Hauer
s.hauer at pengutronix.de
Thu Oct 29 05:14:41 EDT 2009
Hi,
On Thu, Oct 29, 2009 at 09:26:27AM +0100, Simon Kagstrom wrote:
> Regular U-boot recently added this patch,
>
> http://git.denx.de/?p=u-boot.git;a=commitdiff;h=8003c361deec3ee651451662efd05352f1abdd40
>
> and while browsing the U-boot v2 tree (the layout looks very nice
> indeed!), I saw that it was leaving the stack unaligned. This caused me
> a lot of problems in regular U-boot and quite a bit of headache, so it
> would be nice to have it fixed in v2 as well.
>
> This is completely untested, and if I misunderstood something about the
> code so that the stack is aligned elsewhere, please ignore the patch.
Hm,
_STACK_START:
.word STACK_BASE + STACK_SIZE - 4
[...]
ldr r0, _STACK_START
sub sp, r0, #12 /* leave 3 words for abort-stack */
STACK_BASE and STACK_SIZE should be aligned, so the stack pointer
should also be 16byte aligned. Of course it is aligned by accident which
is not very good.
Instead of using another instruction for ensuring alignment how about
saving some instructions. I'm not sure about the abort stack though.
Does it have to be 8byte aligned aswell?
Sascha
diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S
index 4741bb8..4a5a1b1 100644
--- a/arch/arm/cpu/exceptions.S
+++ b/arch/arm/cpu/exceptions.S
@@ -37,8 +37,8 @@
#define MODE_SVC 0x13
#define I_BIT 0x80
-_STACK_START:
- .word STACK_BASE + STACK_SIZE - 4
+_ABORT_STACK_START:
+ .word STACK_TOP - 12
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
@@ -48,8 +48,7 @@ _STACK_START:
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
- ldr r2, _STACK_START
- sub r2, r2, #(8) @ set base 2 words into abort stack
+ ldr r2, _ABORT_STACK_START
ldmia r2, {r2 - r3} @ get pc, cpsr
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
@@ -80,8 +79,7 @@ _STACK_START:
.endm
.macro get_bad_stack
- ldr r13, _STACK_START
- sub r13, r13, #(8) @ reserved a couple spots in abort stack
+ ldr r13, _ABORT_STACK_START
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
diff --git a/arch/arm/cpu/start-arm.S b/arch/arm/cpu/start-arm.S
index 408944a..7560674 100644
--- a/arch/arm/cpu/start-arm.S
+++ b/arch/arm/cpu/start-arm.S
@@ -102,8 +102,13 @@ _TEXT_BASE:
_MALLOC_BASE:
.word MALLOC_BASE
+/* Leave 3 words for abort-stack, preserve 8 byte alignment */
_STACK_START:
- .word STACK_BASE + STACK_SIZE - 4
+ .word STACK_TOP - 16
+
+#if (STACK_TOP - 16) & 0x7
+#error stack is not 8 byte aligned
+#endif
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory */
@@ -229,8 +234,7 @@ copy_loop:
/* Set up the stack */
stack_setup:
- ldr r0, _STACK_START
- sub sp, r0, #12 /* leave 3 words for abort-stack */
+ ldr sp, _STACK_START
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
diff --git a/include/asm-generic/memory_layout.h b/include/asm-generic/memory_layout.h
index 941cd42..df26902 100644
--- a/include/asm-generic/memory_layout.h
+++ b/include/asm-generic/memory_layout.h
@@ -5,6 +5,7 @@
#define MALLOC_BASE (TEXT_BASE - CONFIG_MALLOC_SIZE)
#define STACK_BASE (TEXT_BASE - CONFIG_MALLOC_SIZE - CONFIG_STACK_SIZE)
+#define STACK_TOP (STACK_BASE + CONFIG_STACK_SIZE)
#else
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the u-boot-v2
mailing list