diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c index ac5d63787e..025aa5844f 100644 --- a/arch/arm/src/common/arm_createstack.c +++ b/arch/arm/src/common/arm_createstack.c @@ -84,8 +84,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - stack_size = STACK_ALIGN_UP(stack_size); - #ifdef CONFIG_TLS_ALIGNED /* The allocated stack size must not exceed the maximum possible for the * TLS feature. @@ -138,14 +136,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (ttype == TCB_FLAG_TTYPE_KERNEL) { - tcb->stack_alloc_ptr = kmm_memalign(STACK_ALIGNMENT, stack_size); + tcb->stack_alloc_ptr = kmm_malloc(stack_size); } else #endif { /* Use the user-space allocator if this is a task or pthread */ - tcb->stack_alloc_ptr = kumm_memalign(STACK_ALIGNMENT, stack_size); + tcb->stack_alloc_ptr = kumm_malloc(stack_size); } #endif /* CONFIG_TLS_ALIGNED */ @@ -163,6 +161,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { + uintptr_t top_of_stack; + size_t size_of_stack; + /* The ARM uses a "full descending" stack: * the stack grows toward lower addresses in memory. * The stack pointer register points to the last pushed item in @@ -170,14 +171,17 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * Items on the stack are referenced as positive word offsets from sp. */ - /* Since both stack_alloc_ptr and stack_size are in - * STACK_ALIGNMENT, and the stack ptr is decremented before - * the first write, we can directly save our variables to struct - * tcb_s. - */ + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + + /* Align the top of stack to STACK_ALIGNMENT. */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_size = stack_size; tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = size_of_stack; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a diff --git a/arch/ceva/src/common/up_createstack.c b/arch/ceva/src/common/up_createstack.c index f9e75137d4..0868af0778 100644 --- a/arch/ceva/src/common/up_createstack.c +++ b/arch/ceva/src/common/up_createstack.c @@ -179,7 +179,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - FAR void *top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* The CEVA uses a push-down stack: the stack grows toward lower @@ -193,12 +193,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * boundary */ - size_of_stack = STACK_ALIGN_DOWN(stack_size); - top_of_stack = tcb->stack_alloc_ptr + size_of_stack; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; /* Save the adjusted stack values in the struct tcb_s */ - tcb->stack_base_ptr = top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; #ifdef CONFIG_STACK_COLORATION diff --git a/arch/ceva/src/common/up_stackframe.c b/arch/ceva/src/common/up_stackframe.c index 12ce130af4..9c142b4711 100644 --- a/arch/ceva/src/common/up_stackframe.c +++ b/arch/ceva/src/common/up_stackframe.c @@ -67,7 +67,7 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { - FAR void *topaddr; + FAR void *ret; /* Align the frame_size */ @@ -82,15 +82,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) /* Save the adjusted stack values in the struct tcb_s */ - topaddr = tcb->stack_base_ptr - frame_size; - tcb->stack_base_ptr = topaddr; + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; tcb->adj_stack_size -= frame_size; - /* Reinitialize the task state after the stack is adjusted */ - - up_initial_state(tcb); - /* And return the pointer to the allocated region */ - return topaddr; + return ret; } diff --git a/arch/ceva/src/common/up_usestack.c b/arch/ceva/src/common/up_usestack.c index 85e1886629..0be0d51353 100644 --- a/arch/ceva/src/common/up_usestack.c +++ b/arch/ceva/src/common/up_usestack.c @@ -66,7 +66,7 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { - FAR void *top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS @@ -101,12 +101,13 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) * boundary */ - size_of_stack = STACK_ALIGN_DOWN(stack_size); - top_of_stack = tcb->stack_alloc_ptr + size_of_stack; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; /* Save the adjusted stack values in the struct tcb_s */ - tcb->stack_base_ptr = top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; #ifdef CONFIG_STACK_COLORATION diff --git a/arch/misoc/src/lm32/lm32_usestack.c b/arch/misoc/src/lm32/lm32_usestack.c index ffc13c9cb3..47e3a1449d 100644 --- a/arch/misoc/src/lm32/lm32_usestack.c +++ b/arch/misoc/src/lm32/lm32_usestack.c @@ -34,6 +34,8 @@ #include #include +#include "lm32.h" + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -98,19 +100,21 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif - /* The i486 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. + /* LM32 uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. */ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; - /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary - * top_of_stack must be rounded down to the next boundary + /* The LM32 stack must be aligned at word (4 byte) boundaries; for + * floating point use, the stack must be aligned to 8-byte addresses. + * If necessary top_of_stack must be rounded down to the next + * boundary to meet these alignment requirements. */ - top_of_stack &= ~3; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; /* Save the adjusted stack values in the struct tcb_s */ diff --git a/arch/misoc/src/minerva/minerva_usestack.c b/arch/misoc/src/minerva/minerva_usestack.c index 6f30647464..00b5ea66f1 100644 --- a/arch/misoc/src/minerva/minerva_usestack.c +++ b/arch/misoc/src/minerva/minerva_usestack.c @@ -34,6 +34,8 @@ #include #include +#include "minerva.h" + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -98,19 +100,21 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif - /* The i486 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. + /* MINERVA uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. */ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; - /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary - * top_of_stack must be rounded down to the next boundary + /* The MINERVA stack must be aligned at word (4 byte) boundaries; for + * floating point use, the stack must be aligned to 8-byte addresses. + * If necessary top_of_stack must be rounded down to the next boundary + * to meet these alignment requirements. */ - top_of_stack &= ~3; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; /* Save the adjusted stack values in the struct tcb_s */ diff --git a/arch/or1k/src/common/up_usestack.c b/arch/or1k/src/common/up_usestack.c index e2740db43b..2e1993cb22 100644 --- a/arch/or1k/src/common/up_usestack.c +++ b/arch/or1k/src/common/up_usestack.c @@ -34,6 +34,8 @@ #include #include +#include "up_internal.h" + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -98,19 +100,8 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif - /* The i486 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 = (uintptr_t)tcb->stack_alloc_ptr + stack_size; - - /* The i486 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 &= ~3; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; /* Save the adjusted stack values in the struct tcb_s */ diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c index 558dbb14b7..6e540afd37 100644 --- a/arch/sim/src/sim/up_createstack.c +++ b/arch/sim/src/sim/up_createstack.c @@ -73,9 +73,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - FAR uint8_t *stack_alloc_ptr; - int ret = ERROR; - stack_size += CONFIG_SIM_STACKSIZE_ADJUSTMENT; #ifdef CONFIG_TLS_ALIGNED @@ -90,27 +87,49 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) } #endif - /* Move up to next even word boundary if necessary */ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ - size_t adj_stack_size = STACK_ALIGN_UP(stack_size); + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ - /* Allocate the memory for the stack */ + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + * If TLS is enabled, then we must allocate aligned stacks. + */ #ifdef CONFIG_TLS_ALIGNED - stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, adj_stack_size); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); #else - stack_alloc_ptr = kumm_malloc(adj_stack_size); + tcb->stack_alloc_ptr = kumm_malloc(stack_size); #endif + } - /* Was the allocation successful? */ + /* Did we successfully allocate a stack? */ - if (stack_alloc_ptr) + if (tcb->stack_alloc_ptr) { + uintptr_t top_of_stack; + size_t size_of_stack; + + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; + /* Save the values in the TCB */ - tcb->adj_stack_size = adj_stack_size; - tcb->stack_alloc_ptr = stack_alloc_ptr; - tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = size_of_stack; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a @@ -122,10 +141,10 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) #endif /* CONFIG_STACK_COLORATION */ tcb->flags |= TCB_FLAG_FREE_STACK; - ret = OK; + return OK; } - return ret; + return ERROR; } /**************************************************************************** diff --git a/arch/sim/src/sim/up_usestack.c b/arch/sim/src/sim/up_usestack.c index 0f45fbc9d5..1c23d4719a 100644 --- a/arch/sim/src/sim/up_usestack.c +++ b/arch/sim/src/sim/up_usestack.c @@ -69,24 +69,36 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { #if CONFIG_SIM_STACKSIZE_ADJUSTMENT == 0 - size_t adj_stack_size; + uintptr_t top_of_stack; + size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED /* Make certain that the user provided stack is properly aligned */ DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); #endif - /* Move down to next even word boundary within the pre-allocated stack - * memory, if necessary. - */ - adj_stack_size = STACK_ALIGN_DOWN(stack_size); + /* Is there already a stack allocated? */ - /* Save the values in the TCB */ + if (tcb->stack_alloc_ptr) + { + /* Yes.. Release the old stack allocation */ + + up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK); + } + + /* Save the new stack allocation */ - tcb->adj_stack_size = adj_stack_size; tcb->stack_alloc_ptr = stack; - tcb->stack_base_ptr = tcb->stack_alloc_ptr; + + /* Save the adjusted stack values in the struct tcb_s */ + + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr; + + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = size_of_stack; #if defined(CONFIG_STACK_COLORATION) /* If stack debug is enabled, then fill the stack with a diff --git a/arch/sparc/src/common/up_createstack.c b/arch/sparc/src/common/up_createstack.c index df9cb57e22..3dc94e69b8 100644 --- a/arch/sparc/src/common/up_createstack.c +++ b/arch/sparc/src/common/up_createstack.c @@ -105,14 +105,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (ttype == TCB_FLAG_TTYPE_KERNEL) { - tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + tcb->stack_alloc_ptr = kmm_malloc(stack_size); } else #endif { /* Use the user-space allocator if this is a task or pthread */ - tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + tcb->stack_alloc_ptr = kumm_malloc(stack_size); } #ifdef CONFIG_DEBUG_FEATURES