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:
parent
8640d82ce0
commit
2335b69120
155 changed files with 1103 additions and 1739 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue