arch: Allocate the space from the beginning in up_stack_frame

arch: Allocate the space from the beginning in up_stack_frame

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

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao
2021-04-12 23:44:08 +08:00
committed by Masayuki Ishikawa
parent 8640d82ce0
commit 2335b69120
155 changed files with 1103 additions and 1739 deletions
+22 -7
View File
@@ -57,8 +57,8 @@ APIs Exported by Architecture-Specific Logic to NuttX
- ``adj_stack_size``: Stack size after adjustment for hardware, - ``adj_stack_size``: Stack size after adjustment for hardware,
processor, etc. This value is retained only for debug purposes. processor, etc. This value is retained only for debug purposes.
- ``stack_alloc_ptr``: Pointer to allocated stack - ``stack_alloc_ptr``: Pointer to allocated stack
- ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
initial value of the stack pointer. and Arguments has been removed from the stack allocation.
:param tcb: The TCB of new task. :param tcb: The TCB of new task.
:param stack_size: The requested stack size. At least this much :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, - ``adj_stack_size``: Stack size after adjustment for hardware,
processor, etc. This value is retained only for debug purposes. processor, etc. This value is retained only for debug purposes.
- ``stack_alloc_ptr``: Pointer to allocated stack - ``stack_alloc_ptr``: Pointer to allocated stack
- ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
initial value of the stack pointer. and Arguments has been removed from the stack allocation.
:param tcb: The TCB of new task. :param tcb: The TCB of new task.
:param stack_size: The allocated stack size. :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 - ``adj_stack_size``: Stack size after removal of the stack frame
from the stack. from the stack.
- ``adj_stack_ptr``: Adjusted initial stack pointer after the - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
frame has been removed from the stack. This will still be the and Arguments has been removed from the stack allocation.
initial value of the stack pointer when the task is started.
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 tcb: The TCB of new task.
:param frame_size: The size of the stack frame to allocate. :param frame_size: The size of the stack frame to allocate.
+5 -5
View File
@@ -171,7 +171,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */ /* Get the limits on the interrupt stack memory */
@@ -240,14 +240,14 @@ static void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#ifdef CONFIG_ARCH_USBDUMP #ifdef CONFIG_ARCH_USBDUMP
+3 -2
View File
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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 */ /* Save the task entry point */
+4 -4
View File
@@ -57,16 +57,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+7 -7
View File
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */ /* Get the limits on the interrupt stack memory */
@@ -266,14 +266,14 @@ static void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp < ustackbase && sp >= ustackbase - ustacksize) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase);
} }
else else
{ {
_alert("ERROR: Stack pointer is not within the allocated stack\n"); _alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase); up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#else #else
@@ -288,14 +288,14 @@ static void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#endif #endif
+3 -2
View File
@@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -74,7 +74,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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) */ /* Save the task entry point (stripping off the thumb bit) */
+4 -4
View File
@@ -57,16 +57,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+4 -4
View File
@@ -212,7 +212,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
_alert("Current sp: %08x\n", sp); _alert("Current sp: %08x\n", sp);
@@ -291,10 +291,10 @@ static void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp >= ustackbase - ustacksize && sp < ustackbase) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
_alert("User Stack\n", sp); _alert("User Stack\n", sp);
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
#ifdef CONFIG_ARCH_KERNEL_STACK #ifdef CONFIG_ARCH_KERNEL_STACK
@@ -312,7 +312,7 @@ static void up_dumpstate(void)
else else
{ {
_alert("ERROR: Stack pointer is not within the allocated stack\n"); _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 #ifdef CONFIG_ARCH_KERNEL_STACK
up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
#endif #endif
+4 -6
View File
@@ -94,8 +94,8 @@ static FAR const uint32_t *g_cpu_stackalloc[CONFIG_SMP_NCPUS] =
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is * - 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 #if CONFIG_SMP_NCPUS > 1
uintptr_t stack_alloc; uintptr_t stack_alloc;
uintptr_t top_of_stack;
DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL && DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL &&
stack_size <= SMP_STACK_SIZE); 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]; stack_alloc = (uintptr_t)g_cpu_stackalloc[cpu];
DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc)); DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc));
top_of_stack = stack_alloc + SMP_STACK_SIZE;
tcb->adj_stack_size = SMP_STACK_SIZE; tcb->adj_stack_size = SMP_STACK_SIZE;
tcb->stack_alloc_ptr = (FAR uint32_t *)stack_alloc; tcb->stack_alloc_ptr = (FAR void *)stack_alloc;
tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#endif #endif
return OK; return OK;
+3 -2
View File
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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 */ /* Save the task entry point */
+4 -4
View File
@@ -57,16 +57,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+8 -8
View File
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 7 #if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp < ustackbase && sp >= ustackbase - ustacksize) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
else else
{ {
_alert("ERROR: Stack pointer is not within the allocated stack\n"); _alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase); up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#else #else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#endif #endif
+3 -2
View File
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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 #ifdef CONFIG_ARMV7M_STACKCHECK
/* Set the stack limit value */ /* Set the stack limit value */
+4 -4
View File
@@ -59,16 +59,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+4 -4
View File
@@ -60,16 +60,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+4 -4
View File
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
_alert("Current sp: %08x\n", sp); _alert("Current sp: %08x\n", sp);
@@ -284,10 +284,10 @@ static void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp >= ustackbase - ustacksize && sp < ustackbase) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
_alert("User Stack\n", sp); _alert("User Stack\n", sp);
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
#ifdef CONFIG_ARCH_KERNEL_STACK #ifdef CONFIG_ARCH_KERNEL_STACK
@@ -305,7 +305,7 @@ static void up_dumpstate(void)
else else
{ {
_alert("ERROR: Stack pointer is not within the allocated stack\n"); _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 #ifdef CONFIG_ARCH_KERNEL_STACK
up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
#endif #endif
+3 -2
View File
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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 */ /* Save the task entry point */
+4 -4
View File
@@ -57,16 +57,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+8 -8
View File
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 7 #if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp < ustackbase && sp >= ustackbase - ustacksize) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
else else
{ {
_alert("ERROR: Stack pointer is not within the allocated stack\n"); _alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase); up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#else #else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within the allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#endif #endif
+3 -2
View File
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* 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 #ifdef CONFIG_ARMV8M_STACKCHECK
/* Set the stack limit value */ /* Set the stack limit value */
+4 -4
View File
@@ -59,16 +59,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_vfork() then calls nxtask_start_vfork()
+2 -4
View File
@@ -31,7 +31,6 @@
#include <debug.h> #include <debug.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/board.h> #include <nuttx/board.h>
#include "sched/sched.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) size_t up_check_tcbstack(FAR struct tcb_s *tcb)
{ {
return do_stackcheck((FAR void *)((uintptr_t)tcb->adj_stack_ptr - return do_stackcheck(tcb->stack_base_ptr, tcb->adj_stack_size);
tcb->adj_stack_size), tcb->adj_stack_size);
} }
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb) 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) size_t up_check_stack(void)
+13 -35
View File
@@ -58,12 +58,6 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~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 * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -80,8 +74,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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) int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{ {
size_t alloc_size; stack_size = STACK_ALIGN_UP(stack_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);
#ifdef CONFIG_TLS_ALIGNED #ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the /* The allocated stack size must not exceed the maximum possible for the
* TLS feature. * TLS feature.
*/ */
DEBUGASSERT(alloc_size <= TLS_MAXSTACK); DEBUGASSERT(stack_size <= TLS_MAXSTACK);
if (alloc_size > TLS_MAXSTACK) if (stack_size > TLS_MAXSTACK)
{ {
alloc_size = TLS_MAXSTACK; stack_size = TLS_MAXSTACK;
} }
#endif #endif
stack_size = alloc_size - tls_size;
/* Is there already a stack allocated of a different size? */ /* Is there already a stack allocated of a different size? */
if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_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) if (ttype == TCB_FLAG_TTYPE_KERNEL)
{ {
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kmm_memalign(TLS_STACK_ALIGN, alloc_size);
} }
else else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kumm_memalign(TLS_STACK_ALIGN, alloc_size);
} }
#else /* CONFIG_TLS_ALIGNED */ #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) if (ttype == TCB_FLAG_TTYPE_KERNEL)
{ {
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr =
(uint32_t *)kmm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size); kmm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
} }
else else
#endif #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 */ /* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr =
(uint32_t *)kumm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size); kumm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
} }
#endif /* CONFIG_TLS_ALIGNED */ #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. * 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 * CONFIG_STACK_ALIGNMENT, and the stack ptr is decremented before
* the first write, we can directly save our variables to struct * the first write, we can directly save our variables to struct
* tcb_s. * tcb_s.
*/ */
tcb->adj_stack_size = stack_size; tcb->adj_stack_size = stack_size;
tcb->adj_stack_ptr = (FAR void *)((uintptr_t)tcb->stack_alloc_ptr + tcb->stack_base_ptr = tcb->stack_alloc_ptr;
alloc_size);
/* Initialize the TLS data structure */
memset(tcb->stack_alloc_ptr, 0, tls_size);
#ifdef CONFIG_STACK_COLORATION #ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a /* 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. * water marks.
*/ */
arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr - arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
tcb->adj_stack_size), tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */ #endif /* CONFIG_STACK_COLORATION */
board_autoled_on(LED_STACKCREATED); board_autoled_on(LED_STACKCREATED);
+10 -10
View File
@@ -79,9 +79,8 @@
* *
* - adj_stack_size: Stack size after removal of the stack frame from * - adj_stack_size: Stack size after removal of the stack frame from
* the stack * the stack
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* been removed from the stack. This will still be the initial value * Arguments has been removed from the stack allocation.
* of the stack pointer when the task is started.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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 *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{ {
FAR void *ret;
/* Align the frame_size */ /* Align the frame_size */
frame_size = STACK_ALIGN_UP(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; return NULL;
} }
ret = tcb->stack_base_ptr;
memset(ret, 0, frame_size);
/* Save the adjusted stack values in the struct tcb_s */ /* 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; 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 */ /* And return the pointer to the allocated region */
return tcb->adj_stack_ptr; return ret;
} }
+6 -36
View File
@@ -53,12 +53,6 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~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 * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -77,8 +71,8 @@
* processor, etc. This value is retained only for debug * processor, etc. This value is retained only for debug
* purposes. * purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* initial value of the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - tcb: The TCB of new task
@@ -93,16 +87,12 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{ {
size_t tls_size;
#ifdef CONFIG_TLS_ALIGNED #ifdef CONFIG_TLS_ALIGNED
/* Make certain that the user provided stack is properly aligned */ /* Make certain that the user provided stack is properly aligned */
DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0); DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
#endif #endif
tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
/* Is there already a stack allocated? */ /* Is there already a stack allocated? */
if (tcb->stack_alloc_ptr) 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 */ /* Save the new stack allocation */
tcb->stack_alloc_ptr = stack; tcb->stack_alloc_ptr = stack;
tcb->stack_base_ptr = tcb->stack_alloc_ptr;
/* Align stack top */ tcb->adj_stack_size =
STACK_ALIGN_DOWN((uintptr_t)stack + stack_size) - (uintptr_t)stack;
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);
#ifdef CONFIG_STACK_COLORATION #ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a /* 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. * water marks.
*/ */
arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr - arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
tcb->adj_stack_size), tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */ #endif /* CONFIG_STACK_COLORATION */
return OK; return OK;
+22 -42
View File
@@ -67,16 +67,16 @@
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork(). * 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. * 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - 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 * - 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 * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 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 tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
size_t stacksize;
uint32_t newsp; uint32_t newsp;
uint32_t newfp; uint32_t newfp;
uint32_t newtop;
uint32_t stacktop;
uint32_t stackutil; uint32_t stackutil;
size_t argsize;
void *argv;
int ret;
sinfo("vfork context [%p]:\n", context); sinfo("vfork context [%p]:\n", context);
sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32 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. */ /* 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) if (!child)
{ {
serr("ERROR: nxtask_setup_vfork failed\n"); 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); 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 /* How much of the parent's stack was utilized? The ARM uses
* a push-down stack so that the current stack pointer should * a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The * be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two. * stack usage should be the difference between those two.
*/ */
DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); stacktop = (uint32_t)parent->stack_base_ptr +
stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; parent->adj_stack_size;
DEBUGASSERT(stacktop > context->sp);
stackutil = stacktop - context->sp;
sinfo("Parent: stacksize:%zu stackutil:%" PRId32 "\n", sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
stacksize, stackutil);
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * 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. * 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); memcpy((void *)newsp, (const void *)context->sp, stackutil);
/* Was there a frame pointer in place before? */ /* Was there a frame pointer in place before? */
if (context->fp <= (uint32_t)parent->adj_stack_ptr && if (context->fp >= context->sp && context->fp < stacktop)
context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
{ {
uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; uint32_t frameutil = stacktop - context->fp;
newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; newfp = newtop - frameutil;
} }
else else
{ {
newfp = context->fp; newfp = context->fp;
} }
sinfo("Parent: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
parent->adj_stack_ptr, context->sp, context->fp); stacktop, context->sp, context->fp);
sinfo("Child: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n", sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
child->cmn.adj_stack_ptr, newsp, newfp); newtop, newsp, newfp);
/* Update the stack pointer, frame pointer, and volatile registers. When /* Update the stack pointer, frame pointer, and volatile registers. When
* the child TCB was initialized, all of the values were set to zero. * the child TCB was initialized, all of the values were set to zero.
+2 -2
View File
@@ -67,8 +67,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is * - cpu: CPU index that indicates which CPU the IDLE task is
+2 -1
View File
@@ -179,7 +179,8 @@ int up_cpu_start(int cpu)
/* Copy initial stack and reset vector for APP_DSP */ /* 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); putreg32((uint32_t)appdsp_boot, VECTOR_RESETV);
spin_lock(&g_appdsp_boot); spin_lock(&g_appdsp_boot);
@@ -63,8 +63,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is * - cpu: CPU index that indicates which CPU the IDLE task is
+2 -1
View File
@@ -167,7 +167,8 @@ int up_cpu_start(int cpu)
putreg32(0x1, REMAP); /* remap enable */ putreg32(0x1, REMAP); /* remap enable */
backup[0] = getreg32(CPU1_VECTOR_ISTACK); backup[0] = getreg32(CPU1_VECTOR_ISTACK);
backup[1] = getreg32(CPU1_VECTOR_RESETV); 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); putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
spin_lock(&g_cpu_wait[0]); spin_lock(&g_cpu_wait[0]);
+2 -2
View File
@@ -67,8 +67,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is * - cpu: CPU index that indicates which CPU the IDLE task is
+2 -1
View File
@@ -222,7 +222,8 @@ int up_cpu_start(int cpu)
core1_boot_msg[0] = 0; core1_boot_msg[0] = 0;
core1_boot_msg[1] = 1; core1_boot_msg[1] = 1;
core1_boot_msg[2] = getreg32(ARMV6M_SYSCON_VECTAB); 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; core1_boot_msg[4] = (uint32_t)core1_boot;
do do
+2 -2
View File
@@ -97,8 +97,8 @@ void up_idle(void)
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is * - cpu: CPU index that indicates which CPU the IDLE task is
+2 -1
View File
@@ -204,7 +204,8 @@ int up_cpu_start(int cpu)
/* Copy initial vectors for CPU1 */ /* 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); putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
spin_lock(&g_cpu1_boot); spin_lock(&g_cpu1_boot);
+2 -2
View File
@@ -146,12 +146,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
size_t up_check_tcbstack(FAR struct tcb_s *tcb) 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) 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) size_t up_check_stack(void)
+7 -27
View File
@@ -64,8 +64,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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) 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 #ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the /* The allocated stack size must not exceed the maximum possible for the
* TLS feature. * 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) if (ttype == TCB_FLAG_TTYPE_KERNEL)
{ {
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
} }
else else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
} }
#else /* CONFIG_TLS_ALIGNED */ #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) 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 else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* 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 */ #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) if (tcb->stack_alloc_ptr)
{ {
size_t top_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a /* Yes.. If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high * recognizable value that we can use later to test for high
* water marks. * 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); memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
#endif #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 */ /* 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; 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) #if defined(ARCH_HAVE_LEDS)
board_autoled_on(LED_STACKCREATED); board_autoled_on(LED_STACKCREATED);
#endif #endif
+8 -8
View File
@@ -139,7 +139,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint16_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */ /* Get the limits on the interrupt stack memory */
@@ -196,14 +196,14 @@ void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp < ustackbase && sp >= ustackbase - ustacksize) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
else else
{ {
_alert("ERROR: Stack pointer is not within allocated stack\n"); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase); up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#else #else
_alert("sp: %04x\n", sp); _alert("sp: %04x\n", sp);
@@ -217,14 +217,14 @@ void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#endif #endif
} }
+7 -4
View File
@@ -55,6 +55,7 @@
void up_initial_state(struct tcb_s *tcb) void up_initial_state(struct tcb_s *tcb)
{ {
struct xcptcontext *xcp = &tcb->xcp; struct xcptcontext *xcp = &tcb->xcp;
uintptr_t sp;
/* Initialize the idle thread stack */ /* 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 - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; 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)); 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); sp = (uintptr_t)tcb->stack_base_ptr +
xcp->regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff); 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 */ /* Save the task entry point */
+10 -11
View File
@@ -77,9 +77,8 @@
* *
* - adj_stack_size: Stack size after removal of the stack frame from * - adj_stack_size: Stack size after removal of the stack frame from
* the stack * the stack
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* been removed from the stack. This will still be the initial value * Arguments has been removed from the stack allocation.
* of the stack pointer when the task is started.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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 *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{ {
FAR void *ret;
/* Align the frame_size */ /* Align the frame_size */
frame_size = STACK_ALIGN_UP(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; return NULL;
} }
ret = tcb->stack_base_ptr;
memset(ret, 0, frame_size);
/* Save the adjusted stack values in the struct tcb_s */ /* 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; 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);
/* And return the pointer to the allocated region */ /* And return the pointer to the allocated region */
return tcb->adj_stack_ptr; return ret;
} }
+3 -11
View File
@@ -54,8 +54,8 @@
* processor, etc. This value is retained only for debug * processor, etc. This value is retained only for debug
* purposes. * purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* initial value of the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - tcb: The TCB of new task
@@ -70,8 +70,6 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{ {
size_t top_of_stack;
#ifdef CONFIG_TLS_ALIGNED #ifdef CONFIG_TLS_ALIGNED
/* Make certain that the user provided stack is properly 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. * 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 */ /* 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; tcb->adj_stack_size = stack_size;
/* Initialize the TLS data structure */
memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
return OK; return OK;
} }
+10 -20
View File
@@ -64,8 +64,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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) 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 #ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the /* The allocated stack size must not exceed the maximum possible for the
* TLS feature. * 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) if (ttype == TCB_FLAG_TTYPE_KERNEL)
{ {
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
} }
else else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
} }
#else /* CONFIG_TLS_ALIGNED */ #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) 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 else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* 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 */ #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) if (tcb->stack_alloc_ptr)
{ {
size_t top_of_stack; uintptr_t top_of_stack;
size_t size_of_stack; size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a /* 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. * 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 /* The AVR32 stack must be aligned at word (4 byte) boundaries. If
* necessary top_of_stack must be rounded down to the next boundary * necessary top_of_stack must be rounded down to the next boundary
*/ */
top_of_stack &= ~3; 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 */ /* 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; 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); board_autoled_on(LED_STACKCREATED);
return OK; return OK;
} }
+8 -8
View File
@@ -109,7 +109,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */ /* Get the limits on the interrupt stack memory */
@@ -166,14 +166,14 @@ void up_dumpstate(void)
* stack memory. * stack memory.
*/ */
if (sp < ustackbase && sp >= ustackbase - ustacksize) if (sp >= ustackbase && sp < ustackbase + ustacksize)
{ {
up_stackdump(sp, ustackbase); up_stackdump(sp, ustackbase + ustacksize);
} }
else else
{ {
_alert("ERROR: Stack pointer is not within allocated stack\n"); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase - ustacksize, ustackbase); up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#else #else
_alert("sp: %08x\n", sp); _alert("sp: %08x\n", sp);
@@ -187,14 +187,14 @@ void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#endif #endif
} }
+3 -2
View File
@@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
{ {
tcb->stack_alloc_ptr = (void *)(g_idle_topstack - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; 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 */ /* 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 */ /* Save the task entry point */
+10 -10
View File
@@ -79,9 +79,8 @@
* *
* - adj_stack_size: Stack size after removal of the stack frame from * - adj_stack_size: Stack size after removal of the stack frame from
* the stack * the stack
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* been removed from the stack. This will still be the initial value * Arguments has been removed from the stack allocation.
* of the stack pointer when the task is started.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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 *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{ {
FAR void *ret;
/* Align the frame_size */ /* Align the frame_size */
frame_size = STACK_ALIGN_UP(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; return NULL;
} }
ret = tcb->stack_base_ptr;
memset(ret, 0, frame_size);
/* Save the adjusted stack values in the struct tcb_s */ /* 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; 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 */ /* And return the pointer to the allocated region */
return tcb->adj_stack_ptr; return ret;
} }
+6 -10
View File
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug * processor, etc. This value is retained only for debug
* purposes. * purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* initial value of the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - tcb: The TCB of new task
@@ -69,7 +69,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size) 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; size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED #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. * 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) /* The AVR32 stack must be aligned at word (4 byte)
* boundaries. If necessary top_of_stack must be rounded * 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; 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 */ /* 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; 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; return OK;
} }
+10 -20
View File
@@ -61,8 +61,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor, * - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes. * etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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) 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 #ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the /* The allocated stack size must not exceed the maximum possible for the
* TLS feature. * 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) if (ttype == TCB_FLAG_TTYPE_KERNEL)
{ {
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
} }
else else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
} }
#else /* CONFIG_TLS_ALIGNED */ #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) 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 else
#endif #endif
{ {
/* Use the user-space allocator if this is a task or pthread */ /* 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 */ #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) if (tcb->stack_alloc_ptr)
{ {
size_t top_of_stack; uintptr_t top_of_stack;
size_t size_of_stack; size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a /* 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. * 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) /* The CPU12 stack should be aligned at half-word (2 byte)
* boundaries. If necessary top_of_stack must be rounded * 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; 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 */ /* 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; 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); board_autoled_on(LED_STACKCREATED);
return OK; return OK;
} }
+10 -11
View File
@@ -79,9 +79,8 @@
* *
* - adj_stack_size: Stack size after removal of the stack frame from * - adj_stack_size: Stack size after removal of the stack frame from
* the stack * the stack
* - adj_stack_ptr: Adjusted initial stack pointer after the frame has * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* been removed from the stack. This will still be the initial value * Arguments has been removed from the stack allocation.
* of the stack pointer when the task is started.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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 *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{ {
FAR void *ret;
/* Align the frame_size */ /* Align the frame_size */
frame_size = STACK_ALIGN_UP(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; return NULL;
} }
ret = tcb->stack_base_ptr;
memset(ret, 0, frame_size);
/* Save the adjusted stack values in the struct tcb_s */ /* 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; 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;
/* And return the pointer to the allocated region */ /* And return the pointer to the allocated region */
return tcb->adj_stack_ptr; return ret;
} }
+7 -11
View File
@@ -52,8 +52,8 @@
* processor, etc. This value is retained only for debug * processor, etc. This value is retained only for debug
* purposes. * purposes.
* - stack_alloc_ptr: Pointer to allocated stack * - stack_alloc_ptr: Pointer to allocated stack
* - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
* initial value of the stack pointer. * Arguments has been removed from the stack allocation.
* *
* Input Parameters: * Input Parameters:
* - tcb: The TCB of new task * - 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; size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED #ifdef CONFIG_TLS_ALIGNED
@@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* stack address. * 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) /* The CPU12 stack should be aligned at half-word (2 byte)
* boundaries. If necessary top_of_stack must be rounded * 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; 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 */ /* 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; 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; return OK;
} }
+5 -5
View File
@@ -184,7 +184,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */ /* 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; ustacksize = (uint16_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */ /* Get the limits on the interrupt stack memory */
@@ -238,14 +238,14 @@ static void up_dumpstate(void)
* stack memory. * 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(sp, ustackbase + ustacksize);
up_stackdump(ustackbase - ustacksize, ustackbase);
} }
else else
{ {
up_stackdump(sp, ustackbase); _alert("ERROR: Stack pointer is not within allocated stack\n");
up_stackdump(ustackbase, ustackbase + ustacksize);
} }
#ifdef CONFIG_ARCH_USBDUMP #ifdef CONFIG_ARCH_USBDUMP
+6 -3
View File
@@ -52,6 +52,7 @@
void up_initial_state(struct tcb_s *tcb) void up_initial_state(struct tcb_s *tcb)
{ {
struct xcptcontext *xcp = &tcb->xcp; struct xcptcontext *xcp = &tcb->xcp;
uintptr_t sp;
/* Initialize the idle thread stack */ /* 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 - tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE); 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; tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
} }
@@ -69,8 +70,10 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */ /* Save the initial stack pointer */
xcp->regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8; sp = (uintptr_t)tcb->stack_base_ptr +
xcp->regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff; tcb->adj_stack_size;
xcp->regs[REG_SPH] = sp >> 8;
xcp->regs[REG_SPL] = sp & 0xff;
/* Save the task entry point */ /* Save the task entry point */

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