diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c index b5b2c6752a3..7aee3e83102 100644 --- a/arch/arm/src/common/arm_usestack.c +++ b/arch/arm/src/common/arm_usestack.c @@ -49,7 +49,7 @@ /* Stack alignment macros */ -#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1) +#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) diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c index d54b2049fe6..859cb422e49 100644 --- a/arch/avr/src/avr/up_createstack.c +++ b/arch/avr/src/avr/up_createstack.c @@ -49,6 +49,7 @@ #include #include +#include #include #include "up_arch.h" @@ -100,6 +101,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -118,9 +137,42 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ - tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)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); + } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -160,6 +212,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR void *)top_of_stack; tcb->adj_stack_size = stack_size; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + #if defined(ARCH_HAVE_LEDS) board_autoled_on(LED_STACKCREATED); #endif diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c index 652e6010665..03d741d6098 100644 --- a/arch/avr/src/avr/up_usestack.c +++ b/arch/avr/src/avr/up_usestack.c @@ -47,6 +47,7 @@ #include #include +#include #include "up_internal.h" @@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { size_t top_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -112,11 +119,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ #ifdef CONFIG_STACK_COLORATION - memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); #endif - /* The AVR uses a push-down stack: the stack grows toward loweraddresses in - * memory. The stack pointer register, points to the lowest, valid work + /* The AVR 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. */ @@ -128,5 +135,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (FAR void *)top_of_stack; tcb->adj_stack_size = stack_size; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c index bcfb34847ac..8c6aba82d89 100644 --- a/arch/avr/src/avr32/up_createstack.c +++ b/arch/avr/src/avr32/up_createstack.c @@ -48,6 +48,7 @@ #include #include +#include #include #include @@ -105,6 +106,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -123,8 +142,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -139,6 +178,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -186,6 +226,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR void *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c index 8557f72b3e3..8a4986cf1f9 100644 --- a/arch/avr/src/avr32/up_usestack.c +++ b/arch/avr/src/avr32/up_usestack.c @@ -46,6 +46,7 @@ #include #include +#include #include "up_internal.h" @@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -112,7 +119,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ #ifdef CONFIG_STACK_COLORATION - memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); + memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); #endif /* The AVR32 uses a push-down stack: the stack grows @@ -137,5 +144,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (FAR void *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c index e0948f917de..5496859d053 100644 --- a/arch/hc/src/common/up_createstack.c +++ b/arch/hc/src/common/up_createstack.c @@ -46,6 +46,7 @@ #include #include +#include #include #include "up_arch.h" @@ -102,6 +103,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -120,8 +139,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -136,6 +175,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c index 4ecf5351f7b..d3d58368d59 100644 --- a/arch/hc/src/common/up_usestack.c +++ b/arch/hc/src/common/up_usestack.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "up_internal.h" @@ -93,6 +94,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) @@ -125,7 +132,14 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; + +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c index 1e1ba2840a7..bc57aba1f01 100644 --- a/arch/mips/src/common/mips_createstack.c +++ b/arch/mips/src/common/mips_createstack.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -123,6 +124,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -143,6 +162,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * then create a zeroed stack to make stack dumps easier to trace. */ +#ifdef CONFIG_TLS_ALIGNED +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -157,6 +195,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -199,13 +238,26 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) */ 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. + */ + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c index fcfd184dff1..dc52292c29f 100644 --- a/arch/mips/src/common/mips_usestack.c +++ b/arch/mips/src/common/mips_usestack.c @@ -65,7 +65,7 @@ /* Stack alignment macros */ -#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_MASK (STACK_ALIGNMENT - 1) #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) #define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) @@ -114,6 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -141,6 +147,13 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ 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. + */ + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ @@ -148,5 +161,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c index 12da119838c..6071440fba6 100644 --- a/arch/misoc/src/lm32/lm32_createstack.c +++ b/arch/misoc/src/lm32/lm32_createstack.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -123,6 +124,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -143,6 +162,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * then create a zeroed stack to make stack dumps easier to trace. */ +#ifdef CONFIG_TLS_ALIGNED +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -157,6 +195,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -206,6 +245,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c index c9d26ad2fd6..b493de14650 100644 --- a/arch/misoc/src/minerva/minerva_createstack.c +++ b/arch/misoc/src/minerva/minerva_createstack.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -115,6 +116,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -133,23 +152,44 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { - tcb->stack_alloc_ptr = (uint32_t *) kmm_malloc(stack_size); + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, 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 = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); } +#else /* CONFIG_TLS_ALIGNED */ +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)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); + } +#endif /* CONFIG_TLS_ALIGNED */ + #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -198,6 +238,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR uint32_t *) top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c index 78cfee262a3..ffa8d804a72 100644 --- a/arch/or1k/src/common/up_createstack.c +++ b/arch/or1k/src/common/up_createstack.c @@ -122,6 +122,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) stack_size += sizeof(struct tls_info_s); +#ifdef CONFIG_TLS_ALIGNED /* The allocated stack size must not exceed the maximum possible for the * TLS feature. */ @@ -131,6 +132,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { stack_size = TLS_MAXSTACK; } +#endif #endif /* Is there already a stack allocated of a different size? Because of @@ -154,7 +156,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * If TLS is enabled, then we must allocate aligned stacks. */ -#ifdef CONFIG_TLS +#ifdef CONFIG_TLS_ALIGNED #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -172,7 +174,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); } -#else /* CONFIG_TLS */ +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -187,7 +189,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } -#endif /* CONFIG_TLS */ +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c index bb6b974466a..88e672046c6 100644 --- a/arch/renesas/src/common/up_createstack.c +++ b/arch/renesas/src/common/up_createstack.c @@ -46,6 +46,7 @@ #include #include +#include #include #include "up_arch.h" @@ -102,6 +103,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -120,8 +139,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -136,6 +175,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c index c089e547337..f7525e8c186 100644 --- a/arch/renesas/src/common/up_usestack.c +++ b/arch/renesas/src/common/up_usestack.c @@ -46,6 +46,7 @@ #include #include +#include #include "up_internal.h" @@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -127,5 +134,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c index da674e56cbb..449fec64f7e 100644 --- a/arch/risc-v/src/common/riscv_createstack.c +++ b/arch/risc-v/src/common/riscv_createstack.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -123,6 +124,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -141,8 +160,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -157,6 +196,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -172,10 +212,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { +#if defined(CONFIG_TLS) && defined(CONFIG_STACK_COLORATION) + uintptr_t stack_base; +#endif size_t top_of_stack; size_t size_of_stack; - /* MIPS uses a push-down stack: the stack grows toward lower + /* RISCV 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. @@ -197,13 +240,32 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; - /* Yes.. If stack debug is enabled, then fill the stack with a +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); + +#ifdef CONFIG_STACK_COLORATION + /* If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ + stack_base = (uintptr_t)tcb->stack_alloc_ptr + + sizeof(struct tls_info_s); + stack_size = tcb->adj_stack_size - + sizeof(struct tls_info_s); + riscv_stack_color((FAR void *)stack_base, stack_size); + +#endif /* CONFIG_STACK_COLORATION */ +#else /* CONFIG_TLS */ #ifdef CONFIG_STACK_COLORATION - up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size); + /* If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + + riscv_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size); #endif board_autoled_on(LED_STACKCREATED); @@ -214,7 +276,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) } /**************************************************************************** - * Name: up_stack_color + * Name: riscv_stack_color * * Description: * Write a well know value into the stack @@ -222,7 +284,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) ****************************************************************************/ #ifdef CONFIG_STACK_COLORATION -void up_stack_color(FAR void *stackbase, size_t nbytes) +void riscv_stack_color(FAR void *stackbase, size_t nbytes) { /* Take extra care that we do not write outsize the stack boundaries */ diff --git a/arch/risc-v/src/common/riscv_usestack.c b/arch/risc-v/src/common/riscv_usestack.c index ec033a28714..8da809d3356 100644 --- a/arch/risc-v/src/common/riscv_usestack.c +++ b/arch/risc-v/src/common/riscv_usestack.c @@ -46,6 +46,7 @@ #include #include +#include #include "riscv_internal.h" @@ -114,6 +115,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -148,5 +155,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (uintptr_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c index 20b648646b3..7e9a3081620 100644 --- a/arch/x86/src/i486/up_createstack.c +++ b/arch/x86/src/i486/up_createstack.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -104,6 +105,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -122,8 +141,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -138,6 +177,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c index 59221bedd6b..347d48c9228 100644 --- a/arch/x86/src/i486/up_usestack.c +++ b/arch/x86/src/i486/up_usestack.c @@ -46,6 +46,7 @@ #include #include +#include #include "up_internal.h" @@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -107,8 +114,8 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->stack_alloc_ptr = stack; - /* The i486 uses a push-down stack: the stack grows toward loweraddresses in - * memory. The stack pointer register, points to the lowest, valid work + /* 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. */ @@ -124,8 +131,14 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint32_t*)top_of_stack; + tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c index 10e2b08f47d..4d23d8fc995 100644 --- a/arch/x86_64/src/intel64/up_createstack.c +++ b/arch/x86_64/src/intel64/up_createstack.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -89,6 +90,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -107,8 +126,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -123,6 +162,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -173,6 +213,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (uint64_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c index 30e022c5c5f..dd5720f096a 100644 --- a/arch/x86_64/src/intel64/up_usestack.c +++ b/arch/x86_64/src/intel64/up_usestack.c @@ -31,6 +31,7 @@ #include #include +#include #include "up_internal.h" @@ -79,6 +80,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -115,5 +122,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (uint64_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c index b96633dfeca..1166272074a 100644 --- a/arch/xtensa/src/common/xtensa_createstack.c +++ b/arch/xtensa/src/common/xtensa_createstack.c @@ -46,6 +46,7 @@ #include #include +#include #include #include @@ -120,6 +121,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) uintptr_t cpstart; #endif +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -148,8 +167,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -164,6 +203,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -247,6 +287,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c index dfcfeb01fff..71fa7ba3e30 100644 --- a/arch/xtensa/src/common/xtensa_usestack.c +++ b/arch/xtensa/src/common/xtensa_usestack.c @@ -46,6 +46,7 @@ #include #include +#include #include "xtensa.h" @@ -106,6 +107,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -140,5 +147,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c index 6420cb01418..e77edec04c4 100644 --- a/arch/z16/src/common/z16_createstack.c +++ b/arch/z16/src/common/z16_createstack.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -83,6 +84,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -101,9 +120,43 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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. */ - tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); +#ifdef CONFIG_TLS_ALIGNED +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)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); + } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -151,6 +204,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/z16/src/common/z16_usestack.c b/arch/z16/src/common/z16_usestack.c index 3971f6f9459..3ced8aa71fa 100644 --- a/arch/z16/src/common/z16_usestack.c +++ b/arch/z16/src/common/z16_usestack.c @@ -31,6 +31,7 @@ #include #include +#include #include "z16_internal.h" @@ -79,6 +80,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -112,5 +119,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_size = top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; } diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c index ba557e8dc15..59ab44d890b 100644 --- a/arch/z80/src/common/z80_createstack.c +++ b/arch/z80/src/common/z80_createstack.c @@ -31,6 +31,7 @@ #include #include +#include #include #include "z80_arch.h" @@ -87,6 +88,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { +#ifdef CONFIG_TLS + /* Add the size of the TLS information structure */ + + stack_size += sizeof(struct tls_info_s); + +#ifdef CONFIG_TLS_ALIGNED + /* The allocated stack size must not exceed the maximum possible for the + * TLS feature. + */ + + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size >= TLS_MAXSTACK) + { + stack_size = TLS_MAXSTACK; + } +#endif +#endif + /* 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. @@ -105,8 +124,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* 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 +#ifdef CONFIG_MM_KERNEL_HEAP + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = + (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = + (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size); + } + +#else /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_MM_KERNEL_HEAP /* Use the kernel allocator if this is a kernel thread */ @@ -121,6 +160,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } +#endif /* CONFIG_TLS_ALIGNED */ #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ @@ -169,6 +209,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c index 90c53b5bdc1..2e746c0d1e0 100644 --- a/arch/z80/src/common/z80_usestack.c +++ b/arch/z80/src/common/z80_usestack.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "z80_internal.h" @@ -78,6 +79,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) size_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 + /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -111,5 +118,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) tcb->adj_stack_size = top_of_stack; tcb->adj_stack_size = size_of_stack; +#ifdef CONFIG_TLS + /* Initialize the TLS data structure */ + + memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); +#endif + return OK; }