summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/common/up_usestack.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/arm/src/common/up_usestack.c')
-rw-r--r--nuttx/arch/arm/src/common/up_usestack.c49
1 files changed, 41 insertions, 8 deletions
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 */