summaryrefslogtreecommitdiff
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
parentf0a1251a7b4c2e9dee486f95db2c6e87a06274bd (diff)
downloadnuttx-b30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2.tar.gz
nuttx-b30b365353a28dc7cc06afe13e3d1ab3f5a3b2b2.tar.bz2
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
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html7
-rw-r--r--nuttx/arch/arm/src/common/up_createstack.c99
-rw-r--r--nuttx/arch/arm/src/common/up_usestack.c49
-rw-r--r--nuttx/configs/README.txt6
5 files changed, 121 insertions, 43 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index b752b8ec3..2f83184f6 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -2194,4 +2194,7 @@
support a file system (such as NXFFS). (Contributed by Hal Glenn).
* include/nuttx/rgbcolors.h: More fixes to RGB color conversion
macros.
+ * arch/arm/src/common/up_createstack.c and up_usestack.c: For ARM EABI
+ the stack must be aligned to 8-byte boundaries. This is necessary for
+ passing aligned floating point values under EABI.
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 7d190a146..f4c699541 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -5114,7 +5114,12 @@ build
some functions into RAM, either for better performance or for errata workarounds.
</li>
<li>
- <code>CONFIG_STACK_POINTER</code>: The initial stack pointer
+ <code>CONFIG_STACK_POINTER</code>: The initial stack pointer (may not be supported
+ in all architectures).
+ </li>
+ <li>
+ <code>CONFIG_STACK_ALIGNMENT</code>: Set if the your application has specific
+ stack alignment requirements (may not be supported in all architectures).
</li>
<li>
<code>CONFIG_IDLETHREAD_STACKSIZE</code>: The size of the initial stack.
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 */
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index f19fa28ee..46b41d1ab 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -1148,7 +1148,11 @@ defconfig -- This is a configuration file similar to the Linux
but copy themselves entirely into RAM for better performance.
CONFIG_BOOT_RAMFUNCS - Other configurations may copy just some functions
into RAM, either for better performance or for errata workarounds.
- CONFIG_STACK_POINTER - The initial stack pointer
+ CONFIG_STACK_POINTER - The initial stack pointer (may not be supported
+ in all architectures).
+ CONFIG_STACK_ALIGNMENT - Set if the your application has specific
+ stack alignment requirements (may not be supported
+ in all architectures).
CONFIG_IDLETHREAD_STACKSIZE - The size of the initial stack.
This is the thread that (1) performs the inital boot of the system up
to the point where user_start() is spawned, and (2) there after is the