[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