arch: Allocate the space from the beginning in up_stack_frame

arch: Allocate the space from the beginning in up_stack_frame

and modify the affected portion:
1.Correct the stack dump and check
2.Allocate tls_info_s by up_stack_frame too
3.Move the stack fork allocation from arch to sched

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2021-04-12 23:44:08 +08:00 committed by Masayuki Ishikawa
parent 8640d82ce0
commit 2335b69120
155 changed files with 1103 additions and 1739 deletions

View file

@ -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.

View file

@ -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

View file

@ -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 */

View file

@ -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()

View file

@ -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

View file

@ -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) */

View file

@ -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()

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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()

View file

@ -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

View file

@ -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 */

View file

@ -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()

View file

@ -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()

View file

@ -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

View file

@ -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 */

View file

@ -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()

View file

@ -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

View file

@ -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 */

View file

@ -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()

View file

@ -31,7 +31,6 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/board.h>
#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)

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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]);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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

View file

@ -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()

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -31,7 +31,6 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/board.h>
#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)

View file

@ -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 */

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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 */
}

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -31,7 +31,6 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/board.h>
#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)

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -46,7 +46,6 @@
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/board.h>
#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)

View file

@ -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;
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 */

Some files were not shown because too many files have changed in this diff Show more