diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2011-11-11 14:06:10 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2011-11-11 14:06:10 +0000 |
commit | d5413654bddd0be978dd37d020cc46e08a085be9 (patch) | |
tree | 026ea8a64f4cf0143b897addc8083698d5898e3d /nuttx/arch/arm/src/common | |
parent | 567572973dfc30c29cad505b0f41597432e8c870 (diff) |
Fix stack alignment for EABI floating point
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4089 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch/arm/src/common')
-rw-r--r-- | nuttx/arch/arm/src/common/up_createstack.c | 99 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_usestack.c | 49 |
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 0d78d9ce9d..068924b4b6 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 822f051689..f46be0cc90 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 */ |