summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/common
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-11-11 14:06:10 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-11-11 14:06:10 +0000
commitb30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2 (patch)
tree026ea8a64f4cf0143b897addc8083698d5898e3d /nuttx/arch/arm/src/common
parentf0a1251a7b4c2e9dee486f95db2c6e87a06274bd (diff)
downloadpx4-nuttx-b30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2.tar.gz
px4-nuttx-b30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2.tar.bz2
px4-nuttx-b30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2.zip
Fix stack alignment for EABI floating point
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4089 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/common')
-rw-r--r--nuttx/arch/arm/src/common/up_createstack.c99
-rw-r--r--nuttx/arch/arm/src/common/up_usestack.c49
2 files changed, 107 insertions, 41 deletions
diff --git a/nuttx/arch/arm/src/common/up_createstack.c b/nuttx/arch/arm/src/common/up_createstack.c
index 0d78d9ce9..068924b4b 100644
--- a/nuttx/arch/arm/src/common/up_createstack.c
+++ b/nuttx/arch/arm/src/common/up_createstack.c
@@ -52,6 +52,33 @@
#include "up_internal.h"
/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* ARM requires at least a 4-byte stack alignment. For use with EABI and
+ * floating point, the stack must be aligned to 8-byte addresses.
+ */
+
+#ifndef CONFIG_STACK_ALIGNMENT
+
+/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you
+ * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly!
+ */
+
+# ifdef __ARM_EABI__
+# define CONFIG_STACK_ALIGNMENT 8
+# else
+# define CONFIG_STACK_ALIGNMENT 4
+# endif
+#endif
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
* Private Types
****************************************************************************/
@@ -110,54 +137,60 @@ int up_create_stack(_TCB *tcb, size_t stack_size)
tcb->stack_alloc_ptr = NULL;
}
- if (!tcb->stack_alloc_ptr)
- {
+ if (!tcb->stack_alloc_ptr)
+ {
#ifdef CONFIG_DEBUG
- tcb->stack_alloc_ptr = (uint32_t*)kzalloc(stack_size);
+ tcb->stack_alloc_ptr = (uint32_t*)kzalloc(stack_size);
#else
- tcb->stack_alloc_ptr = (uint32_t*)kmalloc(stack_size);
+ tcb->stack_alloc_ptr = (uint32_t*)kmalloc(stack_size);
#endif
- }
+ }
- if (tcb->stack_alloc_ptr)
- {
- size_t top_of_stack;
- size_t size_of_stack;
+ if (tcb->stack_alloc_ptr)
+ {
+ size_t top_of_stack;
+ size_t size_of_stack;
+
+ /* The ARM uses a push-down stack: the stack grows toward lower
+ * addresses in memory. The stack pointer register, points to
+ * the lowest, valid work address (the "top" of the stack). Items
+ * on the stack are referenced as positive word offsets from sp.
+ */
- /* The ARM uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
- */
+ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
+ /* The ARM stack must be aligned; 4 byte alignment for OABI and
+ * 8-byte alignment for EABI. If necessary top_of_stack must be
+ * rounded down to the next boundary
+ */
- /* The ARM stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
- */
+ top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
+ /* The size of the stack in bytes is then the difference between
+ * the top and the bottom of the stack (+4 because if the top
+ * is the same as the bottom, then the size is one 32-bit element).
+ * The size need not be aligned.
+ */
- /* Save the adjusted stack values in the _TCB */
+ size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
- tcb->adj_stack_ptr = (uint32_t*)top_of_stack;
- tcb->adj_stack_size = size_of_stack;
+ /* Save the adjusted stack values in the _TCB */
- /* If stack debug is enabled, then fill the stack with a
- * recognizable value that we can use later to test for high
- * water marks.
- */
+ tcb->adj_stack_ptr = (uint32_t*)top_of_stack;
+ tcb->adj_stack_size = size_of_stack;
+
+ /* If stack debug is enabled, then fill the stack with a
+ * recognizable value that we can use later to test for high
+ * water marks.
+ */
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
- memset32(tcb->stack_alloc_ptr, 0xDEADBEEF, tcb->adj_stack_size/4);
+ memset32(tcb->stack_alloc_ptr, 0xDEADBEEF, tcb->adj_stack_size/4);
#endif
- up_ledon(LED_STACKCREATED);
- return OK;
- }
+ up_ledon(LED_STACKCREATED);
+ return OK;
+ }
return ERROR;
}
diff --git a/nuttx/arch/arm/src/common/up_usestack.c b/nuttx/arch/arm/src/common/up_usestack.c
index 822f05168..f46be0cc9 100644
--- a/nuttx/arch/arm/src/common/up_usestack.c
+++ b/nuttx/arch/arm/src/common/up_usestack.c
@@ -50,6 +50,33 @@
#include "up_internal.h"
/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* ARM requires at least a 4-byte stack alignment. For use with EABI and
+ * floating point, the stack must be aligned to 8-byte addresses.
+ */
+
+#ifndef CONFIG_STACK_ALIGNMENT
+
+/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you
+ * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly!
+ */
+
+# ifdef __ARM_EABI__
+# define CONFIG_STACK_ALIGNMENT 8
+# else
+# define CONFIG_STACK_ALIGNMENT 4
+# endif
+#endif
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
* Private Types
****************************************************************************/
@@ -96,21 +123,27 @@ int up_use_stack(_TCB *tcb, void *stack, size_t stack_size)
tcb->stack_alloc_ptr = stack;
- /* The ARM uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
+ /* The ARM uses a push-down stack: the stack grows toward lower addresses
+ * in memory. The stack pointer register, points to the lowest, valid
+ * work address (the "top" of the stack). Items on the stack are
* referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The ARM stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* The ARM stack must be aligned; 4 byte alignment for OABI and 8-byte
+ * alignment for EABI. If necessary top_of_stack must be rounded down
+ * to the next boundary
+ */
+
+ top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
+
+ /* The size of the stack in bytes is then the difference between
+ * the top and the bottom of the stack (+4 because if the top
+ * is the same as the bottom, then the size is one 32-bit element).
+ * The size need not be aligned.
*/
- top_of_stack &= ~3;
size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
/* Save the adjusted stack values in the _TCB */