diff --git a/Documentation/reference/os/arch.rst b/Documentation/reference/os/arch.rst index 3b94233272e..eccfbae034d 100644 --- a/Documentation/reference/os/arch.rst +++ b/Documentation/reference/os/arch.rst @@ -57,8 +57,8 @@ APIs Exported by Architecture-Specific Logic to NuttX - ``adj_stack_size``: Stack size after adjustment for hardware, processor, etc. This value is retained only for debug purposes. - ``stack_alloc_ptr``: Pointer to allocated stack - - ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The - initial value of the stack pointer. + - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data + and Arguments has been removed from the stack allocation. :param tcb: The TCB of new task. :param stack_size: The requested stack size. At least this much @@ -93,8 +93,8 @@ APIs Exported by Architecture-Specific Logic to NuttX - ``adj_stack_size``: Stack size after adjustment for hardware, processor, etc. This value is retained only for debug purposes. - ``stack_alloc_ptr``: Pointer to allocated stack - - ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The - initial value of the stack pointer. + - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data + and Arguments has been removed from the stack allocation. :param tcb: The TCB of new task. :param stack_size: The allocated stack size. @@ -120,9 +120,24 @@ APIs Exported by Architecture-Specific Logic to NuttX - ``adj_stack_size``: Stack size after removal of the stack frame from the stack. - - ``adj_stack_ptr``: Adjusted initial stack pointer after the - frame has been removed from the stack. This will still be the - initial value of the stack pointer when the task is started. + - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data + and Arguments has been removed from the stack allocation. + + Here is the diagram after some allocation(tls, arg): + + +-------------+ <-stack_alloc_ptr(lowest) + | TLS Data | + +-------------+ + | Arguments | + stack_base_ptr-> +-------------+\ + | Available | + + | Stack | | + | | | | + | | | +->adj_stack_size + v | | | + | | | + | | + + +-------------+/ :param tcb: The TCB of new task. :param frame_size: The size of the stack frame to allocate. diff --git a/arch/arm/src/arm/arm_assert.c b/arch/arm/src/arm/arm_assert.c index 89880351084..bc1345dc23a 100644 --- a/arch/arm/src/arm/arm_assert.c +++ b/arch/arm/src/arm/arm_assert.c @@ -171,7 +171,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -240,14 +240,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #ifdef CONFIG_ARCH_USBDUMP diff --git a/arch/arm/src/arm/arm_initialstate.c b/arch/arm/src/arm/arm_initialstate.c index d247838c20f..d15d0b68c21 100644 --- a/arch/arm/src/arm/arm_initialstate.c +++ b/arch/arm/src/arm/arm_initialstate.c @@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/arm/src/arm/vfork.S b/arch/arm/src/arm/vfork.S index 6de4f5f6a6b..4abdf511bf0 100644 --- a/arch/arm/src/arm/vfork.S +++ b/arch/arm/src/arm/vfork.S @@ -57,16 +57,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv6-m/arm_assert.c b/arch/arm/src/armv6-m/arm_assert.c index 8c617a8b169..8db89a6df34 100644 --- a/arch/arm/src/armv6-m/arm_assert.c +++ b/arch/arm/src/armv6-m/arm_assert.c @@ -209,7 +209,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -266,14 +266,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { up_stackdump(sp, ustackbase); } else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else @@ -288,14 +288,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c index c38a4fbe545..5df0fa071e4 100644 --- a/arch/arm/src/armv6-m/arm_initialstate.c +++ b/arch/arm/src/armv6-m/arm_initialstate.c @@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -74,7 +74,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point (stripping off the thumb bit) */ diff --git a/arch/arm/src/armv6-m/vfork.S b/arch/arm/src/armv6-m/vfork.S index 90e2b1f8a96..624134d893a 100644 --- a/arch/arm/src/armv6-m/vfork.S +++ b/arch/arm/src/armv6-m/vfork.S @@ -57,16 +57,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c index b74c2243242..273e6919a0d 100644 --- a/arch/arm/src/armv7-a/arm_assert.c +++ b/arch/arm/src/armv7-a/arm_assert.c @@ -212,7 +212,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; _alert("Current sp: %08x\n", sp); @@ -291,10 +291,10 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase - ustacksize && sp < ustackbase) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { _alert("User Stack\n", sp); - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } #ifdef CONFIG_ARCH_KERNEL_STACK @@ -312,7 +312,7 @@ static void up_dumpstate(void) else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); #ifdef CONFIG_ARCH_KERNEL_STACK up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); #endif diff --git a/arch/arm/src/armv7-a/arm_cpuidlestack.c b/arch/arm/src/armv7-a/arm_cpuidlestack.c index 0dd2885aae3..2e9a1181b98 100644 --- a/arch/arm/src/armv7-a/arm_cpuidlestack.c +++ b/arch/arm/src/armv7-a/arm_cpuidlestack.c @@ -94,8 +94,8 @@ static FAR const uint32_t *g_cpu_stackalloc[CONFIG_SMP_NCPUS] = * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is @@ -111,7 +111,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) { #if CONFIG_SMP_NCPUS > 1 uintptr_t stack_alloc; - uintptr_t top_of_stack; DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL && stack_size <= SMP_STACK_SIZE); @@ -120,11 +119,10 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) stack_alloc = (uintptr_t)g_cpu_stackalloc[cpu]; DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc)); - top_of_stack = stack_alloc + SMP_STACK_SIZE; tcb->adj_stack_size = SMP_STACK_SIZE; - tcb->stack_alloc_ptr = (FAR uint32_t *)stack_alloc; - tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; + tcb->stack_alloc_ptr = (FAR void *)stack_alloc; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #endif return OK; diff --git a/arch/arm/src/armv7-a/arm_initialstate.c b/arch/arm/src/armv7-a/arm_initialstate.c index 5ce1d283a43..521649b0480 100644 --- a/arch/arm/src/armv7-a/arm_initialstate.c +++ b/arch/arm/src/armv7-a/arm_initialstate.c @@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/arm/src/armv7-a/vfork.S b/arch/arm/src/armv7-a/vfork.S index 1fed24d68d3..9524c07b252 100644 --- a/arch/arm/src/armv7-a/vfork.S +++ b/arch/arm/src/armv7-a/vfork.S @@ -57,16 +57,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv7-m/arm_assert.c b/arch/arm/src/armv7-m/arm_assert.c index 01cfe7a6711..f2b76593284 100644 --- a/arch/arm/src/armv7-m/arm_assert.c +++ b/arch/arm/src/armv7-m/arm_assert.c @@ -217,7 +217,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 7 @@ -278,14 +278,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else @@ -303,14 +303,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within the allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c index 6420de8f801..90872ad1439 100644 --- a/arch/arm/src/armv7-m/arm_initialstate.c +++ b/arch/arm/src/armv7-m/arm_initialstate.c @@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; #ifdef CONFIG_ARMV7M_STACKCHECK /* Set the stack limit value */ diff --git a/arch/arm/src/armv7-m/gnu/vfork.S b/arch/arm/src/armv7-m/gnu/vfork.S index b6b618819ef..b5b6dd21421 100644 --- a/arch/arm/src/armv7-m/gnu/vfork.S +++ b/arch/arm/src/armv7-m/gnu/vfork.S @@ -59,16 +59,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv7-m/iar/vfork.S b/arch/arm/src/armv7-m/iar/vfork.S index 91810cbbbc3..305e74728fb 100644 --- a/arch/arm/src/armv7-m/iar/vfork.S +++ b/arch/arm/src/armv7-m/iar/vfork.S @@ -60,16 +60,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c index 70cb80f69e2..17ed679c55a 100644 --- a/arch/arm/src/armv7-r/arm_assert.c +++ b/arch/arm/src/armv7-r/arm_assert.c @@ -209,7 +209,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; _alert("Current sp: %08x\n", sp); @@ -284,10 +284,10 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase - ustacksize && sp < ustackbase) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { _alert("User Stack\n", sp); - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } #ifdef CONFIG_ARCH_KERNEL_STACK @@ -305,7 +305,7 @@ static void up_dumpstate(void) else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); #ifdef CONFIG_ARCH_KERNEL_STACK up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); #endif diff --git a/arch/arm/src/armv7-r/arm_initialstate.c b/arch/arm/src/armv7-r/arm_initialstate.c index 79be1242557..3656bb67649 100644 --- a/arch/arm/src/armv7-r/arm_initialstate.c +++ b/arch/arm/src/armv7-r/arm_initialstate.c @@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/arm/src/armv7-r/vfork.S b/arch/arm/src/armv7-r/vfork.S index 3d6d56cf151..670fdb30ded 100644 --- a/arch/arm/src/armv7-r/vfork.S +++ b/arch/arm/src/armv7-r/vfork.S @@ -57,16 +57,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/armv8-m/arm_assert.c b/arch/arm/src/armv8-m/arm_assert.c index 71b78f8b668..ebdf5214ba0 100644 --- a/arch/arm/src/armv8-m/arm_assert.c +++ b/arch/arm/src/armv8-m/arm_assert.c @@ -217,7 +217,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 7 @@ -278,14 +278,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else @@ -303,14 +303,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within the allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c index a34c853c4de..b2bbf88596a 100644 --- a/arch/arm/src/armv8-m/arm_initialstate.c +++ b/arch/arm/src/armv8-m/arm_initialstate.c @@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; #ifdef CONFIG_ARMV8M_STACKCHECK /* Set the stack limit value */ diff --git a/arch/arm/src/armv8-m/vfork.S b/arch/arm/src/armv8-m/vfork.S index 9d04830fde3..7f68b3b777c 100644 --- a/arch/arm/src/armv8-m/vfork.S +++ b/arch/arm/src/armv8-m/vfork.S @@ -59,16 +59,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c index 7d8524d2ada..5f9f41439f1 100644 --- a/arch/arm/src/common/arm_checkstack.c +++ b/arch/arm/src/common/arm_checkstack.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "sched/sched.h" @@ -207,13 +206,12 @@ void arm_stack_color(FAR void *stackbase, size_t nbytes) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((FAR void *)((uintptr_t)tcb->adj_stack_ptr - - tcb->adj_stack_size), tcb->adj_stack_size); + return do_stackcheck(tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c index dda4b1ff5e8..b14ba8892fd 100644 --- a/arch/arm/src/common/arm_createstack.c +++ b/arch/arm/src/common/arm_createstack.c @@ -58,12 +58,6 @@ #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) #define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) -/* 32bit alignment macros */ - -#define INT32_ALIGN_MASK (3) -#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK) -#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK) - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,8 +74,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -108,28 +102,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - size_t alloc_size; - size_t tls_size; - - /* Add the size of the TLS information structure and align. */ - - tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s)); - alloc_size = STACK_ALIGN_UP(stack_size + tls_size); + 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. */ - DEBUGASSERT(alloc_size <= TLS_MAXSTACK); - if (alloc_size > TLS_MAXSTACK) + DEBUGASSERT(stack_size <= TLS_MAXSTACK); + if (stack_size > TLS_MAXSTACK) { - alloc_size = TLS_MAXSTACK; + stack_size = TLS_MAXSTACK; } #endif - stack_size = alloc_size - tls_size; - /* Is there already a stack allocated of a different size? */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) @@ -154,16 +140,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_memalign(TLS_STACK_ALIGN, alloc_size); + tcb->stack_alloc_ptr = 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, alloc_size); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -173,7 +157,7 @@ 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_memalign(CONFIG_STACK_ALIGNMENT, alloc_size); + kmm_memalign(CONFIG_STACK_ALIGNMENT, stack_size); } else #endif @@ -181,7 +165,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) /* Use the user-space allocator if this is a task or pthread */ tcb->stack_alloc_ptr = - (uint32_t *)kumm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size); + kumm_memalign(CONFIG_STACK_ALIGNMENT, stack_size); } #endif /* CONFIG_TLS_ALIGNED */ @@ -206,19 +190,14 @@ 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 alloc_size are in + /* Since both stack_alloc_ptr and stack_size are in * CONFIG_STACK_ALIGNMENT, and the stack ptr is decremented before * the first write, we can directly save our variables to struct * tcb_s. */ tcb->adj_stack_size = stack_size; - tcb->adj_stack_ptr = (FAR void *)((uintptr_t)tcb->stack_alloc_ptr + - alloc_size); - - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, tls_size); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a @@ -226,8 +205,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * water marks. */ - arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr - - tcb->adj_stack_size), tcb->adj_stack_size); + arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif /* CONFIG_STACK_COLORATION */ board_autoled_on(LED_STACKCREATED); diff --git a/arch/arm/src/common/arm_stackframe.c b/arch/arm/src/common/arm_stackframe.c index 5fa6c36e5a0..bf9bb9235f3 100644 --- a/arch/arm/src/common/arm_stackframe.c +++ b/arch/arm/src/common/arm_stackframe.c @@ -79,9 +79,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -96,6 +95,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c index e8f5269ffa7..dcef7341c08 100644 --- a/arch/arm/src/common/arm_usestack.c +++ b/arch/arm/src/common/arm_usestack.c @@ -53,12 +53,6 @@ #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) #define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) -/* 32bit alignment macros */ - -#define INT32_ALIGN_MASK (3) -#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK) -#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK) - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -77,8 +71,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -93,16 +87,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t tls_size; - #ifdef CONFIG_TLS_ALIGNED /* Make certain that the user provided stack is properly aligned */ DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); #endif - tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s)); - /* Is there already a stack allocated? */ if (tcb->stack_alloc_ptr) @@ -127,28 +117,9 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) /* Save the new stack allocation */ tcb->stack_alloc_ptr = stack; - - /* Align stack top */ - - tcb->adj_stack_ptr = - (FAR void *)STACK_ALIGN_DOWN((uintptr_t)stack + stack_size); - - /* Offset by tls_size */ - - stack = (FAR void *)((uintptr_t)stack + tls_size); - - /* Is there enough room for at least TLS ? */ - - if ((uintptr_t)stack > (uintptr_t)tcb->adj_stack_ptr) - { - return -ENOMEM; - } - - tcb->adj_stack_size = (uintptr_t)tcb->adj_stack_ptr - (uintptr_t)stack; - - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, tls_size); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; + tcb->adj_stack_size = + STACK_ALIGN_DOWN((uintptr_t)stack + stack_size) - (uintptr_t)stack; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a @@ -156,8 +127,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * water marks. */ - arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr - - tcb->adj_stack_size), tcb->adj_stack_size); + arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif /* CONFIG_STACK_COLORATION */ return OK; diff --git a/arch/arm/src/common/arm_vfork.c b/arch/arm/src/common/arm_vfork.c index 35bd20ac980..feb430293ea 100644 --- a/arch/arm/src/common/arm_vfork.c +++ b/arch/arm/src/common/arm_vfork.c @@ -67,16 +67,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() @@ -100,13 +100,11 @@ pid_t up_vfork(const struct vfork_s *context) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; - size_t stacksize; uint32_t newsp; uint32_t newfp; + uint32_t newtop; + uint32_t stacktop; uint32_t stackutil; - size_t argsize; - void *argv; - int ret; sinfo("vfork context [%p]:\n", context); sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32 @@ -119,7 +117,7 @@ pid_t up_vfork(const struct vfork_s *context) /* Allocate and initialize a TCB for the child task. */ - child = nxtask_setup_vfork((start_t)(context->lr & ~1), &argsize); + child = nxtask_setup_vfork((start_t)(context->lr & ~1)); if (!child) { serr("ERROR: nxtask_setup_vfork failed\n"); @@ -128,37 +126,18 @@ pid_t up_vfork(const struct vfork_s *context) sinfo("TCBs: Parent=%p Child=%p\n", parent, child); - /* Get the size of the parent task's stack. */ - - stacksize = parent->adj_stack_size; - - /* Allocate the stack for the TCB */ - - ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize, - parent->flags & TCB_FLAG_TTYPE_MASK); - if (ret != OK) - { - serr("ERROR: up_create_stack failed: %d\n", ret); - nxtask_abort_vfork(child, -ret); - return (pid_t)ERROR; - } - - /* Allocate the memory and copy argument from parent task */ - - argv = up_stack_frame((FAR struct tcb_s *)child, argsize); - memcpy(argv, parent->adj_stack_ptr, argsize); - /* How much of the parent's stack was utilized? The ARM uses * a push-down stack so that the current stack pointer should * be lower than the initial, adjusted stack pointer. The * stack usage should be the difference between those two. */ - DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); - stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; + stacktop = (uint32_t)parent->stack_base_ptr + + parent->adj_stack_size; + DEBUGASSERT(stacktop > context->sp); + stackutil = stacktop - context->sp; - sinfo("Parent: stacksize:%zu stackutil:%" PRId32 "\n", - stacksize, stackutil); + sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil); /* Make some feeble effort to preserve the stack contents. This is * feeble because the stack surely contains invalid pointers and other @@ -167,26 +146,27 @@ pid_t up_vfork(const struct vfork_s *context) * effort is overkill. */ - newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; + newtop = (uint32_t)child->cmn.stack_base_ptr + + child->cmn.adj_stack_size; + newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); /* Was there a frame pointer in place before? */ - if (context->fp <= (uint32_t)parent->adj_stack_ptr && - context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) + if (context->fp >= context->sp && context->fp < stacktop) { - uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; - newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; + uint32_t frameutil = stacktop - context->fp; + newfp = newtop - frameutil; } else { newfp = context->fp; } - sinfo("Parent: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", - parent->adj_stack_ptr, context->sp, context->fp); - sinfo("Child: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", - child->cmn.adj_stack_ptr, newsp, newfp); + sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n", + stacktop, context->sp, context->fp); + sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n", + newtop, newsp, newfp); /* Update the stack pointer, frame pointer, and volatile registers. When * the child TCB was initialized, all of the values were set to zero. diff --git a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c index 4f3f49f5c64..0bf1f6ab011 100644 --- a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c +++ b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c @@ -67,8 +67,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/arch/arm/src/cxd56xx/cxd56_cpustart.c b/arch/arm/src/cxd56xx/cxd56_cpustart.c index a948d9ac9fa..266a7ede8dd 100644 --- a/arch/arm/src/cxd56xx/cxd56_cpustart.c +++ b/arch/arm/src/cxd56xx/cxd56_cpustart.c @@ -179,7 +179,8 @@ int up_cpu_start(int cpu) /* Copy initial stack and reset vector for APP_DSP */ - putreg32((uint32_t)tcb->adj_stack_ptr, VECTOR_ISTACK); + putreg32((uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size, VECTOR_ISTACK); putreg32((uint32_t)appdsp_boot, VECTOR_RESETV); spin_lock(&g_appdsp_boot); diff --git a/arch/arm/src/lc823450/lc823450_cpuidlestack.c b/arch/arm/src/lc823450/lc823450_cpuidlestack.c index bcf48309bca..a163c9d1f9f 100644 --- a/arch/arm/src/lc823450/lc823450_cpuidlestack.c +++ b/arch/arm/src/lc823450/lc823450_cpuidlestack.c @@ -63,8 +63,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/arch/arm/src/lc823450/lc823450_cpustart.c b/arch/arm/src/lc823450/lc823450_cpustart.c index 16fcd2b2f06..043ceaeb9db 100644 --- a/arch/arm/src/lc823450/lc823450_cpustart.c +++ b/arch/arm/src/lc823450/lc823450_cpustart.c @@ -167,7 +167,8 @@ int up_cpu_start(int cpu) putreg32(0x1, REMAP); /* remap enable */ backup[0] = getreg32(CPU1_VECTOR_ISTACK); backup[1] = getreg32(CPU1_VECTOR_RESETV); - putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK); + putreg32((uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size, CPU1_VECTOR_ISTACK); putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV); spin_lock(&g_cpu_wait[0]); diff --git a/arch/arm/src/rp2040/rp2040_cpuidlestack.c b/arch/arm/src/rp2040/rp2040_cpuidlestack.c index e675a2fed1d..eacab6ab765 100644 --- a/arch/arm/src/rp2040/rp2040_cpuidlestack.c +++ b/arch/arm/src/rp2040/rp2040_cpuidlestack.c @@ -67,8 +67,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/arch/arm/src/rp2040/rp2040_cpustart.c b/arch/arm/src/rp2040/rp2040_cpustart.c index 05e1fddf2ec..08c16c2d726 100644 --- a/arch/arm/src/rp2040/rp2040_cpustart.c +++ b/arch/arm/src/rp2040/rp2040_cpustart.c @@ -222,7 +222,8 @@ int up_cpu_start(int cpu) core1_boot_msg[0] = 0; core1_boot_msg[1] = 1; core1_boot_msg[2] = getreg32(ARMV6M_SYSCON_VECTAB); - core1_boot_msg[3] = (uint32_t)tcb->adj_stack_ptr; + core1_boot_msg[3] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; core1_boot_msg[4] = (uint32_t)core1_boot; do diff --git a/arch/arm/src/sam34/sam4cm_cpuidlestack.c b/arch/arm/src/sam34/sam4cm_cpuidlestack.c index 815dd404044..98a1b4a365c 100644 --- a/arch/arm/src/sam34/sam4cm_cpuidlestack.c +++ b/arch/arm/src/sam34/sam4cm_cpuidlestack.c @@ -97,8 +97,8 @@ void up_idle(void) * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/arch/arm/src/sam34/sam4cm_cpustart.c b/arch/arm/src/sam34/sam4cm_cpustart.c index 5df68022344..a653dfc13c9 100644 --- a/arch/arm/src/sam34/sam4cm_cpustart.c +++ b/arch/arm/src/sam34/sam4cm_cpustart.c @@ -204,7 +204,8 @@ int up_cpu_start(int cpu) /* Copy initial vectors for CPU1 */ - putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK); + putreg32((uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size, CPU1_VECTOR_ISTACK); putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV); spin_lock(&g_cpu1_boot); diff --git a/arch/avr/src/avr/up_checkstack.c b/arch/avr/src/avr/up_checkstack.c index 517578288bc..5003c8a4d52 100644 --- a/arch/avr/src/avr/up_checkstack.c +++ b/arch/avr/src/avr/up_checkstack.c @@ -146,12 +146,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size); + return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c index a6c606c382b..8ac95e7b557 100644 --- a/arch/avr/src/avr/up_createstack.c +++ b/arch/avr/src/avr/up_createstack.c @@ -64,8 +64,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -86,10 +86,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -129,16 +125,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -147,14 +141,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -172,8 +166,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; - /* Yes.. If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. @@ -183,23 +175,11 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size); #endif - /* The AVR 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 = (size_t)tcb->stack_alloc_ptr + stack_size; - /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = stack_size; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - #if defined(ARCH_HAVE_LEDS) board_autoled_on(LED_STACKCREATED); #endif diff --git a/arch/avr/src/avr/up_dumpstate.c b/arch/avr/src/avr/up_dumpstate.c index b84a95ff8e4..dcf0030cda1 100644 --- a/arch/avr/src/avr/up_dumpstate.c +++ b/arch/avr/src/avr/up_dumpstate.c @@ -139,7 +139,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustackbase = (uint16_t)rtcb->stack_base_ptr; ustacksize = (uint16_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -196,14 +196,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else _alert("sp: %04x\n", sp); @@ -217,14 +217,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif } diff --git a/arch/avr/src/avr/up_initialstate.c b/arch/avr/src/avr/up_initialstate.c index fb8a2a82f97..5135dc718ed 100644 --- a/arch/avr/src/avr/up_initialstate.c +++ b/arch/avr/src/avr/up_initialstate.c @@ -55,6 +55,7 @@ void up_initial_state(struct tcb_s *tcb) { struct xcptcontext *xcp = &tcb->xcp; + uintptr_t sp; /* Initialize the idle thread stack */ @@ -62,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -72,10 +73,12 @@ void up_initial_state(struct tcb_s *tcb) memset(xcp, 0, sizeof(struct xcptcontext)); - /* Set the initial stack pointer to the "base" of the allocated stack */ + /* Set the initial stack pointer to the top of the allocated stack */ - xcp->regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8); - xcp->regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff); + sp = (uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size; + xcp->regs[REG_SPH] = (uint8_t)(sp >> 8); + xcp->regs[REG_SPL] = (uint8_t)(sp & 0xff); /* Save the task entry point */ diff --git a/arch/avr/src/avr/up_stackframe.c b/arch/avr/src/avr/up_stackframe.c index 860350eaadd..687f105a87a 100644 --- a/arch/avr/src/avr/up_stackframe.c +++ b/arch/avr/src/avr/up_stackframe.c @@ -77,9 +77,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -94,6 +93,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -105,17 +106,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Set the initial stack pointer to the "base" of the allocated stack */ - - tcb->xcp.regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8); - tcb->xcp.regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff); + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c index bdde37c2396..8e796e97105 100644 --- a/arch/avr/src/avr/up_usestack.c +++ b/arch/avr/src/avr/up_usestack.c @@ -54,8 +54,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -70,8 +70,6 @@ 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 */ @@ -105,16 +103,10 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * positive word offsets from sp. */ - top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; - /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (FAR void *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = stack_size; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c index 6ef611e05af..daa48d6cc8e 100644 --- a/arch/avr/src/avr32/up_createstack.c +++ b/arch/avr/src/avr32/up_createstack.c @@ -64,8 +64,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -91,10 +91,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -134,16 +130,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -152,14 +146,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -177,7 +171,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -195,24 +189,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The AVR32 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; - size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR void *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/avr/src/avr32/up_dumpstate.c b/arch/avr/src/avr32/up_dumpstate.c index 98f29603842..04b800a13a2 100644 --- a/arch/avr/src/avr32/up_dumpstate.c +++ b/arch/avr/src/avr32/up_dumpstate.c @@ -109,7 +109,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -166,14 +166,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else _alert("sp: %08x\n", sp); @@ -187,14 +187,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif } diff --git a/arch/avr/src/avr32/up_initialstate.c b/arch/avr/src/avr32/up_initialstate.c index ee33df69fa0..eea5c8cca7f 100644 --- a/arch/avr/src/avr32/up_initialstate.c +++ b/arch/avr/src/avr32/up_initialstate.c @@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -85,7 +85,8 @@ void up_initial_state(struct tcb_s *tcb) /* Set the initial stack pointer to the top of the allocated stack */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/avr/src/avr32/up_stackframe.c b/arch/avr/src/avr32/up_stackframe.c index 67ea2cd118b..b01ea527362 100644 --- a/arch/avr/src/avr32/up_stackframe.c +++ b/arch/avr/src/avr32/up_stackframe.c @@ -79,9 +79,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -96,6 +95,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c index ef3b1d422ae..c2532262a2a 100644 --- a/arch/avr/src/avr32/up_usestack.c +++ b/arch/avr/src/avr32/up_usestack.c @@ -53,8 +53,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -69,7 +69,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -106,7 +106,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * referenced as positive word offsets from sp. */ - top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The AVR32 stack must be aligned at word (4 byte) * boundaries. If necessary top_of_stack must be rounded @@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR void *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c index d0f89b9b4b6..3fe163fe287 100644 --- a/arch/hc/src/common/up_createstack.c +++ b/arch/hc/src/common/up_createstack.c @@ -61,8 +61,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,10 +88,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -131,16 +127,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -149,14 +143,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * stack address. */ - top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The CPU12 stack should be aligned at half-word (2 byte) * boundaries. If necessary top_of_stack must be rounded @@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) */ top_of_stack &= ~1; - size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->alloc_stack_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/hc/src/common/up_stackframe.c b/arch/hc/src/common/up_stackframe.c index d8fd239b056..b57de5c3078 100644 --- a/arch/hc/src/common/up_stackframe.c +++ b/arch/hc/src/common/up_stackframe.c @@ -79,9 +79,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -96,6 +95,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -107,17 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8; - tcb->xcp.regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c index 87523e9fb4a..d7173b8ffda 100644 --- a/arch/hc/src/common/up_usestack.c +++ b/arch/hc/src/common/up_usestack.c @@ -52,8 +52,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -66,9 +66,9 @@ * ****************************************************************************/ -int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * stack address. */ - top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The CPU12 stack should be aligned at half-word (2 byte) * boundaries. If necessary top_of_stack must be rounded @@ -113,16 +113,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ top_of_stack &= ~1; - size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c index 8e778f68e8b..c14faa8a2e9 100644 --- a/arch/hc/src/m9s12/m9s12_assert.c +++ b/arch/hc/src/m9s12/m9s12_assert.c @@ -184,7 +184,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustackbase = (uint16_t)rtcb->stack_base_ptr; ustacksize = (uint16_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -238,14 +238,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #ifdef CONFIG_ARCH_USBDUMP diff --git a/arch/hc/src/m9s12/m9s12_initialstate.c b/arch/hc/src/m9s12/m9s12_initialstate.c index 25f831393ab..7cb6d69c457 100644 --- a/arch/hc/src/m9s12/m9s12_initialstate.c +++ b/arch/hc/src/m9s12/m9s12_initialstate.c @@ -52,6 +52,7 @@ void up_initial_state(struct tcb_s *tcb) { struct xcptcontext *xcp = &tcb->xcp; + uintptr_t sp; /* Initialize the idle thread stack */ @@ -59,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -69,8 +70,10 @@ void up_initial_state(struct tcb_s *tcb) /* Save the initial stack pointer */ - xcp->regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8; - xcp->regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff; + sp = (uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size; + xcp->regs[REG_SPH] = sp >> 8; + xcp->regs[REG_SPL] = sp & 0xff; /* Save the task entry point */ diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c index f3c9ea5fc20..b906a0dfeaf 100644 --- a/arch/mips/src/common/mips_createstack.c +++ b/arch/mips/src/common/mips_createstack.c @@ -82,8 +82,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -109,10 +109,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -151,16 +147,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -169,14 +163,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -212,7 +206,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The MIPS stack must be aligned at word (4 byte) boundaries; for * floating point use, the stack must be aligned to 8-byte addresses. @@ -228,17 +222,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * The size need not be aligned. */ - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/mips/src/common/mips_stackframe.c b/arch/mips/src/common/mips_stackframe.c index df6287a2085..3fdfcc4128f 100644 --- a/arch/mips/src/common/mips_stackframe.c +++ b/arch/mips/src/common/mips_stackframe.c @@ -82,9 +82,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -99,6 +98,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -110,16 +111,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c index 531e7c50a45..e6e4e60899f 100644 --- a/arch/mips/src/common/mips_usestack.c +++ b/arch/mips/src/common/mips_usestack.c @@ -73,8 +73,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -89,7 +89,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -125,7 +125,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The MIPS stack must be aligned at word (4 byte) or double word (8 byte) * boundaries. If necessary top_of_stack must be rounded down to the @@ -140,16 +140,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * The size need not be aligned. */ - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/mips/src/mips32/mips_dumpstate.c b/arch/mips/src/mips32/mips_dumpstate.c index 02686986ebe..b850e859cec 100644 --- a/arch/mips/src/mips32/mips_dumpstate.c +++ b/arch/mips/src/mips32/mips_dumpstate.c @@ -139,7 +139,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -193,14 +193,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/mips/src/mips32/mips_initialstate.c b/arch/mips/src/mips32/mips_initialstate.c index 65fc6c20929..0a3d0c2cce8 100644 --- a/arch/mips/src/mips32/mips_initialstate.c +++ b/arch/mips/src/mips32/mips_initialstate.c @@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -78,7 +78,8 @@ void up_initial_state(struct tcb_s *tcb) * only the start function would do that and we have control over that one. */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/mips/src/mips32/mips_vfork.c b/arch/mips/src/mips32/mips_vfork.c index 536b78df484..65aa6934ea4 100644 --- a/arch/mips/src/mips32/mips_vfork.c +++ b/arch/mips/src/mips32/mips_vfork.c @@ -69,16 +69,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * this consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() @@ -102,15 +102,13 @@ pid_t up_vfork(const struct vfork_s *context) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; - size_t stacksize; uint32_t newsp; #ifdef CONFIG_MIPS32_FRAMEPOINTER uint32_t newfp; #endif + uint32_t newtop; + uint32_t stacktop; uint32_t stackutil; - size_t argsize; - void *argv; - int ret; sinfo("s0:%08" PRIx32 " s1:%08" PRIx32 " s2:%08" PRIx32 " s3:%08" PRIx32 " s4:%08" PRIx32 "\n", @@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context) /* Allocate and initialize a TCB for the child task. */ - child = nxtask_setup_vfork((start_t)context->ra, &argsize); + child = nxtask_setup_vfork((start_t)context->ra); if (!child) { sinfo("nxtask_setup_vfork failed\n"); @@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context) sinfo("Parent=%p Child=%p\n", parent, child); - /* Get the size of the parent task's stack. Due to alignment operations, - * the adjusted stack size may be smaller than the stack size originally - * requested. - */ - - stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1; - - /* Allocate the stack for the TCB */ - - ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize, - parent->flags & TCB_FLAG_TTYPE_MASK); - if (ret != OK) - { - serr("ERROR: up_create_stack failed: %d\n", ret); - nxtask_abort_vfork(child, -ret); - return (pid_t)ERROR; - } - - /* Allocate the memory and copy argument from parent task */ - - argv = up_stack_frame((FAR struct tcb_s *)child, argsize); - memcpy(argv, parent->adj_stack_ptr, argsize); - /* How much of the parent's stack was utilized? The MIPS uses * a push-down stack so that the current stack pointer should * be lower than the initial, adjusted stack pointer. The * stack usage should be the difference between those two. */ - DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); - stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; + stacktop = (uint32_t)parent->stack_base_ptr + + parent->adj_stack_size; + DEBUGASSERT(stacktop > context->sp); + stackutil = stacktop - context->sp; - sinfo("stacksize:%zd stackutil:%" PRId32 "\n", stacksize, stackutil); + sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil); /* Make some feeble effort to perserve the stack contents. This is * feeble because the stack surely contains invalid pointers and other @@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context) * effort is overkill. */ - newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; + newtop = (uintptr_t)child->cmn.stack_base_ptr + + child->cmn.adj_stack_size; + newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); /* Was there a frame pointer in place before? */ #ifdef CONFIG_MIPS32_FRAMEPOINTER - if (context->fp <= (uint32_t)parent->adj_stack_ptr && - context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) + if (context->fp >= context->sp && context->fp < stacktop) { - uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; - newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; + uint32_t frameutil = stacktop - context->fp; + newfp = newtop - frameutil; } else { newfp = context->fp; } - sinfo("Old stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", - parent->adj_stack_ptr, context->sp, context->fp); - sinfo("New stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", - child->cmn.adj_stack_ptr, newsp, newfp); + sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n", + stacktop, context->sp, context->fp); + sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n", + newtop, newsp, newfp); #else - sinfo("Old stack base:%p SP:%08" PRIx32 "\n", - parent->adj_stack_ptr, context->sp); - sinfo("New stack base:%p SP:%08" PRIx32 "\n", - child->cmn.adj_stack_ptr, newsp); + sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 "\n", + stacktop, context->sp); + sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 "\n", + newtop, newsp); #endif /* Update the stack pointer, frame pointer, global pointer and saved diff --git a/arch/mips/src/mips32/vfork.S b/arch/mips/src/mips32/vfork.S index aa7f96c1b0f..4dfa94a606b 100644 --- a/arch/mips/src/mips32/vfork.S +++ b/arch/mips/src/mips32/vfork.S @@ -56,16 +56,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c index 8e354ab670d..e00f5ab9a0f 100644 --- a/arch/misoc/src/lm32/lm32_createstack.c +++ b/arch/misoc/src/lm32/lm32_createstack.c @@ -97,8 +97,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -124,10 +124,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -166,16 +162,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -184,14 +178,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -209,7 +203,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -227,7 +221,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The LM32 stack must be aligned at word (4 byte) boundaries; for * floating point use, the stack must be aligned to 8-byte addresses. @@ -236,17 +230,13 @@ 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); - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c index fa4440305d0..6dded3d74b5 100644 --- a/arch/misoc/src/lm32/lm32_dumpstate.c +++ b/arch/misoc/src/lm32/lm32_dumpstate.c @@ -141,7 +141,7 @@ void lm32_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -195,14 +195,14 @@ void lm32_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c index 45024e6b2c3..525cd7a698b 100644 --- a/arch/misoc/src/lm32/lm32_initialstate.c +++ b/arch/misoc/src/lm32/lm32_initialstate.c @@ -77,7 +77,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -91,7 +91,8 @@ void up_initial_state(struct tcb_s *tcb) * only the start function would do that and we have control over that one */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/misoc/src/lm32/lm32_stackframe.c b/arch/misoc/src/lm32/lm32_stackframe.c index c436f5aa426..624c6fed072 100644 --- a/arch/misoc/src/lm32/lm32_stackframe.c +++ b/arch/misoc/src/lm32/lm32_stackframe.c @@ -90,9 +90,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -107,6 +106,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/misoc/src/lm32/lm32_usestack.c b/arch/misoc/src/lm32/lm32_usestack.c index 13aa6af5d99..c55a100cf59 100644 --- a/arch/misoc/src/lm32/lm32_usestack.c +++ b/arch/misoc/src/lm32/lm32_usestack.c @@ -51,8 +51,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -67,7 +67,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c index a46539a49ce..186e564120c 100644 --- a/arch/misoc/src/minerva/minerva_createstack.c +++ b/arch/misoc/src/minerva/minerva_createstack.c @@ -89,8 +89,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -116,10 +116,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -159,16 +155,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -177,14 +171,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -202,7 +196,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -220,7 +214,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The MINERVA stack must be aligned at word (4 byte) boundaries; for * floating point use, the stack must be aligned to 8-byte addresses. @@ -229,17 +223,13 @@ 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); - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR uint32_t *) top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/misoc/src/minerva/minerva_dumpstate.c b/arch/misoc/src/minerva/minerva_dumpstate.c index c3de5f9440f..4e5331c993f 100644 --- a/arch/misoc/src/minerva/minerva_dumpstate.c +++ b/arch/misoc/src/minerva/minerva_dumpstate.c @@ -148,7 +148,7 @@ void minerva_dumpstate(void) * == NULL) */ - ustackbase = (uint32_t) rtcb->adj_stack_ptr; + ustackbase = (uint32_t) rtcb->stack_base_ptr; ustacksize = (uint32_t) rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -200,14 +200,14 @@ void minerva_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/misoc/src/minerva/minerva_initialstate.c b/arch/misoc/src/minerva/minerva_initialstate.c index 7bcd29b53d8..21953eb0391 100644 --- a/arch/misoc/src/minerva/minerva_initialstate.c +++ b/arch/misoc/src/minerva/minerva_initialstate.c @@ -81,7 +81,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -95,11 +95,12 @@ void up_initial_state(struct tcb_s *tcb) * only the start function would do that and we have control over that one. */ - xcp->regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ - xcp->regs[REG_CSR_MEPC] = (uint32_t) tcb->start; + xcp->regs[REG_CSR_MEPC] = (uint32_t)tcb->start; xcp->regs[REG_CSR_MSTATUS] = CSR_MSTATUS_MPIE; diff --git a/arch/misoc/src/minerva/minerva_stackframe.c b/arch/misoc/src/minerva/minerva_stackframe.c index ba8b5cbda4b..3dc536ee4b1 100644 --- a/arch/misoc/src/minerva/minerva_stackframe.c +++ b/arch/misoc/src/minerva/minerva_stackframe.c @@ -90,9 +90,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -107,6 +106,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; tcb->adj_stack_size -= frame_size; - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr; - /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/misoc/src/minerva/minerva_usestack.c b/arch/misoc/src/minerva/minerva_usestack.c index fbb2de14686..3d1c6d76621 100644 --- a/arch/misoc/src/minerva/minerva_usestack.c +++ b/arch/misoc/src/minerva/minerva_usestack.c @@ -51,8 +51,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -67,7 +67,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/or1k/src/common/up_assert.c b/arch/or1k/src/common/up_assert.c index 6df9c2ce550..fe9ff7aa292 100644 --- a/arch/or1k/src/common/up_assert.c +++ b/arch/or1k/src/common/up_assert.c @@ -209,7 +209,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -266,14 +266,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp < ustackbase && sp >= ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } #else @@ -288,14 +288,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #endif diff --git a/arch/or1k/src/common/up_checkstack.c b/arch/or1k/src/common/up_checkstack.c index c9fb7ec07da..2562ae5359a 100644 --- a/arch/or1k/src/common/up_checkstack.c +++ b/arch/or1k/src/common/up_checkstack.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "sched/sched.h" @@ -43,14 +42,12 @@ * Private Function Prototypes ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); +static size_t do_stackcheck(uintptr_t alloc, size_t size); /**************************************************************************** - * Private Functions + * Private Function ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); - /**************************************************************************** * Name: do_stackcheck * @@ -68,7 +65,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); * ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) +static size_t do_stackcheck(uintptr_t alloc, size_t size) { FAR uintptr_t start; FAR uintptr_t end; @@ -82,21 +79,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) /* Get aligned addresses of the top and bottom of the stack */ - if (!int_stack) - { - /* Skip over the TLS data structure at the bottom of the stack */ - -#ifdef CONFIG_TLS_ALIGNED - DEBUGASSERT((alloc & TLS_STACK_MASK) == 0); -#endif - start = alloc + sizeof(struct tls_info_s); - } - else - { - start = alloc & ~3; - } - - end = (alloc + size + 3) & ~3; + start = (alloc + 3) & ~3; + end = (alloc + size) & ~3; /* Get the adjusted size based on the top and bottom of the stack */ @@ -133,13 +117,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size, - false); + return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) @@ -156,8 +139,7 @@ ssize_t up_check_stack_remain(void) size_t up_check_intstack(void) { return do_stackcheck((uintptr_t)&g_intstackalloc, - (CONFIG_ARCH_INTERRUPTSTACK & ~3), - true); + (CONFIG_ARCH_INTERRUPTSTACK & ~3)); } size_t up_check_intstack_remain(void) diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c index 22029475d0e..9a440ce6a42 100644 --- a/arch/or1k/src/common/up_createstack.c +++ b/arch/or1k/src/common/up_createstack.c @@ -74,8 +74,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -102,10 +102,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -145,16 +141,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -163,14 +157,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -188,36 +182,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { -#if defined(CONFIG_STACK_COLORATION) - uintptr_t stack_base; -#endif - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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 - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* 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); - up_stack_color((FAR void *)stack_base, stack_size); + up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/or1k/src/common/up_initialstate.c b/arch/or1k/src/common/up_initialstate.c index a884c78f1ad..28c9827d192 100644 --- a/arch/or1k/src/common/up_initialstate.c +++ b/arch/or1k/src/common/up_initialstate.c @@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -87,7 +87,8 @@ void up_initial_state(struct tcb_s *tcb) memset(xcp, 0, sizeof(struct xcptcontext)); - xcp->regs[REG_R1] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_R1] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[REG_PC] = (uint32_t)tcb->start; mfspr(SPR_SYS_SR, sr); diff --git a/arch/or1k/src/common/up_stackframe.c b/arch/or1k/src/common/up_stackframe.c index 98903ecc8bb..c6e84853a5b 100644 --- a/arch/or1k/src/common/up_stackframe.c +++ b/arch/or1k/src/common/up_stackframe.c @@ -71,9 +71,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,6 +87,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_R1] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/or1k/src/common/up_usestack.c b/arch/or1k/src/common/up_usestack.c index 1ccdaf20899..9866c4c2422 100644 --- a/arch/or1k/src/common/up_usestack.c +++ b/arch/or1k/src/common/up_usestack.c @@ -51,8 +51,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -67,7 +67,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c index dbdfb3dd46c..c5043715cd3 100644 --- a/arch/renesas/src/common/up_createstack.c +++ b/arch/renesas/src/common/up_createstack.c @@ -61,8 +61,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,10 +88,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -131,16 +127,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -149,14 +143,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The SH stack must be aligned at word (4 byte) * boundaries. If necessary top_of_stack must be rounded @@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/renesas/src/common/up_stackframe.c b/arch/renesas/src/common/up_stackframe.c index 7ad96a790a9..ebc7eadce46 100644 --- a/arch/renesas/src/common/up_stackframe.c +++ b/arch/renesas/src/common/up_stackframe.c @@ -78,9 +78,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -95,6 +94,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -106,16 +107,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; tcb->adj_stack_size -= frame_size; - /* Reset the initial state */ - - up_initial_state(tcb); - /* And return a pointer to allocated memory */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c index bd7a120e5e6..b447b3ebedd 100644 --- a/arch/renesas/src/common/up_usestack.c +++ b/arch/renesas/src/common/up_usestack.c @@ -53,8 +53,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -69,7 +69,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The SH 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR void *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c index 52dbcf1a963..a5c8ff52489 100644 --- a/arch/renesas/src/m16c/m16c_dumpstate.c +++ b/arch/renesas/src/m16c/m16c_dumpstate.c @@ -136,7 +136,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint16_t)rtcb->adj_stack_ptr; + ustackbase = (uint16_t)rtcb->stack_base_ptr; ustacksize = (uint16_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory. @@ -197,14 +197,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - m16c_stackdump(ustackbase - ustacksize, ustackbase); + m16c_stackdump(sp, ustackbase + ustacksize); } else { - m16c_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + m16c_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/renesas/src/m16c/m16c_initialstate.c b/arch/renesas/src/m16c/m16c_initialstate.c index 9a5f9e55514..5c88e0f91b5 100644 --- a/arch/renesas/src/m16c/m16c_initialstate.c +++ b/arch/renesas/src/m16c/m16c_initialstate.c @@ -54,6 +54,7 @@ void up_initial_state(FAR struct tcb_s *tcb) { FAR struct xcptcontext *xcp = &tcb->xcp; FAR uint8_t *regs = xcp->regs; + uintptr_t sp; /* Initialize the idle thread stack */ @@ -61,7 +62,7 @@ void up_initial_state(FAR struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -90,7 +91,9 @@ void up_initial_state(FAR struct tcb_s *tcb) /* Offset 18-20: User stack pointer */ + sp = (uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size; regs = &xcp->regs[REG_SP]; - *regs++ = (uint32_t)tcb->adj_stack_ptr >> 8; /* Bits 8-15 of SP */ - *regs = (uint32_t)tcb->adj_stack_ptr; /* Bits 0-7 of SP */ + *regs++ = sp >> 8; /* Bits 8-15 of SP */ + *regs = sp; /* Bits 0-7 of SP */ } diff --git a/arch/renesas/src/rx65n/rx65n_dumpstate.c b/arch/renesas/src/rx65n/rx65n_dumpstate.c index 0fa573b049d..ebf99059c5a 100644 --- a/arch/renesas/src/rx65n/rx65n_dumpstate.c +++ b/arch/renesas/src/rx65n/rx65n_dumpstate.c @@ -143,7 +143,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint16_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 @@ -194,14 +194,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - rx65n_stackdump(ustackbase - ustacksize, ustackbase); + rx65n_stackdump(sp, ustackbase + ustacksize); } else { - rx65n_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + rx65n_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/renesas/src/rx65n/rx65n_initialstate.c b/arch/renesas/src/rx65n/rx65n_initialstate.c index e371367289c..c6808b1fd12 100644 --- a/arch/renesas/src/rx65n/rx65n_initialstate.c +++ b/arch/renesas/src/rx65n/rx65n_initialstate.c @@ -67,7 +67,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb) memset(xcp, 0, sizeof(struct xcptcontext)); - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Enable or disable interrupts, based on user configuration */ diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c index 5988d256ff9..215100f3479 100644 --- a/arch/renesas/src/sh1/sh1_dumpstate.c +++ b/arch/renesas/src/sh1/sh1_dumpstate.c @@ -123,7 +123,7 @@ void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -177,14 +177,14 @@ void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - sh1_stackdump(ustackbase - ustacksize, ustackbase); + sh1_stackdump(sp, ustackbase + ustacksize); } else { - sh1_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + sh1_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/renesas/src/sh1/sh1_initialstate.c b/arch/renesas/src/sh1/sh1_initialstate.c index e097f6d5508..d52e09a71d9 100644 --- a/arch/renesas/src/sh1/sh1_initialstate.c +++ b/arch/renesas/src/sh1/sh1_initialstate.c @@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -89,7 +89,8 @@ void up_initial_state(struct tcb_s *tcb) /* Set the initial stack pointer to the "top" of the allocated stack */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/risc-v/src/common/riscv_checkstack.c b/arch/risc-v/src/common/riscv_checkstack.c index eec04ae94b7..ca35375e3cf 100644 --- a/arch/risc-v/src/common/riscv_checkstack.c +++ b/arch/risc-v/src/common/riscv_checkstack.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "sched/sched.h" @@ -43,7 +42,7 @@ * Private Function Prototypes ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); +static size_t do_stackcheck(uintptr_t alloc, size_t size); /**************************************************************************** * Name: do_stackcheck @@ -62,7 +61,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); * ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) +static size_t do_stackcheck(uintptr_t alloc, size_t size) { FAR uintptr_t start; FAR uintptr_t end; @@ -76,21 +75,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) /* Get aligned addresses of the top and bottom of the stack */ - if (!int_stack) - { - /* Skip over the TLS data structure at the bottom of the stack */ - -#ifdef CONFIG_TLS_ALIGNED - DEBUGASSERT((alloc & TLS_STACK_MASK) == 0); -#endif - start = alloc + sizeof(struct tls_info_s); - } - else - { - start = alloc & ~3; - } - - end = (alloc + size + 3) & ~3; + start = (alloc + 3) & ~3; + end = (alloc + size) & ~3; /* Get the adjusted size based on the top and bottom of the stack */ @@ -172,13 +158,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size, - false); + return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) @@ -195,8 +180,7 @@ ssize_t up_check_stack_remain(void) size_t up_check_intstack(void) { return do_stackcheck((uintptr_t)&g_intstackalloc, - (CONFIG_ARCH_INTERRUPTSTACK & ~3), - true); + (CONFIG_ARCH_INTERRUPTSTACK & ~3)); } size_t up_check_intstack_remain(void) diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c index 4754520b7ce..2086b857cf8 100644 --- a/arch/risc-v/src/common/riscv_createstack.c +++ b/arch/risc-v/src/common/riscv_createstack.c @@ -83,8 +83,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -110,10 +110,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -153,16 +149,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -171,14 +165,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -196,10 +190,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { -#if defined(CONFIG_STACK_COLORATION) - uintptr_t stack_base; -#endif - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* RISCV uses a push-down stack: the stack grows toward lower @@ -221,24 +212,16 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* 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); + riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/risc-v/src/common/riscv_stackframe.c b/arch/risc-v/src/common/riscv_stackframe.c index 193adcbff63..5b4b7f3894d 100644 --- a/arch/risc-v/src/common/riscv_stackframe.c +++ b/arch/risc-v/src/common/riscv_stackframe.c @@ -83,9 +83,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -100,6 +99,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -111,16 +112,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/risc-v/src/common/riscv_usestack.c b/arch/risc-v/src/common/riscv_usestack.c index 7cdb9fbd4c4..d6debd5dcbf 100644 --- a/arch/risc-v/src/common/riscv_usestack.c +++ b/arch/risc-v/src/common/riscv_usestack.c @@ -74,8 +74,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,9 +88,9 @@ * ****************************************************************************/ -int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -130,22 +130,16 @@ 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 = (uintptr_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - #if defined(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. */ - riscv_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr + - sizeof(struct tls_info_s)), - size_of_stack - sizeof(struct tls_info_s)); + riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif return OK; diff --git a/arch/risc-v/src/k210/k210_cpuidlestack.c b/arch/risc-v/src/k210/k210_cpuidlestack.c index 9872182028a..1c59e18716f 100644 --- a/arch/risc-v/src/k210/k210_cpuidlestack.c +++ b/arch/risc-v/src/k210/k210_cpuidlestack.c @@ -67,8 +67,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/arch/risc-v/src/rv32im/riscv_assert.c b/arch/risc-v/src/rv32im/riscv_assert.c index 5b55b6d9256..a5410825090 100644 --- a/arch/risc-v/src/rv32im/riscv_assert.c +++ b/arch/risc-v/src/rv32im/riscv_assert.c @@ -184,7 +184,7 @@ static void riscv_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -238,14 +238,14 @@ static void riscv_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - riscv_stackdump(ustackbase - ustacksize, ustackbase); + riscv_stackdump(sp, ustackbase + ustacksize); } else { - riscv_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + riscv_stackdump(ustackbase, ustackbase + ustacksize); } } diff --git a/arch/risc-v/src/rv32im/riscv_initialstate.c b/arch/risc-v/src/rv32im/riscv_initialstate.c index 6338b309420..4106125070f 100644 --- a/arch/risc-v/src/rv32im/riscv_initialstate.c +++ b/arch/risc-v/src/rv32im/riscv_initialstate.c @@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb) * only the start function would do that and we have control over that one */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/risc-v/src/rv32im/riscv_vfork.c b/arch/risc-v/src/rv32im/riscv_vfork.c index 3ed4b8de857..bb390faaa05 100644 --- a/arch/risc-v/src/rv32im/riscv_vfork.c +++ b/arch/risc-v/src/rv32im/riscv_vfork.c @@ -68,16 +68,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() @@ -105,15 +105,13 @@ pid_t up_vfork(const struct vfork_s *context) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; - size_t stacksize; uint32_t newsp; #ifdef CONFIG_RISCV_FRAMEPOINTER uint32_t newfp; #endif + uint32_t newtop; + uint32_t stacktop; uint32_t stackutil; - size_t argsize; - void *argv; - int ret; sinfo("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n", context->s0, context->s1, context->s2, context->s3, context->s4); @@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context) /* Allocate and initialize a TCB for the child task. */ - child = nxtask_setup_vfork((start_t)context->ra, &argsize); + child = nxtask_setup_vfork((start_t)context->ra); if (!child) { sinfo("nxtask_setup_vfork failed\n"); @@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context) sinfo("Parent=%p Child=%p\n", parent, child); - /* Get the size of the parent task's stack. Due to alignment operations, - * the adjusted stack size may be smaller than the stack size originally - * requested. - */ - - stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1; - - /* Allocate the stack for the TCB */ - - ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize, - parent->flags & TCB_FLAG_TTYPE_MASK); - if (ret != OK) - { - serr("ERROR: up_create_stack failed: %d\n", ret); - nxtask_abort_vfork(child, -ret); - return (pid_t)ERROR; - } - - /* Allocate the memory and copy argument from parent task */ - - argv = up_stack_frame((FAR struct tcb_s *)child, argsize); - memcpy(argv, parent->adj_stack_ptr, argsize); - /* How much of the parent's stack was utilized? The RISC-V uses * a push-down stack so that the current stack pointer should * be lower than the initial, adjusted stack pointer. The * stack usage should be the difference between those two. */ - DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); - stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; + stacktop = (uint32_t)parent->stack_base_ptr + + parent->adj_stack_size; + DEBUGASSERT(stacktop > context->sp); + stackutil = stacktop - context->sp; - sinfo("stacksize:%d stackutil:%d\n", stacksize, stackutil); + sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil); /* Make some feeble effort to preserve the stack contents. This is * feeble because the stack surely contains invalid pointers and other @@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context) * effort is overkill. */ - newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; + newtop = (uint32_t)child->cmn.stack_base_ptr + + child->cmn.adj_stack_size; + newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); /* Was there a frame pointer in place before? */ #ifdef CONFIG_RISCV_FRAMEPOINTER - if (context->fp <= (uint32_t)parent->adj_stack_ptr && - context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) + if (context->fp >= context->sp && context->fp < stacktop) { - uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; - newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; + uint32_t frameutil = stacktop - context->fp; + newfp = newtop - frameutil; } else { newfp = context->fp; } - sinfo("Old stack base:%08x SP:%08x FP:%08x\n", - parent->adj_stack_ptr, context->sp, context->fp); - sinfo("New stack base:%08x SP:%08x FP:%08x\n", - child->cmn.adj_stack_ptr, newsp, newfp); + sinfo("Old stack top:%08x SP:%08x FP:%08x\n", + stacktop, context->sp, context->fp); + sinfo("New stack top:%08x SP:%08x FP:%08x\n", + newtop, newsp, newfp); #else - sinfo("Old stack base:%08x SP:%08x\n", - parent->adj_stack_ptr, context->sp); - sinfo("New stack base:%08x SP:%08x\n", - child->cmn.adj_stack_ptr, newsp); + sinfo("Old stack top:%08x SP:%08x\n", + stacktop, context->sp); + sinfo("New stack top:%08x SP:%08x\n", + newtop, newsp); #endif /* Update the stack pointer, frame pointer, global pointer and saved diff --git a/arch/risc-v/src/rv64gc/riscv_assert.c b/arch/risc-v/src/rv64gc/riscv_assert.c index 1ba121bfb92..d7a9b801ed7 100644 --- a/arch/risc-v/src/rv64gc/riscv_assert.c +++ b/arch/risc-v/src/rv64gc/riscv_assert.c @@ -195,7 +195,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uintptr_t)rtcb->adj_stack_ptr; + ustackbase = (uintptr_t)rtcb->stack_base_ptr; ustacksize = (uintptr_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -247,14 +247,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(ustackbase, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } } diff --git a/arch/risc-v/src/rv64gc/riscv_initialstate.c b/arch/risc-v/src/rv64gc/riscv_initialstate.c index afd13f63680..d20b187de89 100644 --- a/arch/risc-v/src/rv64gc/riscv_initialstate.c +++ b/arch/risc-v/src/rv64gc/riscv_initialstate.c @@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb) * only the start function would do that and we have control over that one */ - xcp->regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uintptr_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/sim/src/sim/up_checkstack.c b/arch/sim/src/sim/up_checkstack.c index 8d276e97978..1cd616526c1 100644 --- a/arch/sim/src/sim/up_checkstack.c +++ b/arch/sim/src/sim/up_checkstack.c @@ -46,7 +46,6 @@ #include #include -#include #include #include "sched/sched.h" @@ -56,7 +55,7 @@ * Private Function Prototypes ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); +static size_t do_stackcheck(uintptr_t alloc, size_t size); /**************************************************************************** * Name: do_stackcheck @@ -75,7 +74,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack); * ****************************************************************************/ -static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) +static size_t do_stackcheck(uintptr_t alloc, size_t size) { FAR uintptr_t start; FAR uintptr_t end; @@ -89,21 +88,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) /* Get aligned addresses of the top and bottom of the stack */ - if (!int_stack) - { - /* Skip over the TLS data structure at the bottom of the stack */ - -#ifdef CONFIG_TLS_ALIGNED - DEBUGASSERT((alloc & TLS_STACK_MASK) == 0); -#endif - start = alloc + sizeof(struct tls_info_s); - } - else - { - start = alloc & ~3; - } - - end = (alloc + size + 3) & ~3; + start = (alloc + 3) & ~3; + end = (alloc + size) & ~3; /* Get the adjusted size based on the top and bottom of the stack */ @@ -185,13 +171,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size, - false); + return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) diff --git a/arch/sim/src/sim/up_cpuidlestack.c b/arch/sim/src/sim/up_cpuidlestack.c index e878f2c8104..ce9e7c108c8 100644 --- a/arch/sim/src/sim/up_cpuidlestack.c +++ b/arch/sim/src/sim/up_cpuidlestack.c @@ -63,8 +63,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is @@ -82,6 +82,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) tcb->adj_stack_size = 0; tcb->stack_alloc_ptr = NULL; - tcb->adj_stack_ptr = NULL; + tcb->stack_base_ptr = NULL; return OK; } diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c index 20b6d2a7445..dcfd0d2c29a 100644 --- a/arch/sim/src/sim/up_createstack.c +++ b/arch/sim/src/sim/up_createstack.c @@ -66,8 +66,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -91,10 +91,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; - /* 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. @@ -109,43 +105,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) /* Move up to next even word boundary if necessary */ - size_t adj_stack_size = STACK_ALIGN_UP(stack_size); + size_t adj_stack_size = STACK_ALIGN_UP(stack_size); /* Allocate the memory for the stack */ #ifdef CONFIG_TLS_ALIGNED - stack_alloc_ptr = (FAR uint8_t *)kumm_memalign(TLS_STACK_ALIGN, - adj_stack_size); + stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, adj_stack_size); #else - stack_alloc_ptr = (FAR uint8_t *)kumm_malloc(adj_stack_size); + stack_alloc_ptr = kumm_malloc(adj_stack_size); #endif /* Was the allocation successful? */ if (stack_alloc_ptr) { -#if defined(CONFIG_STACK_COLORATION) - uintptr_t stack_base; -#endif - - /* This is the address of the last aligned word in the allocation. - * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte - * outside of the stack. This is okay for an initial state; the - * first pushed values will be within the stack allocation. - */ - - uintptr_t adj_stack_addr = - STACK_ALIGN_DOWN((uintptr_t)stack_alloc_ptr + adj_stack_size); - /* Save the values in the TCB */ tcb->adj_stack_size = adj_stack_size; tcb->stack_alloc_ptr = stack_alloc_ptr; - tcb->adj_stack_ptr = (FAR void *)adj_stack_addr; - - /* Initialize the TLS data structure */ - - memset(stack_alloc_ptr, 0, sizeof(struct tls_info_s)); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a @@ -153,10 +131,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * 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); - up_stack_color((FAR void *)stack_base, stack_size); + up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif /* CONFIG_STACK_COLORATION */ diff --git a/arch/sim/src/sim/up_initialstate.c b/arch/sim/src/sim/up_initialstate.c index 0a4a94c5420..bca7c25304c 100644 --- a/arch/sim/src/sim/up_initialstate.c +++ b/arch/sim/src/sim/up_initialstate.c @@ -55,11 +55,12 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(sim_getsp() - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)sim_getsp(); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } memset(&tcb->xcp, 0, sizeof(struct xcptcontext)); - tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t); + tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->stack_base_ptr + + tcb->adj_stack_size; tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start; } diff --git a/arch/sim/src/sim/up_releasestack.c b/arch/sim/src/sim/up_releasestack.c index a9e33c22725..179b699701d 100644 --- a/arch/sim/src/sim/up_releasestack.c +++ b/arch/sim/src/sim/up_releasestack.c @@ -74,5 +74,5 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) dtcb->stack_alloc_ptr = NULL; dtcb->adj_stack_size = 0; - dtcb->adj_stack_ptr = NULL; + dtcb->stack_base_ptr = NULL; } diff --git a/arch/sim/src/sim/up_stackframe.c b/arch/sim/src/sim/up_stackframe.c index 8c50d033f53..5aae8bf8a7b 100644 --- a/arch/sim/src/sim/up_stackframe.c +++ b/arch/sim/src/sim/up_stackframe.c @@ -69,9 +69,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -86,6 +85,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -97,16 +98,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; tcb->adj_stack_size -= frame_size; - /* Reset the initial state */ - - tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t); - /* And return a pointer to the allocated memory */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/sim/src/sim/up_usestack.c b/arch/sim/src/sim/up_usestack.c index d8ca91a4971..41952a0c17c 100644 --- a/arch/sim/src/sim/up_usestack.c +++ b/arch/sim/src/sim/up_usestack.c @@ -67,8 +67,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -83,7 +83,6 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { - uintptr_t adj_stack_addr; size_t adj_stack_size; #ifdef CONFIG_TLS_ALIGNED @@ -97,23 +96,11 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) adj_stack_size = STACK_ALIGN_DOWN(stack_size); - /* This is the address of the last word in the allocation. - * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte - * outside of the stack. This is okay for an initial state; the - * first pushed values will be within the stack allocation. - */ - - adj_stack_addr = STACK_ALIGN_DOWN((uintptr_t)stack + adj_stack_size); - /* Save the values in the TCB */ tcb->adj_stack_size = adj_stack_size; tcb->stack_alloc_ptr = stack; - tcb->adj_stack_ptr = (FAR void *)adj_stack_addr; - - /* Initialize the TLS data structure */ - - memset(stack, 0, sizeof(struct tls_info_s)); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #if defined(CONFIG_STACK_COLORATION) /* If stack debug is enabled, then fill the stack with a @@ -121,9 +108,7 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) * water marks. */ - up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr + - sizeof(struct tls_info_s)), - adj_stack_size - sizeof(struct tls_info_s)); + up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif return OK; diff --git a/arch/sim/src/sim/up_vfork.c b/arch/sim/src/sim/up_vfork.c index 116bad2cefc..daa4d7cb460 100644 --- a/arch/sim/src/sim/up_vfork.c +++ b/arch/sim/src/sim/up_vfork.c @@ -56,16 +56,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * This consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() @@ -86,13 +86,11 @@ pid_t up_vfork(const xcpt_reg_t *context) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; - size_t stacksize; xcpt_reg_t newsp; xcpt_reg_t newfp; + xcpt_reg_t newtop; + xcpt_reg_t stacktop; xcpt_reg_t stackutil; - size_t argsize; - void *argv; - int ret; sinfo("vfork context [%p]:\n", context); sinfo(" frame pointer:%08" PRIxPTR " sp:%08" PRIxPTR " pc:%08" PRIxPTR "" @@ -100,7 +98,7 @@ pid_t up_vfork(const xcpt_reg_t *context) /* Allocate and initialize a TCB for the child task. */ - child = nxtask_setup_vfork((start_t)(context[JB_PC]), &argsize); + child = nxtask_setup_vfork((start_t)context[JB_PC]); if (!child) { serr("ERROR: nxtask_setup_vfork failed\n"); @@ -109,38 +107,18 @@ pid_t up_vfork(const xcpt_reg_t *context) sinfo("TCBs: Parent=%p Child=%p\n", parent, child); - /* Get the size of the parent task's stack. */ - - stacksize = parent->adj_stack_size; - - /* Allocate the stack for the TCB */ - - ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize, - parent->flags & TCB_FLAG_TTYPE_MASK); - if (ret != OK) - { - serr("ERROR: up_create_stack failed: %d\n", ret); - nxtask_abort_vfork(child, -ret); - return (pid_t)ERROR; - } - - /* Allocate the memory and copy argument from parent task */ - - argv = up_stack_frame((FAR struct tcb_s *)child, argsize); - - memcpy(argv, parent->adj_stack_ptr, argsize); - /* How much of the parent's stack was utilized? The ARM uses * a push-down stack so that the current stack pointer should * be lower than the initial, adjusted stack pointer. The * stack usage should be the difference between those two. */ - DEBUGASSERT((xcpt_reg_t)parent->adj_stack_ptr > context[JB_SP]); - stackutil = (xcpt_reg_t)parent->adj_stack_ptr - context[JB_SP]; + stacktop = (xcpt_reg_t)parent->stack_base_ptr + + parent->adj_stack_size; + DEBUGASSERT(stacktop > context[JB_SP]); + stackutil = stacktop - context[JB_SP]; - sinfo("Parent: stacksize:%zu stackutil:%" PRIdPTR "\n", - stacksize, stackutil); + sinfo("Parent: stackutil:%" PRIuPTR "\n", stackutil); /* Make some feeble effort to preserve the stack contents. This is * feeble because the stack surely contains invalid pointers and other @@ -149,28 +127,27 @@ pid_t up_vfork(const xcpt_reg_t *context) * effort is overkill. */ - newsp = (xcpt_reg_t)child->cmn.adj_stack_ptr - stackutil; + newtop = (xcpt_reg_t)child->cmn.stack_base_ptr + + child->cmn.adj_stack_size; + newsp = newtop - stackutil; memcpy((void *)newsp, (const void *)context[JB_SP], stackutil); /* Was there a frame pointer in place before? */ - if (context[JB_FP] <= (xcpt_reg_t)parent->adj_stack_ptr && - context[JB_FP] >= (xcpt_reg_t)parent->adj_stack_ptr - - stacksize) + if (context[JB_FP] >= context[JB_SP] && context[JB_FP] < stacktop) { - xcpt_reg_t frameutil = (xcpt_reg_t)parent->adj_stack_ptr - - context[JB_FP]; - newfp = (xcpt_reg_t)child->cmn.adj_stack_ptr - frameutil; + xcpt_reg_t frameutil = stacktop - context[JB_FP]; + newfp = newtop - frameutil; } else { newfp = context[JB_FP]; } - sinfo("Parent: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n", - parent->adj_stack_ptr, context[JB_SP], context[JB_FP]); - sinfo("Child: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n", - child->cmn.adj_stack_ptr, newsp, newfp); + sinfo("Old stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n", + stacktop, context[JB_SP], context[JB_FP]); + sinfo("New stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n", + newtop, newsp, newfp); /* Update the stack pointer, frame pointer, and volatile registers. When * the child TCB was initialized, all of the values were set to zero. @@ -179,8 +156,8 @@ pid_t up_vfork(const xcpt_reg_t *context) * child thread. */ - memcpy(child->cmn.xcp.regs, context, sizeof(xcpt_reg_t) * - XCPTCONTEXT_REGS); + memcpy(child->cmn.xcp.regs, context, + sizeof(xcpt_reg_t) * XCPTCONTEXT_REGS); child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */ child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */ diff --git a/arch/sim/src/sim/up_vfork32.S b/arch/sim/src/sim/up_vfork32.S index 8dad26b0cb8..223a0233b89 100644 --- a/arch/sim/src/sim/up_vfork32.S +++ b/arch/sim/src/sim/up_vfork32.S @@ -63,16 +63,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/sim/src/sim/up_vfork64.S b/arch/sim/src/sim/up_vfork64.S index fa76ac1509e..48da703f539 100644 --- a/arch/sim/src/sim/up_vfork64.S +++ b/arch/sim/src/sim/up_vfork64.S @@ -63,16 +63,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/sim/src/sim/up_vfork_arm.S b/arch/sim/src/sim/up_vfork_arm.S index b75870c45ce..a60faff6b69 100644 --- a/arch/sim/src/sim/up_vfork_arm.S +++ b/arch/sim/src/sim/up_vfork_arm.S @@ -55,16 +55,16 @@ * * 1) User code calls vfork(). vfork() collects context information and * transfers control up up_vfork(). - * 2) up_vfork()and calls nxtask_setup_vfork(). + * 2) up_vfork() and calls nxtask_setup_vfork(). * 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * consists of: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() diff --git a/arch/x86/src/common/up_assert.c b/arch/x86/src/common/up_assert.c index 2f090d18f94..b7abe093a5b 100644 --- a/arch/x86/src/common/up_assert.c +++ b/arch/x86/src/common/up_assert.c @@ -145,7 +145,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -199,14 +199,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } #ifdef CONFIG_ARCH_USBDUMP diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c index 31b23726997..ed4a22b842c 100644 --- a/arch/x86/src/i486/up_createstack.c +++ b/arch/x86/src/i486/up_createstack.c @@ -63,8 +63,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -90,10 +90,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -133,16 +129,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -151,14 +145,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -194,24 +188,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/x86/src/i486/up_initialstate.c b/arch/x86/src/i486/up_initialstate.c index 254bf9fe199..fe40db4be66 100644 --- a/arch/x86/src/i486/up_initialstate.c +++ b/arch/x86/src/i486/up_initialstate.c @@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -73,7 +73,8 @@ void up_initial_state(struct tcb_s *tcb) * that depends on if a priority change is required or not. */ - xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/x86/src/i486/up_stackframe.c b/arch/x86/src/i486/up_stackframe.c index e1b1d3623a0..ebd5b005fd5 100644 --- a/arch/x86/src/i486/up_stackframe.c +++ b/arch/x86/src/i486/up_stackframe.c @@ -80,9 +80,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -97,6 +96,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c index 1e73f624c04..ac40aeb5f44 100644 --- a/arch/x86/src/i486/up_usestack.c +++ b/arch/x86/src/i486/up_usestack.c @@ -53,8 +53,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -69,7 +69,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + 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; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/x86_64/src/common/up_assert.c b/arch/x86_64/src/common/up_assert.c index e4a88fb6cc4..88f5a72dd38 100644 --- a/arch/x86_64/src/common/up_assert.c +++ b/arch/x86_64/src/common/up_assert.c @@ -123,7 +123,7 @@ static void up_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint64_t)rtcb->adj_stack_ptr; + ustackbase = (uint64_t)rtcb->stack_base_ptr; ustacksize = (uint64_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -172,15 +172,14 @@ static void up_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { -#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 - _alert("ERROR: Stack pointer is not within allocated stack\n"); -#endif + up_stackdump(sp, ustackbase + ustacksize); } else { - up_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + up_stackdump(ustackbase, ustackbase + ustacksize); } /* Then dump the registers (if available) */ diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c index e56e739f5f2..958e07240a9 100644 --- a/arch/x86_64/src/intel64/up_createstack.c +++ b/arch/x86_64/src/intel64/up_createstack.c @@ -63,8 +63,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -90,10 +90,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -133,16 +129,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -151,14 +145,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive quad-words offsets from sp. */ - top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The intel64 stack must be aligned at word (16 byte) boundaries. If * necessary top_of_stack must be rounded down to the next boundary. @@ -203,17 +197,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) */ top_of_stack &= ~0x0f; - size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr; + 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_ptr = (uint64_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/x86_64/src/intel64/up_initialstate.c b/arch/x86_64/src/intel64/up_initialstate.c index a4fff0149f8..a517c04db19 100644 --- a/arch/x86_64/src/intel64/up_initialstate.c +++ b/arch/x86_64/src/intel64/up_initialstate.c @@ -51,12 +51,9 @@ * ****************************************************************************/ -extern uintptr_t tux_mm_new_pd1(void); - void up_initial_state(struct tcb_s *tcb) { struct xcptcontext *xcp = &tcb->xcp; - struct tcb_s *rtcb; /* Initialize the idle thread stack */ @@ -64,7 +61,7 @@ void up_initial_state(struct tcb_s *tcb) { tcb->stack_alloc_ptr = (void *)(g_idle_topstack - CONFIG_IDLETHREAD_STACKSIZE); - tcb->adj_stack_ptr = (void *)g_idle_topstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -80,17 +77,14 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[3] = (uint64_t)0x0000000000001f80; - /* set page table to share space with current process */ - - rtcb = this_task(); - UNUSED(rtcb); - /* Save the initial stack pointer... the value of the stackpointer before * the "interrupt occurs." */ - xcp->regs[REG_RSP] = (uint64_t)tcb->adj_stack_ptr; - xcp->regs[REG_RBP] = (uint64_t)tcb->adj_stack_ptr; + xcp->regs[REG_RSP] = (uint64_t)tcb->stack_base_ptr + + tcb->adj_stack_size; + xcp->regs[REG_RBP] = (uint64_t)tcb->stack_base_ptr + + tcb->adj_stack_size; /* Save the task entry point */ diff --git a/arch/x86_64/src/intel64/up_stackframe.c b/arch/x86_64/src/intel64/up_stackframe.c index b8256de41dc..2fc0b978229 100644 --- a/arch/x86_64/src/intel64/up_stackframe.c +++ b/arch/x86_64/src/intel64/up_stackframe.c @@ -80,9 +80,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -97,6 +96,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, tcb->adj_stack_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_RSP] = (uint64_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c index 26ee3b7ab9f..6a1bbed2315 100644 --- a/arch/x86_64/src/intel64/up_usestack.c +++ b/arch/x86_64/src/intel64/up_usestack.c @@ -53,8 +53,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -69,7 +69,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * referenced as positive word offsets from sp. */ - top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The intel64 stack must be aligned at word (16 byte) boundaries. If * necessary top_of_stack must be rounded down to the next boundary. @@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) */ top_of_stack &= ~0x0f; - size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr; + 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_ptr = (uint64_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/xtensa/src/common/xtensa_checkstack.c b/arch/xtensa/src/common/xtensa_checkstack.c index b27d9b1e606..2e2a4347d77 100644 --- a/arch/xtensa/src/common/xtensa_checkstack.c +++ b/arch/xtensa/src/common/xtensa_checkstack.c @@ -31,7 +31,6 @@ #include #include -#include #include #include "xtensa.h" @@ -87,10 +86,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size) * Skip over the TLS data structure at the bottom of the stack */ -#ifdef CONFIG_TLS_ALIGNED - DEBUGASSERT((alloc & TLS_STACK_MASK) == 0); -#endif - start = STACK_ALIGN_UP(alloc + sizeof(struct tls_info_s)); + start = STACK_ALIGN_UP(alloc); end = STACK_ALIGN_DOWN(alloc + size); /* Get the adjusted size based on the top and bottom of the stack */ @@ -173,12 +169,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size) size_t up_check_tcbstack(FAR struct tcb_s *tcb) { - return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size); + return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size); } ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) { - return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb); + return tcb->adj_stack_size - up_check_tcbstack(tcb); } size_t up_check_stack(void) diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c index 9a42dfbab65..b3a6556382a 100644 --- a/arch/xtensa/src/common/xtensa_createstack.c +++ b/arch/xtensa/src/common/xtensa_createstack.c @@ -71,8 +71,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -103,10 +103,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) uintptr_t cpstart; #endif - /* 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. @@ -156,16 +152,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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 *)UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -174,14 +168,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 *)UMM_MALLOC(stack_size); + tcb->stack_alloc_ptr = UMM_MALLOC(stack_size); } #endif /* CONFIG_TLS_ALIGNED */ @@ -243,26 +237,20 @@ 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); - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* 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. */ - up_stack_color((FAR void *)tcb->stack_alloc_ptr + - sizeof(struct tls_info_s), - tcb->adj_stack_size - sizeof(struct tls_info_s)); + up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif board_autoled_on(LED_STACKCREATED); diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c index bd05c45a301..34e70e0af1e 100644 --- a/arch/xtensa/src/common/xtensa_dumpstate.c +++ b/arch/xtensa/src/common/xtensa_dumpstate.c @@ -291,7 +291,7 @@ void xtensa_dumpstate(void) /* Get the limits on the user stack memory */ - ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustackbase = (uint32_t)rtcb->stack_base_ptr; ustacksize = (uint32_t)rtcb->adj_stack_size; /* Get the limits on the interrupt stack memory */ @@ -362,14 +362,14 @@ void xtensa_dumpstate(void) * stack memory. */ - if (sp >= ustackbase || sp < ustackbase - ustacksize) + if (sp >= ustackbase && sp < ustackbase + ustacksize) { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - xtensa_stackdump(ustackbase - ustacksize, ustackbase); + xtensa_stackdump(sp, ustackbase + ustacksize); } else { - xtensa_stackdump(sp, ustackbase); + _alert("ERROR: Stack pointer is not within allocated stack\n"); + xtensa_stackdump(ustackbase, ustackbase + ustacksize); } /* Dump the state of all tasks (if available) */ diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c index 1dc939eb390..772ad0e9eb5 100644 --- a/arch/xtensa/src/common/xtensa_initialstate.c +++ b/arch/xtensa/src/common/xtensa_initialstate.c @@ -63,8 +63,7 @@ void up_initial_state(struct tcb_s *tcb) if (tcb->pid == 0) { tcb->stack_alloc_ptr = g_idlestack; - tcb->adj_stack_ptr = (char *)g_idlestack + - CONFIG_IDLETHREAD_STACKSIZE; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -74,9 +73,10 @@ void up_initial_state(struct tcb_s *tcb) /* Set initial values of registers */ - xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Task entrypoint */ - xcp->regs[REG_A0] = 0; /* To terminate GDB backtrace */ - xcp->regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr; /* Physical top of stack frame */ + xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Task entrypoint */ + xcp->regs[REG_A0] = 0; /* To terminate GDB backtrace */ + xcp->regs[REG_A1] = (uint32_t)tcb->stack_base_ptr + /* Physical top of stack frame */ + tcb->adj_stack_size; /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user * mode. diff --git a/arch/xtensa/src/common/xtensa_stackframe.c b/arch/xtensa/src/common/xtensa_stackframe.c index e7589eccea2..7707168686d 100644 --- a/arch/xtensa/src/common/xtensa_stackframe.c +++ b/arch/xtensa/src/common/xtensa_stackframe.c @@ -68,9 +68,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -85,6 +84,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -96,16 +97,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer (A1) */ - - tcb->xcp.regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return the pointer to the allocated region */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c index e3b6677cc5f..647b2bb4592 100644 --- a/arch/xtensa/src/common/xtensa_usestack.c +++ b/arch/xtensa/src/common/xtensa_usestack.c @@ -67,8 +67,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -83,7 +83,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -111,33 +111,27 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The XTENSA stack must be aligned at 16 bytes boundaries. If necessary * top_of_stack must be rounded down to the next boundary. */ top_of_stack = STACK_ALIGN_DOWN(top_of_stack); - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - #if defined(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. */ - up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr + - sizeof(struct tls_info_s)), - size_of_stack - sizeof(struct tls_info_s)); + up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size); #endif return OK; diff --git a/arch/xtensa/src/esp32/esp32_cpuidlestack.c b/arch/xtensa/src/esp32/esp32_cpuidlestack.c index 3aad0cfb29e..a12d7744c1c 100644 --- a/arch/xtensa/src/esp32/esp32_cpuidlestack.c +++ b/arch/xtensa/src/esp32/esp32_cpuidlestack.c @@ -73,8 +73,8 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS] * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is @@ -88,8 +88,6 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS] int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) { - uintptr_t topofstack; - /* XTENSA 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 @@ -100,9 +98,7 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) tcb->stack_alloc_ptr = g_cpu1_idlestack; tcb->adj_stack_size = CPU1_IDLETHREAD_STACKSIZE; - topofstack = (uintptr_t)g_cpu1_idlestack + - CPU1_IDLETHREAD_STACKSIZE; - tcb->adj_stack_ptr = (uint32_t *)topofstack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #if XCHAL_CP_NUM > 0 /* REVISIT: Does it make since to have co-processors enabled on the IDLE diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 8fa169d94c8..742f078f572 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -158,7 +158,7 @@ void xtensa_appcpu_start(void) * is to switch to a well-known IDLE thread stack. */ - sp = (uint32_t)tcb->adj_stack_ptr; + sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size; __asm__ __volatile__("mov sp, %0\n" : : "r"(sp)); sinfo("CPU%d Started\n", up_cpu_index()); diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c index 86300692df0..5c3004db4c6 100644 --- a/arch/z16/src/common/z16_createstack.c +++ b/arch/z16/src/common/z16_createstack.c @@ -62,8 +62,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -84,10 +84,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -127,16 +123,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -145,14 +139,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -170,7 +164,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -188,24 +182,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* Align the stack to word (4 byte) boundaries. This is probably * a greater alignment than is required. */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/z16/src/common/z16_initialstate.c b/arch/z16/src/common/z16_initialstate.c index bff065626d6..216823c1a62 100644 --- a/arch/z16/src/common/z16_initialstate.c +++ b/arch/z16/src/common/z16_initialstate.c @@ -59,6 +59,7 @@ void up_initial_state(struct tcb_s *tcb) #ifndef CONFIG_SUPPRESS_INTERRUPTS tcb->xcp.regs[REG_FLAGS] = (uint16_t)Z16F_CNTRL_FLAGS_IRQE; /* IRQE flag will enable interrupts */ #endif - reg32[REG_SP / 2] = (uint32_t)tcb->adj_stack_ptr; + reg32[REG_SP / 2] = (uint32_t)tcb->stack_base_ptr + + tcb->adj_stack_size; reg32[REG_PC / 2] = (uint32_t)tcb->start; } diff --git a/arch/z16/src/common/z16_stackdump.c b/arch/z16/src/common/z16_stackdump.c index 73648d035dc..705aa67ce62 100644 --- a/arch/z16/src/common/z16_stackdump.c +++ b/arch/z16/src/common/z16_stackdump.c @@ -50,7 +50,7 @@ static void z16_stackdump(void) { struct tcb_s *rtcb = this_task(); chipreg_t sp = z16_getsp(); - chipreg_t stack_base = (chipreg_t)rtcb->adj_stack_ptr; + chipreg_t stack_base = (chipreg_t)rtcb->stack_base_ptr; chipreg_t stack_size = (chipreg_t)rtcb->adj_stack_size; chipreg_t stack; @@ -58,18 +58,18 @@ static void z16_stackdump(void) _alert("stack_size: %08x\n", stack_size); _alert("sp: %08x\n", sp); - if (sp >= stack_base || sp < stack_base - stack_size) - { - _err("ERROR: Stack pointer is not within allocated stack\n"); - stack = stack_base - stack_size; - } - else + if (sp >= stack_base && sp < stack_base + stack_size) { stack = sp; } + else + { + _err("ERROR: Stack pointer is not within allocated stack\n"); + stack = stack_base; + } for (stack = stack & ~0x0f; - stack < stack_base; + stack < stack_base + stack_size; stack += 8 * sizeof(chipreg_t)) { chipreg_t *ptr = (chipreg_t *)stack; diff --git a/arch/z16/src/common/z16_stackframe.c b/arch/z16/src/common/z16_stackframe.c index a42170470c6..6b1e09dc83b 100644 --- a/arch/z16/src/common/z16_stackframe.c +++ b/arch/z16/src/common/z16_stackframe.c @@ -71,9 +71,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,6 +87,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; - tcb->adj_stack_size -= frame_size; - - /* Reset the initial stack pointer */ - - tcb->xcp.regs[REG_SP / 2] = (uint32_t)tcb->adj_stack_ptr; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; + tcb->adj_stack_size -= frame_size; /* And return a pointer to the allocated memory */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/z16/src/common/z16_usestack.c b/arch/z16/src/common/z16_usestack.c index bfdc548febb..a5a374c8de9 100644 --- a/arch/z16/src/common/z16_usestack.c +++ b/arch/z16/src/common/z16_usestack.c @@ -53,8 +53,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -67,9 +67,9 @@ * ****************************************************************************/ -int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) +int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * the stack are referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* Align the stack to word (4 byte) boundaries. This is probably * a greater alignment than is required. */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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 = top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c index 3585f3cd338..4826af9e634 100644 --- a/arch/z80/src/common/z80_createstack.c +++ b/arch/z80/src/common/z80_createstack.c @@ -61,8 +61,8 @@ * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -88,10 +88,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { - /* 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. @@ -131,16 +127,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_memalign(TLS_STACK_ALIGN, stack_size); + tcb->stack_alloc_ptr = 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); + tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size); } #else /* CONFIG_TLS_ALIGNED */ @@ -149,14 +143,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); } #endif /* CONFIG_TLS_ALIGNED */ @@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) if (tcb->stack_alloc_ptr) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a @@ -193,24 +187,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) * referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The Z80 stack does not need to be aligned. Here is is aligned at * word (4 byte) boundary. */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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_ptr = (FAR uint32_t *)top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - board_autoled_on(LED_STACKCREATED); return OK; } diff --git a/arch/z80/src/common/z80_stackdump.c b/arch/z80/src/common/z80_stackdump.c index 189c5a9e994..093696e3a2c 100644 --- a/arch/z80/src/common/z80_stackdump.c +++ b/arch/z80/src/common/z80_stackdump.c @@ -45,7 +45,7 @@ void up_stackdump(void) { FAR struct tcb_s *rtcb = this_task(); uintptr_t sp = z80_getsp(); - uintptr_t stack_base = (uintptr_t)rtcb->adj_stack_ptr; + uintptr_t stack_base = (uintptr_t)rtcb->stack_base_ptr; uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size; uintptr_t stack; @@ -53,17 +53,17 @@ void up_stackdump(void) _alert("stack_size: %06x\n", stack_size); _alert("sp: %06x\n", sp); - if (sp >= stack_base || sp < stack_base - stack_size) - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - stack = stack_base - stack_size; - } - else + if (sp >= stack_base && sp < stack_base + stack_size) { stack = sp; } + else + { + _alert("ERROR: Stack pointer is not within allocated stack\n"); + stack = stack_base; + } - for (stack = stack & ~0x0f; stack < stack_base; stack += 16) + for (stack = stack & ~0x0f; stack < stack_base + stack_size; stack += 16) { FAR uint8_t *ptr = (FAR uint8_t *)stack; diff --git a/arch/z80/src/common/z80_stackframe.c b/arch/z80/src/common/z80_stackframe.c index 2120bb9c323..37562009886 100644 --- a/arch/z80/src/common/z80_stackframe.c +++ b/arch/z80/src/common/z80_stackframe.c @@ -70,9 +70,8 @@ * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -87,6 +86,8 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) { + FAR void *ret; + /* Align the frame_size */ frame_size = STACK_ALIGN_UP(frame_size); @@ -98,16 +99,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) return NULL; } + ret = tcb->stack_base_ptr; + memset(ret, 0, frame_size); + /* Save the adjusted stack values in the struct tcb_s */ - tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size; + tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size; tcb->adj_stack_size -= frame_size; - /* Reset the initial stack pointer */ - - tcb->xcp.regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; - /* And return a pointer to the allocated memory */ - return tcb->adj_stack_ptr; + return ret; } diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c index 260d8842514..40b212b594f 100644 --- a/arch/z80/src/common/z80_usestack.c +++ b/arch/z80/src/common/z80_usestack.c @@ -52,8 +52,8 @@ * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -68,7 +68,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) { - size_t top_of_stack; + uintptr_t top_of_stack; size_t size_of_stack; #ifdef CONFIG_TLS_ALIGNED @@ -104,23 +104,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) * the stack are* referenced as positive word offsets from sp. */ - top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size; + top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size; /* The Z80 stack does not need to be aligned. Here is is aligned at * word (4 byte) boundary. */ top_of_stack &= ~3; - size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr; + 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 = top_of_stack; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = size_of_stack; - /* Initialize the TLS data structure */ - - memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s)); - return OK; } diff --git a/arch/z80/src/ez80/ez80_initialstate.c b/arch/z80/src/ez80/ez80_initialstate.c index d6d057330a8..cd97727dded 100644 --- a/arch/z80/src/ez80/ez80_initialstate.c +++ b/arch/z80/src/ez80/ez80_initialstate.c @@ -52,7 +52,7 @@ void up_initial_state(FAR struct tcb_s *tcb) { - struct xcptcontext *xcp = &tcb->xcp; + FAR struct xcptcontext *xcp = &tcb->xcp; /* Initialize the initial exception register context structure */ @@ -61,9 +61,10 @@ void up_initial_state(FAR struct tcb_s *tcb) #ifndef CONFIG_SUPPRESS_INTERRUPTS /* Parity/Overflow flag will enable interrupts */ - ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG; + ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG; #endif - xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; } diff --git a/arch/z80/src/z180/z180_initialstate.c b/arch/z80/src/z180/z180_initialstate.c index 43f4c5281e7..f05ce92d274 100644 --- a/arch/z80/src/z180/z180_initialstate.c +++ b/arch/z80/src/z180/z180_initialstate.c @@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb) if (tcb->pid == 0) { tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE; - tcb->adj_stack_ptr = (void *)(CONFIG_STACK_BASE + - CONFIG_IDLETHREAD_STACKSIZE); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb) #ifndef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[XCPT_I] = Z180_PV_FLAG; /* Parity flag will enable interrupts */ #endif - xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; } diff --git a/arch/z80/src/z8/z8_initialstate.c b/arch/z80/src/z8/z8_initialstate.c index d62c4b973b0..187e1625c06 100644 --- a/arch/z80/src/z8/z8_initialstate.c +++ b/arch/z80/src/z8/z8_initialstate.c @@ -74,6 +74,7 @@ void up_initial_state(FAR struct tcb_s *tcb) xcp->regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */ #endif xcp->regs[XCPT_RPFLAGS] = 0xe000; /* RP=%e0 */ - xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; } diff --git a/arch/z80/src/z80/z80_initialstate.c b/arch/z80/src/z80/z80_initialstate.c index 05c2df32076..9b24a6524bd 100644 --- a/arch/z80/src/z80/z80_initialstate.c +++ b/arch/z80/src/z80/z80_initialstate.c @@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb) if (tcb->pid == 0) { tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE; - tcb->adj_stack_ptr = (void *)(CONFIG_STACK_BASE + - CONFIG_IDLETHREAD_STACKSIZE); + tcb->stack_base_ptr = tcb->stack_alloc_ptr; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; } @@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb) #ifndef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[XCPT_I] = Z80_PV_FLAG; /* Parity flag will enable interrupts */ #endif - xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr; + xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr + + tcb->adj_stack_size; xcp->regs[XCPT_PC] = (chipreg_t)tcb->start; } diff --git a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c index 83117c3eb80..8ccf65f9136 100644 --- a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c +++ b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c @@ -181,7 +181,8 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb, pdump->info.stacks.user.sp = currentsp; } - pdump->info.stacks.user.top = (uint32_t)rtcb->adj_stack_ptr; + pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr + + rtcb->adj_stack_size; pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c index df58f7504f1..fb14e793984 100644 --- a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c +++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c @@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb, pdump->info.stacks.user.sp = currentsp; } - pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr; - pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size; + pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr + + rtcb->adj_stack_size; + pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 /* Get the limits on the interrupt stack memory */ diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c index 87e2f1a2911..b3a16005e1c 100644 --- a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c +++ b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c @@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb, pdump->info.stacks.user.sp = currentsp; } - pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr; - pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size; + pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr + + rtcb->adj_stack_size; + pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 /* Get the limits on the interrupt stack memory */ diff --git a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c index 0118242fe93..31153f7baa7 100644 --- a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c +++ b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c @@ -403,8 +403,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb, pdump->info.stacks.user.sp = currentsp; } - pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr; - pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size; + pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr + + rtcb->adj_stack_size; + pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 /* Get the limits on the interrupt stack memory */ diff --git a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c index cda6328620d..04a8ab3e783 100644 --- a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c +++ b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c @@ -401,8 +401,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb, pdump->info.stacks.user.sp = currentsp; } - pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr; - pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size; + pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr + + rtcb->adj_stack_size; + pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size; #if CONFIG_ARCH_INTERRUPTSTACK > 3 /* Get the limits on the interrupt stack memory */ diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index a3af61f65d1..83018676412 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -857,7 +857,7 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile, /* Show the stack base address */ linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s0x%p\n", - "StackBase:", tcb->adj_stack_ptr); + "StackBase:", tcb->stack_base_ptr); copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset); diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 379146e51ac..f9e5bda7d88 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -232,8 +232,8 @@ void up_initial_state(FAR struct tcb_s *tcb); * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -274,8 +274,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype); * processor, etc. This value is retained only for debug * purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The - * initial value of the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - tcb: The TCB of new task @@ -308,9 +308,24 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size); * * - adj_stack_size: Stack size after removal of the stack frame from * the stack - * - adj_stack_ptr: Adjusted initial stack pointer after the frame has - * been removed from the stack. This will still be the initial value - * of the stack pointer when the task is started. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. + * + * Here is the diagram after some allocation(tls, arg): + * + * +-------------+ <-stack_alloc_ptr(lowest) + * | TLS Data | + * +-------------+ + * | Arguments | + * stack_base_ptr-> +-------------+\ + * | Available | + + * | Stack | | + * | | | | + * | | | +->adj_stack_size + * v | | | + * | | | + * | | + + * +-------------+/ * * Input Parameters: * - tcb: The TCB of new task @@ -1847,8 +1862,8 @@ int up_cpu_index(void); * - adj_stack_size: Stack size after adjustment for hardware, processor, * etc. This value is retained only for debug purposes. * - stack_alloc_ptr: Pointer to allocated stack - * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of - * the stack pointer. + * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and + * Arguments has been removed from the stack allocation. * * Input Parameters: * - cpu: CPU index that indicates which CPU the IDLE task is diff --git a/include/nuttx/lib/libvars.h b/include/nuttx/lib/libvars.h deleted file mode 100644 index 47612cc7a00..00000000000 --- a/include/nuttx/lib/libvars.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** - * include/nuttx/lib/libvars.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_LIB_LIBVARS_H -#define __INCLUDE_NUTTX_LIB_LIBVARS_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -#ifndef CONFIG_BUILD_KERNEL -/* This structure encapsulates all task-specific variables needed by the C - * Library. This structure is retained at the beginning of the main thread - * of and is accessed via a reference stored in the TLS of all threads in - * the task group. - * - * NOTE: task-specific variables are not needed in the KERNEL build. In - * that build mode, all global variables are inherently process-specific. - */ - -struct libvars_s -{ - struct getopt_s lv_getopt; /* Globals used by getopt() */ -}; -#endif - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __INCLUDE_NUTTX_LIB_LIBVARS_H */ diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 4e06514a332..4f7f647a27b 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -401,8 +400,9 @@ struct stackinfo_s /* (for debug purposes only) */ FAR void *stack_alloc_ptr; /* Pointer to allocated stack */ /* Needed to deallocate stack */ - FAR void *adj_stack_ptr; /* Adjusted stack_alloc_ptr for HW */ - /* The initial stack pointer value */ + FAR void *stack_base_ptr; /* Adjusted initial stack pointer */ + /* after the frame has been removed */ + /* from the stack. */ }; /* struct exitinfo_s ************************************************************/ @@ -530,12 +530,6 @@ struct task_group_s tls_ndxset_t tg_tlsset; /* Set of TLS data indexes allocated */ #endif - /* Task-specific Data *********************************************************/ - -#ifndef CONFIG_BUILD_KERNEL - FAR struct libvars_s *tg_libvars; /* C library global variables */ -#endif - /* POSIX Signal Control Fields ************************************************/ sq_queue_t tg_sigactionq; /* List of actions for signals */ @@ -662,8 +656,9 @@ struct tcb_s /* (for debug purposes only) */ FAR void *stack_alloc_ptr; /* Pointer to allocated stack */ /* Needed to deallocate stack */ - FAR void *adj_stack_ptr; /* Adjusted stack_alloc_ptr for HW */ - /* The initial stack pointer value */ + FAR void *stack_base_ptr; /* Adjusted initial stack pointer */ + /* after the frame has been removed */ + /* from the stack. */ /* External Module Support ****************************************************/ @@ -1030,10 +1025,10 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]); * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) vfork() provides any additional operating context. vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) vfork() provides any additional operating context. vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) vfork() then calls nxtask_start_vfork() @@ -1043,7 +1038,7 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]); * ********************************************************************************/ -FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize); +FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr); pid_t nxtask_start_vfork(FAR struct task_tcb_s *child); void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode); @@ -1330,7 +1325,7 @@ int nxsched_set_affinity(pid_t pid, size_t cpusetsize, * * Input Parameters: * pid - Identifies the thread to query. Zero is interpreted as the - * the calling thread + * the calling thread, -1 is interpreted as the calling task. * stackinfo - User-provided location to return the stack information. * * Returned Value: diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index bd729d36dbc..79f0e78abed 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -27,7 +27,7 @@ #include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -71,6 +71,26 @@ * * The stack memory is fully accessible to user mode threads. TLS is not * available from interrupt handlers (nor from the IDLE thread). + * + * The following diagram represent the typic stack layout: + * + * Push Down Push Up + * +-------------+ +-------------+ <- Stack memory allocation + * | TLS Data | | TLS Data | + * +-------------+ +-------------+ + * | Task Data* | | Task Data* | + * +-------------+ +-------------+ + * | Arguments | | Arguments | + * +-------------+ +-------------+ | + * | | | | v + * | Available | | Available | + * | Stack | | Stack | + * | | | | + * | | | | + * | | ^ | | + * +-------------+ | +-------------+ + * + * Task data is allocated in the main's thread's stack only */ struct tls_info_s @@ -78,10 +98,17 @@ struct tls_info_s #if CONFIG_TLS_NELEM > 0 uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ #endif - FAR struct libvars_s *tl_libvars; /* Task-specific C library data */ int tl_errno; /* Per-thread error number */ }; +struct task_info_s +{ + struct tls_info_s ta_tls; /* Must be first field */ +#ifndef CONFIG_BUILD_KERNEL + struct getopt_s ta_getopt; /* Globals used by getopt() */ +#endif +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -189,4 +216,21 @@ int tls_set_value(int tlsindex, uintptr_t tlsvalue); FAR struct tls_info_s *tls_get_info(void); #endif +/**************************************************************************** + * Name: task_get_info + * + * Description: + * Return a reference to the task_info_s structure. + * + * Input Parameters: + * None + * + * Returned Value: + * A reference to the task-specific task_info_s structure is return on + * success. NULL would be returned in the event of any failure. + * + ****************************************************************************/ + +FAR struct task_info_s *task_get_info(void); + #endif /* __INCLUDE_NUTTX_TLS_H */ diff --git a/libs/libc/pthread/pthread_get_stackaddr_np.c b/libs/libc/pthread/pthread_get_stackaddr_np.c index e2be5468770..a8a570b46ac 100644 --- a/libs/libc/pthread/pthread_get_stackaddr_np.c +++ b/libs/libc/pthread/pthread_get_stackaddr_np.c @@ -74,5 +74,5 @@ FAR void *pthread_get_stackaddr_np(pthread_t thread) return NULL; } - return stackinfo.adj_stack_ptr; + return stackinfo.stack_base_ptr; } diff --git a/libs/libc/tls/Make.defs b/libs/libc/tls/Make.defs index 0e125f8ecb5..504d2c6a0bf 100644 --- a/libs/libc/tls/Make.defs +++ b/libs/libc/tls/Make.defs @@ -18,6 +18,8 @@ # ############################################################################ +CSRCS += task_getinfo.c + ifneq ($(CONFIG_TLS_NELEM),0) CSRCS += tls_setvalue.c tls_getvalue.c endif diff --git a/sched/group/group_taskdata.c b/libs/libc/tls/task_getinfo.c similarity index 68% rename from sched/group/group_taskdata.c rename to libs/libc/tls/task_getinfo.c index 392cb3d8303..8ae77a183ce 100644 --- a/sched/group/group_taskdata.c +++ b/libs/libc/tls/task_getinfo.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/group/group_taskdata.c + * libs/libc/tls/task_getinfo.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,51 +25,39 @@ #include #include -#include #include -#include "group/group.h" - -#ifndef CONFIG_BUILD_KERNEL - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: tls_set_taskdata + * Name: task_get_info * * Description: - * Set task-specific data pointer in TLS. + * Return a reference to the task_info_s structure. * * Input Parameters: - * tcb - Identifies task to set TLS data + * None * * Returned Value: - * None + * A reference to the task-specific task_info_s structure is return on + * success. NULL would be returned in the event of any failure. * ****************************************************************************/ -void tls_set_taskdata(FAR struct tcb_s *tcb) +FAR struct task_info_s *task_get_info(void) { - FAR struct tls_info_s *info; - FAR struct task_group_s *group; + FAR struct task_info_s *info = NULL; + struct stackinfo_s stackinfo; + int ret; - DEBUGASSERT(tcb != NULL && tcb->group != NULL); - group = tcb->group; + ret = nxsched_get_stackinfo(-1, &stackinfo); + if (ret >= 0) + { + info = (FAR struct task_info_s *)stackinfo.stack_alloc_ptr; + } - /* This currently assumes a push-down stack. The TLS data lies at the - * lowest address of the stack allocation. - */ - - info = (FAR struct tls_info_s *)tcb->stack_alloc_ptr; - - /* Copy the task data point buffer in the group structure into the - * thread's TLS data. - */ - - info->tl_libvars = group->tg_libvars; + return info; } - -#endif /* !CONFIG_BUILD_KERNEL */ \ No newline at end of file diff --git a/libs/libc/tls/tls.h b/libs/libc/tls/tls.h deleted file mode 100644 index d935baff0ae..00000000000 --- a/libs/libc/tls/tls.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * libs/libc/tls/tls.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __SCHED_TLS_TLS_H -#define __SCHED_TLS_TLS_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#endif /* __SCHED_TLS_TLS_H */ diff --git a/libs/libc/unistd/lib_getoptvars.c b/libs/libc/unistd/lib_getoptvars.c index 1e159258b13..cc0fde2cd5a 100644 --- a/libs/libc/unistd/lib_getoptvars.c +++ b/libs/libc/unistd/lib_getoptvars.c @@ -24,16 +24,11 @@ #include -#include #include #include -#include - -#include #include "unistd.h" -#include "libc.h" /**************************************************************************** * Private Data @@ -70,13 +65,13 @@ FAR struct getopt_s g_getopt_vars = FAR struct getopt_s *getoptvars(void) { #ifndef CONFIG_BUILD_KERNEL - FAR struct tls_info_s *tlsinfo; + FAR struct task_info_s *info; /* Get the structure of getopt() variables using the key. */ - tlsinfo = up_tls_info(); - DEBUGASSERT(tlsinfo != NULL && tlsinfo->tl_libvars != NULL); - return &tlsinfo->tl_libvars->lv_getopt; + info = task_get_info(); + DEBUGASSERT(info != NULL); + return &info->ta_getopt; #else return &g_getopt_vars; #endif diff --git a/sched/group/Make.defs b/sched/group/Make.defs index 9d2e6769960..14f12257491 100644 --- a/sched/group/Make.defs +++ b/sched/group/Make.defs @@ -57,10 +57,6 @@ ifneq ($(CONFIG_TLS_NELEM),0) CSRCS += group_tlsalloc.c group_tlsfree.c endif -ifndef CONFIG_BUILD_KERNEL -CSRCS += group_taskdata.c -endif - # Include group build support DEPPATH += --dep-path group diff --git a/sched/group/group.h b/sched/group/group.h index 94b49bf07ee..3449891803f 100644 --- a/sched/group/group.h +++ b/sched/group/group.h @@ -140,10 +140,4 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb); int group_setupstreams(FAR struct task_tcb_s *tcb); #endif -#ifndef CONFIG_BUILD_KERNEL -/* Task specific data */ - -void tls_set_taskdata(FAR struct tcb_s *tcb); -#endif - #endif /* __SCHED_GROUP_GROUP_H */ diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 007c7bf23e9..1c4af3b9b92 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "sched/sched.h" #include "group/group.h" @@ -218,6 +219,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, pthread_startroutine_t start_routine, pthread_addr_t arg) { FAR struct pthread_tcb_s *ptcb; + FAR struct tls_info_s *info; FAR struct join_s *pjoin; struct sched_param param; int policy; @@ -291,7 +293,8 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, { /* Allocate the stack for the TCB */ - ret = up_create_stack((FAR struct tcb_s *)ptcb, attr->stacksize, + ret = up_create_stack((FAR struct tcb_s *)ptcb, + sizeof(struct tls_info_s) + attr->stacksize, TCB_FLAG_TTYPE_PTHREAD); } @@ -301,11 +304,16 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, goto errout_with_join; } -#ifndef CONFIG_BUILD_KERNEL - /* Save the allocated task data in TLS */ + /* Initialize thread local storage */ - tls_set_taskdata(&ptcb->cmn); -#endif + info = up_stack_frame(&ptcb->cmn, sizeof(struct tls_info_s)); + if (info == NULL) + { + errcode = ENOMEM; + goto errout_with_join; + } + + DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr); /* Should we use the priority and scheduler specified in the pthread * attributes? Or should we use the current thread's priority and diff --git a/sched/sched/sched_get_stackinfo.c b/sched/sched/sched_get_stackinfo.c index 12209645742..7d6bda0ae34 100644 --- a/sched/sched/sched_get_stackinfo.c +++ b/sched/sched/sched_get_stackinfo.c @@ -42,7 +42,7 @@ * * Input Parameters: * pid - Identifies the thread to query. Zero is interpreted as the - * the calling thread + * the calling thread, -1 is interpreted as the calling task. * stackinfo - User-provided location to return the stack information. * * Returned Value: @@ -69,6 +69,16 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo) qtcb = rtcb; } + else if (pid == -1) + { + /* We can always query our main thread */ + + qtcb = nxsched_get_tcb(rtcb->group->tg_pid); + if (qtcb == NULL) + { + return -ENOENT; + } + } else { /* Get the task to be queried */ @@ -100,6 +110,7 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo) stackinfo->adj_stack_size = qtcb->adj_stack_size; stackinfo->stack_alloc_ptr = qtcb->stack_alloc_ptr; - stackinfo->adj_stack_ptr = qtcb->adj_stack_ptr; + stackinfo->stack_base_ptr = qtcb->stack_base_ptr; + return OK; } diff --git a/sched/task/task_init.c b/sched/task/task_init.c index bd6a9bca682..ba34b93bc6a 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include "sched/sched.h" #include "group/group.h" @@ -85,9 +85,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, main_t entry, FAR char * const argv[]) { uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; -#ifndef CONFIG_BUILD_KERNEL - FAR struct task_group_s *group; -#endif + FAR struct task_info_s *info; int ret; #ifndef CONFIG_DISABLE_PTHREAD @@ -122,7 +120,9 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, { /* Allocate the stack for the TCB */ - ret = up_create_stack(&tcb->cmn, stack_size, ttype); + ret = up_create_stack(&tcb->cmn, + sizeof(struct task_info_s) + stack_size, + ttype); } if (ret < OK) @@ -130,21 +130,16 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, goto errout_with_group; } -#ifndef CONFIG_BUILD_KERNEL - /* Allocate a stack frame to hold task-specific data */ + /* Initialize thread local storage */ - group = tcb->cmn.group; - group->tg_libvars = up_stack_frame(&tcb->cmn, sizeof(struct libvars_s)); - DEBUGASSERT(group->tg_libvars != NULL); + info = up_stack_frame(&tcb->cmn, sizeof(struct task_info_s)); + if (info == NULL) + { + ret = -ENOMEM; + goto errout_with_group; + } - /* Initialize the task-specific data */ - - memset(group->tg_libvars, 0, sizeof(struct libvars_s)); - - /* Save the allocated task data in TLS */ - - tls_set_taskdata(&tcb->cmn); -#endif + DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr); /* Initialize the task control block */ diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c index 9dd874df7a1..b31b73254fb 100644 --- a/sched/task/task_vfork.c +++ b/sched/task/task_vfork.c @@ -34,191 +34,16 @@ #include #include +#include #include "sched/sched.h" #include "group/group.h" #include "task/task.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /* vfork() requires architecture-specific support as well as waipid(). */ #if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) -/* This is an artificial limit to detect error conditions where an argv[] - * list is not properly terminated. - */ - -#define MAX_VFORK_ARGS 256 - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxvfork_setup_name - * - * Description: - * Copy the task name. - * - * Input Parameters: - * tcb - Address of the new task's TCB - * name - Name of the new task - * - * Returned Value: - * None - * - ****************************************************************************/ - -#if CONFIG_TASK_NAME_SIZE > 0 -static inline void nxvfork_setup_name(FAR struct tcb_s *parent, - FAR struct task_tcb_s *child) -{ - /* Copy the name from the parent into the child TCB */ - - strncpy(child->cmn.name, parent->name, CONFIG_TASK_NAME_SIZE); -} -#else -# define nxvfork_setup_name(p,c) -#endif /* CONFIG_TASK_NAME_SIZE */ - -/**************************************************************************** - * Name: nxvfork_setup_stackargs - * - * Description: - * Clone the task arguments in the same relative positions on the child's - * stack. - * - * Input Parameters: - * parent - Address of the parent task's TCB - * child - Address of the child task's TCB - * - * Returned Value: - * Zero (OK) on success; a negated errno on failure. - * - ****************************************************************************/ - -static inline int nxvfork_setup_stackargs(FAR struct tcb_s *parent, - FAR struct task_tcb_s *child) -{ - /* Is the parent a task? or a pthread? Only tasks (and kernel threads) - * have command line arguments. - */ - - child->argv = NULL; - if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) - { - FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent; - uintptr_t offset; - int argc; - - /* Get the address correction */ - - offset = (uintptr_t)child->cmn.adj_stack_ptr - - (uintptr_t)parent->adj_stack_ptr; - - /* Change the child argv[] to point into its stack (instead of its - * parent's stack). - */ - - child->argv = (FAR char **)((uintptr_t)ptcb->argv + offset); - - /* Copy the adjusted address for each argument */ - - argc = 0; - while (ptcb->argv[argc]) - { - uintptr_t newaddr = (uintptr_t)ptcb->argv[argc] + offset; - child->argv[argc] = (FAR char *)newaddr; - - /* Increment the number of args. Here is a sanity check to - * prevent running away with an unterminated argv[] list. - * MAX_VFORK_ARGS should be sufficiently large that this never - * happens in normal usage. - */ - - if (++argc > MAX_VFORK_ARGS) - { - return -E2BIG; - } - } - - /* Put a terminator entry at the end of the child argv[] array. */ - - child->argv[argc] = NULL; - } - - return OK; -} - -/**************************************************************************** - * Name: nxvfork_setup_arguments - * - * Description: - * Clone the argument list from the parent to the child. - * - * Input Parameters: - * parent - Address of the parent task's TCB - * child - Address of the child task's TCB - * - * Returned Value: - * Zero (OK) on success; a negated errno on failure. - * - ****************************************************************************/ - -static inline int nxvfork_setup_arguments(FAR struct tcb_s *parent, - FAR struct task_tcb_s *child) -{ - /* Clone the task name */ - - nxvfork_setup_name(parent, child); - - /* Adjust and copy the argv[] array. */ - - return nxvfork_setup_stackargs(parent, child); -} - -/**************************************************************************** - * Name: nxvfork_sizeof_arguments - * - * Description: - * Get the parent's argument size. - * - * Input Parameters: - * parent - Address of the parent task's TCB - * - * Return Value: - * The parent's argument size. - * - ****************************************************************************/ - -static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent) -{ - if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) - { - FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent; - size_t strtablen = 0; - int argc = 0; - - while (ptcb->argv[argc]) - { - /* Add the size of this argument (with NUL terminator) */ - - strtablen += strlen(ptcb->argv[argc++]) + 1; - } - - /* Return the size to hold argv[] array and the strings. */ - - return (argc + 1) * sizeof(FAR char *) + strtablen; - } - else - { - return 0; - } -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -246,10 +71,10 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent) * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) up_vfork() provides any additional operating context. up_vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) up_vfork() provides any additional operating context. up_vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) up_vfork() then calls nxtask_start_vfork() @@ -266,29 +91,48 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent) * ****************************************************************************/ -FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize) +FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr) { - FAR struct tcb_s *parent = this_task(); + FAR struct tcb_s *ptcb = this_task(); + FAR struct task_tcb_s *parent; FAR struct task_tcb_s *child; + FAR struct task_info_s *info; + FAR const char *name = NULL; + size_t stack_size; uint8_t ttype; int priority; int ret; - DEBUGASSERT(retaddr != NULL && argsize != NULL); + DEBUGASSERT(retaddr != NULL); /* Get the type of the fork'ed task (kernel or user) */ - if ((parent->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) + if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) { /* Fork'ed from a kernel thread */ ttype = TCB_FLAG_TTYPE_KERNEL; + parent = (FAR struct task_tcb_s *)ptcb; } else { /* Fork'ed from a user task or pthread */ ttype = TCB_FLAG_TTYPE_TASK; + if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) + { + parent = (FAR struct task_tcb_s *)ptcb; + } + else + { + parent = (FAR struct task_tcb_s *) + nxsched_get_tcb(ptcb->group->tg_pid); + if (parent == NULL) + { + ret = -ENOENT; + goto errout; + } + } } /* Allocate a TCB for the child task. */ @@ -297,13 +141,13 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize) if (!child) { serr("ERROR: Failed to allocate TCB\n"); - set_errno(ENOMEM); - return NULL; + ret = -ENOMEM; + goto errout; } /* Allocate a new task group with the same privileges as the parent */ - ret = group_allocate(child, parent->flags); + ret = group_allocate(child, ttype); if (ret < 0) { goto errout_with_tcb; @@ -317,33 +161,71 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize) goto errout_with_tcb; } - /* Get the priority of the parent task */ + /* Allocate the stack for the TCB */ -#ifdef CONFIG_PRIORITY_INHERITANCE - priority = parent->base_priority; /* "Normal," unboosted priority */ -#else - priority = parent->sched_priority; /* Current priority */ -#endif + stack_size = (uintptr_t)ptcb->stack_base_ptr - + (uintptr_t)ptcb->stack_alloc_ptr + ptcb->adj_stack_size; - /* Initialize the task control block. This calls up_initial_state() */ - - sinfo("Child priority=%d start=%p\n", priority, retaddr); - ret = nxtask_setup_scheduler(child, priority, retaddr, parent->entry.main, - ttype); + ret = up_create_stack(&child->cmn, stack_size, ttype); if (ret < OK) { goto errout_with_tcb; } - /* Return the argument size */ + /* Setup thread local storage */ - *argsize = nxvfork_sizeof_arguments(parent); + info = up_stack_frame(&child->cmn, sizeof(struct task_info_s)); + if (info == NULL) + { + ret = -ENOMEM; + goto errout_with_tcb; + } + + DEBUGASSERT(info == child->cmn.stack_alloc_ptr); + memcpy(info, parent->cmn.stack_alloc_ptr, sizeof(struct task_info_s)); + + /* Get the priority of the parent task */ + +#ifdef CONFIG_PRIORITY_INHERITANCE + priority = ptcb->base_priority; /* "Normal," unboosted priority */ +#else + priority = ptcb->sched_priority; /* Current priority */ +#endif + + /* Initialize the task control block. This calls up_initial_state() */ + + sinfo("Child priority=%d start=%p\n", priority, retaddr); + ret = nxtask_setup_scheduler(child, priority, retaddr, + ptcb->entry.main, ttype); + if (ret < OK) + { + goto errout_with_tcb; + } + + /* Setup to pass parameters to the new task */ + +#if CONFIG_TASK_NAME_SIZE > 0 + name = parent->cmn.name; +#endif + + nxtask_setup_arguments(child, name, parent->argv); + + /* Now we have enough in place that we can join the group */ + + ret = group_initialize(child); + if (ret < OK) + { + goto errout_with_list; + } sinfo("parent=%p, returning child=%p\n", parent, child); return child; +errout_with_list: + dq_rem((FAR dq_entry_t *)child, (FAR dq_queue_t *)&g_inactivetasks); errout_with_tcb: nxsched_release_tcb((FAR struct tcb_s *)child, ttype); +errout: set_errno(-ret); return NULL; } @@ -371,10 +253,10 @@ errout_with_tcb: * - Allocation of the child task's TCB. * - Initialization of file descriptors and streams * - Configuration of environment variables - * - Setup the input parameters for the task. - * - Initialization of the TCB (including call to up_initial_state() - * 4) vfork() provides any additional operating context. vfork must: * - Allocate and initialize the stack + * - Setup the input parameters for the task. + * - Initialization of the TCB (including call to up_initial_state()) + * 4) vfork() provides any additional operating context. vfork must: * - Initialize special values in any CPU registers that were not * already configured by up_initial_state() * 5) vfork() then calls nxtask_start_vfork() @@ -394,32 +276,13 @@ errout_with_tcb: pid_t nxtask_start_vfork(FAR struct task_tcb_s *child) { - FAR struct tcb_s *parent = this_task(); pid_t pid; - int rc; + int rc = 0; int ret; - sinfo("Starting Child TCB=%p, parent=%p\n", child, this_task()); + sinfo("Starting Child TCB=%p\n", child); DEBUGASSERT(child); - /* Duplicate the original argument list in the forked child TCB */ - - ret = nxvfork_setup_arguments(parent, child); - if (ret < 0) - { - nxtask_abort_vfork(child, -ret); - return ERROR; - } - - /* Now we have enough in place that we can join the group */ - - ret = group_initialize(child); - if (ret < 0) - { - nxtask_abort_vfork(child, -ret); - return ERROR; - } - /* Get the assigned pid before we start the task */ pid = (int)child->cmn.pid; @@ -453,17 +316,11 @@ pid_t nxtask_start_vfork(FAR struct task_tcb_s *child) * opportunity to run. */ - rc = 0; - -#ifdef CONFIG_DEBUG_FEATURES ret = waitpid(pid, &rc, 0); if (ret < 0) { serr("ERROR: waitpid failed: %d\n", get_errno()); } -#else - waitpid(pid, &rc, 0); -#endif sched_unlock(); return pid; @@ -489,7 +346,7 @@ void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode) /* Release the TCB */ nxsched_release_tcb((FAR struct tcb_s *)child, - child->cmn.flags & TCB_FLAG_TTYPE_MASK); + child->cmn.flags & TCB_FLAG_TTYPE_MASK); set_errno(errcode); }