You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2021/04/16 03:41:53 UTC
[incubator-nuttx] 02/02: arch: Allocate the space from the
beginning in up_stack_frame
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 2335b69120a3e36f1aa0cecc19c95208806cae54
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Mon Apr 12 23:44:08 2021 +0800
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 <xi...@xiaomi.com>
---
Documentation/reference/os/arch.rst | 29 +-
arch/arm/src/arm/arm_assert.c | 10 +-
arch/arm/src/arm/arm_initialstate.c | 5 +-
arch/arm/src/arm/vfork.S | 6 +-
arch/arm/src/armv6-m/arm_assert.c | 14 +-
arch/arm/src/armv6-m/arm_initialstate.c | 5 +-
arch/arm/src/armv6-m/vfork.S | 6 +-
arch/arm/src/armv7-a/arm_assert.c | 8 +-
arch/arm/src/armv7-a/arm_cpuidlestack.c | 10 +-
arch/arm/src/armv7-a/arm_initialstate.c | 5 +-
arch/arm/src/armv7-a/vfork.S | 6 +-
arch/arm/src/armv7-m/arm_assert.c | 16 +-
arch/arm/src/armv7-m/arm_initialstate.c | 5 +-
arch/arm/src/armv7-m/gnu/vfork.S | 6 +-
arch/arm/src/armv7-m/iar/vfork.S | 6 +-
arch/arm/src/armv7-r/arm_assert.c | 8 +-
arch/arm/src/armv7-r/arm_initialstate.c | 5 +-
arch/arm/src/armv7-r/vfork.S | 6 +-
arch/arm/src/armv8-m/arm_assert.c | 16 +-
arch/arm/src/armv8-m/arm_initialstate.c | 5 +-
arch/arm/src/armv8-m/vfork.S | 6 +-
arch/arm/src/common/arm_checkstack.c | 6 +-
arch/arm/src/common/arm_createstack.c | 48 +---
arch/arm/src/common/arm_stackframe.c | 20 +-
arch/arm/src/common/arm_usestack.c | 42 +--
arch/arm/src/common/arm_vfork.c | 62 ++---
arch/arm/src/cxd56xx/cxd56_cpuidlestack.c | 4 +-
arch/arm/src/cxd56xx/cxd56_cpustart.c | 3 +-
arch/arm/src/lc823450/lc823450_cpuidlestack.c | 4 +-
arch/arm/src/lc823450/lc823450_cpustart.c | 3 +-
arch/arm/src/rp2040/rp2040_cpuidlestack.c | 4 +-
arch/arm/src/rp2040/rp2040_cpustart.c | 3 +-
arch/arm/src/sam34/sam4cm_cpuidlestack.c | 4 +-
arch/arm/src/sam34/sam4cm_cpustart.c | 3 +-
arch/avr/src/avr/up_checkstack.c | 4 +-
arch/avr/src/avr/up_createstack.c | 34 +--
arch/avr/src/avr/up_dumpstate.c | 16 +-
arch/avr/src/avr/up_initialstate.c | 11 +-
arch/avr/src/avr/up_stackframe.c | 21 +-
arch/avr/src/avr/up_usestack.c | 14 +-
arch/avr/src/avr32/up_createstack.c | 30 +--
arch/avr/src/avr32/up_dumpstate.c | 16 +-
arch/avr/src/avr32/up_initialstate.c | 5 +-
arch/avr/src/avr32/up_stackframe.c | 20 +-
arch/avr/src/avr32/up_usestack.c | 16 +-
arch/hc/src/common/up_createstack.c | 30 +--
arch/hc/src/common/up_stackframe.c | 21 +-
arch/hc/src/common/up_usestack.c | 18 +-
arch/hc/src/m9s12/m9s12_assert.c | 10 +-
arch/hc/src/m9s12/m9s12_initialstate.c | 9 +-
arch/mips/src/common/mips_createstack.c | 30 +--
arch/mips/src/common/mips_stackframe.c | 20 +-
arch/mips/src/common/mips_usestack.c | 16 +-
arch/mips/src/mips32/mips_dumpstate.c | 10 +-
arch/mips/src/mips32/mips_initialstate.c | 5 +-
arch/mips/src/mips32/mips_vfork.c | 72 ++---
arch/mips/src/mips32/vfork.S | 6 +-
arch/misoc/src/lm32/lm32_createstack.c | 30 +--
arch/misoc/src/lm32/lm32_dumpstate.c | 10 +-
arch/misoc/src/lm32/lm32_initialstate.c | 5 +-
arch/misoc/src/lm32/lm32_stackframe.c | 20 +-
arch/misoc/src/lm32/lm32_usestack.c | 16 +-
arch/misoc/src/minerva/minerva_createstack.c | 30 +--
arch/misoc/src/minerva/minerva_dumpstate.c | 10 +-
arch/misoc/src/minerva/minerva_initialstate.c | 7 +-
arch/misoc/src/minerva/minerva_stackframe.c | 18 +-
arch/misoc/src/minerva/minerva_usestack.c | 16 +-
arch/or1k/src/common/up_assert.c | 16 +-
arch/or1k/src/common/up_checkstack.c | 34 +--
arch/or1k/src/common/up_createstack.c | 39 +--
arch/or1k/src/common/up_initialstate.c | 5 +-
arch/or1k/src/common/up_stackframe.c | 20 +-
arch/or1k/src/common/up_usestack.c | 16 +-
arch/renesas/src/common/up_createstack.c | 30 +--
arch/renesas/src/common/up_stackframe.c | 18 +-
arch/renesas/src/common/up_usestack.c | 16 +-
arch/renesas/src/m16c/m16c_dumpstate.c | 10 +-
arch/renesas/src/m16c/m16c_initialstate.c | 9 +-
arch/renesas/src/rx65n/rx65n_dumpstate.c | 10 +-
arch/renesas/src/rx65n/rx65n_initialstate.c | 5 +-
arch/renesas/src/sh1/sh1_dumpstate.c | 10 +-
arch/renesas/src/sh1/sh1_initialstate.c | 5 +-
arch/risc-v/src/common/riscv_checkstack.c | 30 +--
arch/risc-v/src/common/riscv_createstack.c | 35 +--
arch/risc-v/src/common/riscv_stackframe.c | 20 +-
arch/risc-v/src/common/riscv_usestack.c | 18 +-
arch/risc-v/src/k210/k210_cpuidlestack.c | 4 +-
arch/risc-v/src/rv32im/riscv_assert.c | 10 +-
arch/risc-v/src/rv32im/riscv_initialstate.c | 5 +-
arch/risc-v/src/rv32im/riscv_vfork.c | 72 ++---
arch/risc-v/src/rv64gc/riscv_assert.c | 8 +-
arch/risc-v/src/rv64gc/riscv_initialstate.c | 5 +-
arch/sim/src/sim/up_checkstack.c | 27 +-
arch/sim/src/sim/up_cpuidlestack.c | 6 +-
arch/sim/src/sim/up_createstack.c | 39 +--
arch/sim/src/sim/up_initialstate.c | 5 +-
arch/sim/src/sim/up_releasestack.c | 2 +-
arch/sim/src/sim/up_stackframe.c | 18 +-
arch/sim/src/sim/up_usestack.c | 23 +-
arch/sim/src/sim/up_vfork.c | 69 ++---
arch/sim/src/sim/up_vfork32.S | 6 +-
arch/sim/src/sim/up_vfork64.S | 6 +-
arch/sim/src/sim/up_vfork_arm.S | 6 +-
arch/x86/src/common/up_assert.c | 10 +-
arch/x86/src/i486/up_createstack.c | 30 +--
arch/x86/src/i486/up_initialstate.c | 5 +-
arch/x86/src/i486/up_stackframe.c | 20 +-
arch/x86/src/i486/up_usestack.c | 16 +-
arch/x86_64/src/common/up_assert.c | 11 +-
arch/x86_64/src/intel64/up_createstack.c | 30 +--
arch/x86_64/src/intel64/up_initialstate.c | 16 +-
arch/x86_64/src/intel64/up_stackframe.c | 20 +-
arch/x86_64/src/intel64/up_usestack.c | 16 +-
arch/xtensa/src/common/xtensa_checkstack.c | 10 +-
arch/xtensa/src/common/xtensa_createstack.c | 30 +--
arch/xtensa/src/common/xtensa_dumpstate.c | 10 +-
arch/xtensa/src/common/xtensa_initialstate.c | 10 +-
arch/xtensa/src/common/xtensa_stackframe.c | 20 +-
arch/xtensa/src/common/xtensa_usestack.c | 20 +-
arch/xtensa/src/esp32/esp32_cpuidlestack.c | 10 +-
arch/xtensa/src/esp32/esp32_cpustart.c | 2 +-
arch/z16/src/common/z16_createstack.c | 30 +--
arch/z16/src/common/z16_initialstate.c | 3 +-
arch/z16/src/common/z16_stackdump.c | 12 +-
arch/z16/src/common/z16_stackframe.c | 20 +-
arch/z16/src/common/z16_usestack.c | 18 +-
arch/z80/src/common/z80_createstack.c | 30 +--
arch/z80/src/common/z80_stackdump.c | 12 +-
arch/z80/src/common/z80_stackframe.c | 18 +-
arch/z80/src/common/z80_usestack.c | 16 +-
arch/z80/src/ez80/ez80_initialstate.c | 7 +-
arch/z80/src/z180/z180_initialstate.c | 6 +-
arch/z80/src/z8/z8_initialstate.c | 3 +-
arch/z80/src/z80/z80_initialstate.c | 6 +-
boards/arm/cxd56xx/common/src/cxd56_crashdump.c | 3 +-
boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c | 5 +-
boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c | 5 +-
.../renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c | 5 +-
.../renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c | 5 +-
fs/procfs/fs_procfsproc.c | 2 +-
include/nuttx/arch.h | 33 ++-
include/nuttx/lib/libvars.h | 76 ------
include/nuttx/sched.h | 25 +-
include/nuttx/tls.h | 48 +++-
libs/libc/pthread/pthread_get_stackaddr_np.c | 2 +-
libs/libc/tls/Make.defs | 2 +
.../libc/tls/task_getinfo.c | 44 ++-
libs/libc/tls/tls.h | 34 ---
libs/libc/unistd/lib_getoptvars.c | 13 +-
sched/group/Make.defs | 4 -
sched/group/group.h | 6 -
sched/pthread/pthread_create.c | 18 +-
sched/sched/sched_get_stackinfo.c | 15 +-
sched/task/task_init.c | 31 +--
sched/task/task_vfork.c | 299 ++++++---------------
155 files changed, 1074 insertions(+), 1710 deletions(-)
diff --git a/Documentation/reference/os/arch.rst b/Documentation/reference/os/arch.rst
index 3b94233..eccfbae 100644
--- a/Documentation/reference/os/arch.rst
+++ b/Documentation/reference/os/arch.rst
@@ -57,8 +57,8 @@ APIs Exported by Architecture-Specific Logic to NuttX
- ``adj_stack_size``: Stack size after adjustment for hardware,
processor, etc. This value is retained only for debug purposes.
- ``stack_alloc_ptr``: Pointer to allocated stack
- - ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The
- initial value of the stack pointer.
+ - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+ and Arguments has been removed from the stack allocation.
:param tcb: The TCB of new task.
:param stack_size: The requested stack size. At least this much
@@ -93,8 +93,8 @@ APIs Exported by Architecture-Specific Logic to NuttX
- ``adj_stack_size``: Stack size after adjustment for hardware,
processor, etc. This value is retained only for debug purposes.
- ``stack_alloc_ptr``: Pointer to allocated stack
- - ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The
- initial value of the stack pointer.
+ - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+ and Arguments has been removed from the stack allocation.
:param tcb: The TCB of new task.
:param stack_size: The allocated stack size.
@@ -120,9 +120,24 @@ APIs Exported by Architecture-Specific Logic to NuttX
- ``adj_stack_size``: Stack size after removal of the stack frame
from the stack.
- - ``adj_stack_ptr``: Adjusted initial stack pointer after the
- frame has been removed from the stack. This will still be the
- initial value of the stack pointer when the task is started.
+ - ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+ and Arguments has been removed from the stack allocation.
+
+ Here is the diagram after some allocation(tls, arg):
+
+ +-------------+ <-stack_alloc_ptr(lowest)
+ | TLS Data |
+ +-------------+
+ | Arguments |
+ stack_base_ptr-> +-------------+\
+ | Available | +
+ | Stack | |
+ | | | |
+ | | | +->adj_stack_size
+ v | | |
+ | | |
+ | | +
+ +-------------+/
:param tcb: The TCB of new task.
:param frame_size: The size of the stack frame to allocate.
diff --git a/arch/arm/src/arm/arm_assert.c b/arch/arm/src/arm/arm_assert.c
index 8988035..bc1345d 100644
--- a/arch/arm/src/arm/arm_assert.c
+++ b/arch/arm/src/arm/arm_assert.c
@@ -171,7 +171,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -240,14 +240,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/arm/src/arm/arm_initialstate.c b/arch/arm/src/arm/arm_initialstate.c
index d247838..d15d0b6 100644
--- a/arch/arm/src/arm/arm_initialstate.c
+++ b/arch/arm/src/arm/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/arm/src/arm/vfork.S b/arch/arm/src/arm/vfork.S
index 6de4f5f..4abdf51 100644
--- a/arch/arm/src/arm/vfork.S
+++ b/arch/arm/src/arm/vfork.S
@@ -57,16 +57,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv6-m/arm_assert.c b/arch/arm/src/armv6-m/arm_assert.c
index 8c617a8..8db89a6 100644
--- a/arch/arm/src/armv6-m/arm_assert.c
+++ b/arch/arm/src/armv6-m/arm_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -266,14 +266,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
up_stackdump(sp, ustackbase);
}
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
@@ -288,14 +288,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c
index c38a4fb..5df0fa0 100644
--- a/arch/arm/src/armv6-m/arm_initialstate.c
+++ b/arch/arm/src/armv6-m/arm_initialstate.c
@@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -74,7 +74,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point (stripping off the thumb bit) */
diff --git a/arch/arm/src/armv6-m/vfork.S b/arch/arm/src/armv6-m/vfork.S
index 90e2b1f..624134d 100644
--- a/arch/arm/src/armv6-m/vfork.S
+++ b/arch/arm/src/armv6-m/vfork.S
@@ -57,16 +57,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c
index b74c224..273e691 100644
--- a/arch/arm/src/armv7-a/arm_assert.c
+++ b/arch/arm/src/armv7-a/arm_assert.c
@@ -212,7 +212,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
_alert("Current sp: %08x\n", sp);
@@ -291,10 +291,10 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase - ustacksize && sp < ustackbase)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
_alert("User Stack\n", sp);
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
#ifdef CONFIG_ARCH_KERNEL_STACK
@@ -312,7 +312,7 @@ static void up_dumpstate(void)
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
#ifdef CONFIG_ARCH_KERNEL_STACK
up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
#endif
diff --git a/arch/arm/src/armv7-a/arm_cpuidlestack.c b/arch/arm/src/armv7-a/arm_cpuidlestack.c
index 0dd2885..2e9a118 100644
--- a/arch/arm/src/armv7-a/arm_cpuidlestack.c
+++ b/arch/arm/src/armv7-a/arm_cpuidlestack.c
@@ -94,8 +94,8 @@ static FAR const uint32_t *g_cpu_stackalloc[CONFIG_SMP_NCPUS] =
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
@@ -111,7 +111,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
{
#if CONFIG_SMP_NCPUS > 1
uintptr_t stack_alloc;
- uintptr_t top_of_stack;
DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL &&
stack_size <= SMP_STACK_SIZE);
@@ -120,11 +119,10 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
stack_alloc = (uintptr_t)g_cpu_stackalloc[cpu];
DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc));
- top_of_stack = stack_alloc + SMP_STACK_SIZE;
tcb->adj_stack_size = SMP_STACK_SIZE;
- tcb->stack_alloc_ptr = (FAR uint32_t *)stack_alloc;
- tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
+ tcb->stack_alloc_ptr = (FAR void *)stack_alloc;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#endif
return OK;
diff --git a/arch/arm/src/armv7-a/arm_initialstate.c b/arch/arm/src/armv7-a/arm_initialstate.c
index 5ce1d28..521649b 100644
--- a/arch/arm/src/armv7-a/arm_initialstate.c
+++ b/arch/arm/src/armv7-a/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/arm/src/armv7-a/vfork.S b/arch/arm/src/armv7-a/vfork.S
index 1fed24d..9524c07 100644
--- a/arch/arm/src/armv7-a/vfork.S
+++ b/arch/arm/src/armv7-a/vfork.S
@@ -57,16 +57,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-m/arm_assert.c b/arch/arm/src/armv7-m/arm_assert.c
index 01cfe7a..f2b7659 100644
--- a/arch/arm/src/armv7-m/arm_assert.c
+++ b/arch/arm/src/armv7-m/arm_assert.c
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within the allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c
index 6420de8..90872ad 100644
--- a/arch/arm/src/armv7-m/arm_initialstate.c
+++ b/arch/arm/src/armv7-m/arm_initialstate.c
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
#ifdef CONFIG_ARMV7M_STACKCHECK
/* Set the stack limit value */
diff --git a/arch/arm/src/armv7-m/gnu/vfork.S b/arch/arm/src/armv7-m/gnu/vfork.S
index b6b6188..b5b6dd2 100644
--- a/arch/arm/src/armv7-m/gnu/vfork.S
+++ b/arch/arm/src/armv7-m/gnu/vfork.S
@@ -59,16 +59,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-m/iar/vfork.S b/arch/arm/src/armv7-m/iar/vfork.S
index 91810cb..305e747 100644
--- a/arch/arm/src/armv7-m/iar/vfork.S
+++ b/arch/arm/src/armv7-m/iar/vfork.S
@@ -60,16 +60,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c
index 70cb80f..17ed679 100644
--- a/arch/arm/src/armv7-r/arm_assert.c
+++ b/arch/arm/src/armv7-r/arm_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
_alert("Current sp: %08x\n", sp);
@@ -284,10 +284,10 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase - ustacksize && sp < ustackbase)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
_alert("User Stack\n", sp);
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
#ifdef CONFIG_ARCH_KERNEL_STACK
@@ -305,7 +305,7 @@ static void up_dumpstate(void)
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
#ifdef CONFIG_ARCH_KERNEL_STACK
up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
#endif
diff --git a/arch/arm/src/armv7-r/arm_initialstate.c b/arch/arm/src/armv7-r/arm_initialstate.c
index 79be124..3656bb6 100644
--- a/arch/arm/src/armv7-r/arm_initialstate.c
+++ b/arch/arm/src/armv7-r/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/arm/src/armv7-r/vfork.S b/arch/arm/src/armv7-r/vfork.S
index 3d6d56c..670fdb3 100644
--- a/arch/arm/src/armv7-r/vfork.S
+++ b/arch/arm/src/armv7-r/vfork.S
@@ -57,16 +57,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv8-m/arm_assert.c b/arch/arm/src/armv8-m/arm_assert.c
index 71b78f8..ebdf521 100644
--- a/arch/arm/src/armv8-m/arm_assert.c
+++ b/arch/arm/src/armv8-m/arm_assert.c
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within the allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c
index a34c853..b2bbf88 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
#ifdef CONFIG_ARMV8M_STACKCHECK
/* Set the stack limit value */
diff --git a/arch/arm/src/armv8-m/vfork.S b/arch/arm/src/armv8-m/vfork.S
index 9d04830..7f68b3b 100644
--- a/arch/arm/src/armv8-m/vfork.S
+++ b/arch/arm/src/armv8-m/vfork.S
@@ -59,16 +59,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c
index 7d8524d..5f9f414 100644
--- a/arch/arm/src/common/arm_checkstack.c
+++ b/arch/arm/src/common/arm_checkstack.c
@@ -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)
diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c
index dda4b1f..b14ba88 100644
--- a/arch/arm/src/common/arm_createstack.c
+++ b/arch/arm/src/common/arm_createstack.c
@@ -58,12 +58,6 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
-/* 32bit alignment macros */
-
-#define INT32_ALIGN_MASK (3)
-#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
-#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -80,8 +74,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -108,28 +102,20 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- size_t alloc_size;
- size_t tls_size;
-
- /* Add the size of the TLS information structure and align. */
-
- tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
- alloc_size = STACK_ALIGN_UP(stack_size + tls_size);
+ stack_size = STACK_ALIGN_UP(stack_size);
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
*/
- DEBUGASSERT(alloc_size <= TLS_MAXSTACK);
- if (alloc_size > TLS_MAXSTACK)
+ DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+ if (stack_size > TLS_MAXSTACK)
{
- alloc_size = TLS_MAXSTACK;
+ stack_size = TLS_MAXSTACK;
}
#endif
- stack_size = alloc_size - tls_size;
-
/* Is there already a stack allocated of a different size? */
if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
@@ -154,16 +140,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, alloc_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, alloc_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -173,7 +157,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size);
+ kmm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
}
else
#endif
@@ -181,7 +165,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size);
+ kumm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -206,19 +190,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* Items on the stack are referenced as positive word offsets from sp.
*/
- /* Since both stack_alloc_ptr and alloc_size are in
+ /* Since both stack_alloc_ptr and stack_size are in
* CONFIG_STACK_ALIGNMENT, and the stack ptr is decremented before
* the first write, we can directly save our variables to struct
* tcb_s.
*/
tcb->adj_stack_size = stack_size;
- tcb->adj_stack_ptr = (FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
- alloc_size);
-
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, tls_size);
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
@@ -226,8 +205,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* water marks.
*/
- arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
- tcb->adj_stack_size), tcb->adj_stack_size);
+ arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
board_autoled_on(LED_STACKCREATED);
diff --git a/arch/arm/src/common/arm_stackframe.c b/arch/arm/src/common/arm_stackframe.c
index 5fa6c36..bf9bb92 100644
--- a/arch/arm/src/common/arm_stackframe.c
+++ b/arch/arm/src/common/arm_stackframe.c
@@ -79,9 +79,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -96,6 +95,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c
index e8f5269..dcef734 100644
--- a/arch/arm/src/common/arm_usestack.c
+++ b/arch/arm/src/common/arm_usestack.c
@@ -53,12 +53,6 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
-/* 32bit alignment macros */
-
-#define INT32_ALIGN_MASK (3)
-#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
-#define INT32_ALIGN_UP(a) (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -77,8 +71,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -93,16 +87,12 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t tls_size;
-
#ifdef CONFIG_TLS_ALIGNED
/* Make certain that the user provided stack is properly aligned */
DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
#endif
- tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
-
/* Is there already a stack allocated? */
if (tcb->stack_alloc_ptr)
@@ -127,28 +117,9 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
/* Save the new stack allocation */
tcb->stack_alloc_ptr = stack;
-
- /* Align stack top */
-
- tcb->adj_stack_ptr =
- (FAR void *)STACK_ALIGN_DOWN((uintptr_t)stack + stack_size);
-
- /* Offset by tls_size */
-
- stack = (FAR void *)((uintptr_t)stack + tls_size);
-
- /* Is there enough room for at least TLS ? */
-
- if ((uintptr_t)stack > (uintptr_t)tcb->adj_stack_ptr)
- {
- return -ENOMEM;
- }
-
- tcb->adj_stack_size = (uintptr_t)tcb->adj_stack_ptr - (uintptr_t)stack;
-
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, tls_size);
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
+ tcb->adj_stack_size =
+ STACK_ALIGN_DOWN((uintptr_t)stack + stack_size) - (uintptr_t)stack;
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
@@ -156,8 +127,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* water marks.
*/
- arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
- tcb->adj_stack_size), tcb->adj_stack_size);
+ arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
return OK;
diff --git a/arch/arm/src/common/arm_vfork.c b/arch/arm/src/common/arm_vfork.c
index 35bd20a..feb4302 100644
--- a/arch/arm/src/common/arm_vfork.c
+++ b/arch/arm/src/common/arm_vfork.c
@@ -67,16 +67,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
@@ -100,13 +100,11 @@ pid_t up_vfork(const struct vfork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
- size_t stacksize;
uint32_t newsp;
uint32_t newfp;
+ uint32_t newtop;
+ uint32_t stacktop;
uint32_t stackutil;
- size_t argsize;
- void *argv;
- int ret;
sinfo("vfork context [%p]:\n", context);
sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32
@@ -119,7 +117,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */
- child = nxtask_setup_vfork((start_t)(context->lr & ~1), &argsize);
+ child = nxtask_setup_vfork((start_t)(context->lr & ~1));
if (!child)
{
serr("ERROR: nxtask_setup_vfork failed\n");
@@ -128,37 +126,18 @@ pid_t up_vfork(const struct vfork_s *context)
sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
- /* Get the size of the parent task's stack. */
-
- stacksize = parent->adj_stack_size;
-
- /* Allocate the stack for the TCB */
-
- ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
- parent->flags & TCB_FLAG_TTYPE_MASK);
- if (ret != OK)
- {
- serr("ERROR: up_create_stack failed: %d\n", ret);
- nxtask_abort_vfork(child, -ret);
- return (pid_t)ERROR;
- }
-
- /* Allocate the memory and copy argument from parent task */
-
- argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
- memcpy(argv, parent->adj_stack_ptr, argsize);
-
/* How much of the parent's stack was utilized? The ARM uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
- DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
- stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+ stacktop = (uint32_t)parent->stack_base_ptr +
+ parent->adj_stack_size;
+ DEBUGASSERT(stacktop > context->sp);
+ stackutil = stacktop - context->sp;
- sinfo("Parent: stacksize:%zu stackutil:%" PRId32 "\n",
- stacksize, stackutil);
+ sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
/* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
@@ -167,26 +146,27 @@ pid_t up_vfork(const struct vfork_s *context)
* effort is overkill.
*/
- newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+ newtop = (uint32_t)child->cmn.stack_base_ptr +
+ child->cmn.adj_stack_size;
+ newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);
/* Was there a frame pointer in place before? */
- if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
- context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+ if (context->fp >= context->sp && context->fp < stacktop)
{
- uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
- newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+ uint32_t frameutil = stacktop - context->fp;
+ newfp = newtop - frameutil;
}
else
{
newfp = context->fp;
}
- sinfo("Parent: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
- parent->adj_stack_ptr, context->sp, context->fp);
- sinfo("Child: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
- child->cmn.adj_stack_ptr, newsp, newfp);
+ sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+ stacktop, context->sp, context->fp);
+ sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+ newtop, newsp, newfp);
/* Update the stack pointer, frame pointer, and volatile registers. When
* the child TCB was initialized, all of the values were set to zero.
diff --git a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
index 4f3f49f..0bf1f6a 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
@@ -67,8 +67,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/cxd56xx/cxd56_cpustart.c b/arch/arm/src/cxd56xx/cxd56_cpustart.c
index a948d9a..266a7ed 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpustart.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpustart.c
@@ -179,7 +179,8 @@ int up_cpu_start(int cpu)
/* Copy initial stack and reset vector for APP_DSP */
- putreg32((uint32_t)tcb->adj_stack_ptr, VECTOR_ISTACK);
+ putreg32((uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size, VECTOR_ISTACK);
putreg32((uint32_t)appdsp_boot, VECTOR_RESETV);
spin_lock(&g_appdsp_boot);
diff --git a/arch/arm/src/lc823450/lc823450_cpuidlestack.c b/arch/arm/src/lc823450/lc823450_cpuidlestack.c
index bcf4830..a163c9d 100644
--- a/arch/arm/src/lc823450/lc823450_cpuidlestack.c
+++ b/arch/arm/src/lc823450/lc823450_cpuidlestack.c
@@ -63,8 +63,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/lc823450/lc823450_cpustart.c b/arch/arm/src/lc823450/lc823450_cpustart.c
index 16fcd2b..043ceae 100644
--- a/arch/arm/src/lc823450/lc823450_cpustart.c
+++ b/arch/arm/src/lc823450/lc823450_cpustart.c
@@ -167,7 +167,8 @@ int up_cpu_start(int cpu)
putreg32(0x1, REMAP); /* remap enable */
backup[0] = getreg32(CPU1_VECTOR_ISTACK);
backup[1] = getreg32(CPU1_VECTOR_RESETV);
- putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK);
+ putreg32((uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size, CPU1_VECTOR_ISTACK);
putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
spin_lock(&g_cpu_wait[0]);
diff --git a/arch/arm/src/rp2040/rp2040_cpuidlestack.c b/arch/arm/src/rp2040/rp2040_cpuidlestack.c
index e675a2f..eacab6a 100644
--- a/arch/arm/src/rp2040/rp2040_cpuidlestack.c
+++ b/arch/arm/src/rp2040/rp2040_cpuidlestack.c
@@ -67,8 +67,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/rp2040/rp2040_cpustart.c b/arch/arm/src/rp2040/rp2040_cpustart.c
index 05e1fdd..08c16c2 100644
--- a/arch/arm/src/rp2040/rp2040_cpustart.c
+++ b/arch/arm/src/rp2040/rp2040_cpustart.c
@@ -222,7 +222,8 @@ int up_cpu_start(int cpu)
core1_boot_msg[0] = 0;
core1_boot_msg[1] = 1;
core1_boot_msg[2] = getreg32(ARMV6M_SYSCON_VECTAB);
- core1_boot_msg[3] = (uint32_t)tcb->adj_stack_ptr;
+ core1_boot_msg[3] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
core1_boot_msg[4] = (uint32_t)core1_boot;
do
diff --git a/arch/arm/src/sam34/sam4cm_cpuidlestack.c b/arch/arm/src/sam34/sam4cm_cpuidlestack.c
index 815dd40..98a1b4a 100644
--- a/arch/arm/src/sam34/sam4cm_cpuidlestack.c
+++ b/arch/arm/src/sam34/sam4cm_cpuidlestack.c
@@ -97,8 +97,8 @@ void up_idle(void)
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/sam34/sam4cm_cpustart.c b/arch/arm/src/sam34/sam4cm_cpustart.c
index 5df6802..a653dfc 100644
--- a/arch/arm/src/sam34/sam4cm_cpustart.c
+++ b/arch/arm/src/sam34/sam4cm_cpustart.c
@@ -204,7 +204,8 @@ int up_cpu_start(int cpu)
/* Copy initial vectors for CPU1 */
- putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK);
+ putreg32((uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size, CPU1_VECTOR_ISTACK);
putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
spin_lock(&g_cpu1_boot);
diff --git a/arch/avr/src/avr/up_checkstack.c b/arch/avr/src/avr/up_checkstack.c
index 5175782..5003c8a 100644
--- a/arch/avr/src/avr/up_checkstack.c
+++ b/arch/avr/src/avr/up_checkstack.c
@@ -146,12 +146,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
size_t up_check_tcbstack(FAR struct tcb_s *tcb)
{
- return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size);
+ return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
}
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
{
- return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+ return tcb->adj_stack_size - up_check_tcbstack(tcb);
}
size_t up_check_stack(void)
diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c
index a6c606c..8ac95e7 100644
--- a/arch/avr/src/avr/up_createstack.c
+++ b/arch/avr/src/avr/up_createstack.c
@@ -64,8 +64,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -86,10 +86,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -129,16 +125,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -147,14 +141,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -172,8 +166,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
-
/* Yes.. If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
@@ -183,23 +175,11 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
#endif
- /* The AVR uses a push-down stack: the stack grows toward lower
- * addresses in memory. The stack pointer register, points to the
- * lowest, valid work address (the "top" of the stack). Items on the
- * stack are referenced as positive word offsets from sp.
- */
-
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
-
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = stack_size;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#if defined(ARCH_HAVE_LEDS)
board_autoled_on(LED_STACKCREATED);
#endif
diff --git a/arch/avr/src/avr/up_dumpstate.c b/arch/avr/src/avr/up_dumpstate.c
index b84a95f..dcf0030 100644
--- a/arch/avr/src/avr/up_dumpstate.c
+++ b/arch/avr/src/avr/up_dumpstate.c
@@ -139,7 +139,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint16_t)rtcb->stack_base_ptr;
ustacksize = (uint16_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -196,14 +196,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
_alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
_alert("sp: %04x\n", sp);
@@ -217,14 +217,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
}
diff --git a/arch/avr/src/avr/up_initialstate.c b/arch/avr/src/avr/up_initialstate.c
index fb8a2a8..5135dc7 100644
--- a/arch/avr/src/avr/up_initialstate.c
+++ b/arch/avr/src/avr/up_initialstate.c
@@ -55,6 +55,7 @@
void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
+ uintptr_t sp;
/* Initialize the idle thread stack */
@@ -62,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -72,10 +73,12 @@ void up_initial_state(struct tcb_s *tcb)
memset(xcp, 0, sizeof(struct xcptcontext));
- /* Set the initial stack pointer to the "base" of the allocated stack */
+ /* Set the initial stack pointer to the top of the allocated stack */
- xcp->regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8);
- xcp->regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff);
+ sp = (uintptr_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
+ xcp->regs[REG_SPH] = (uint8_t)(sp >> 8);
+ xcp->regs[REG_SPL] = (uint8_t)(sp & 0xff);
/* Save the task entry point */
diff --git a/arch/avr/src/avr/up_stackframe.c b/arch/avr/src/avr/up_stackframe.c
index 860350e..687f105 100644
--- a/arch/avr/src/avr/up_stackframe.c
+++ b/arch/avr/src/avr/up_stackframe.c
@@ -77,9 +77,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -94,6 +93,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -105,17 +106,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Set the initial stack pointer to the "base" of the allocated stack */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8);
- tcb->xcp.regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff);
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c
index bdde37c..8e796e9 100644
--- a/arch/avr/src/avr/up_usestack.c
+++ b/arch/avr/src/avr/up_usestack.c
@@ -54,8 +54,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -70,8 +70,6 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
-
#ifdef CONFIG_TLS_ALIGNED
/* Make certain that the user provided stack is properly aligned */
@@ -105,16 +103,10 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* positive word offsets from sp.
*/
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
-
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = stack_size;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c
index 6ef611e..daa48d6 100644
--- a/arch/avr/src/avr32/up_createstack.c
+++ b/arch/avr/src/avr32/up_createstack.c
@@ -64,8 +64,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -91,10 +91,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -134,16 +130,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -152,14 +146,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -177,7 +171,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -195,24 +189,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The AVR32 stack must be aligned at word (4 byte) boundaries. If
* necessary top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/avr/src/avr32/up_dumpstate.c b/arch/avr/src/avr32/up_dumpstate.c
index 98f2960..04b800a 100644
--- a/arch/avr/src/avr32/up_dumpstate.c
+++ b/arch/avr/src/avr32/up_dumpstate.c
@@ -109,7 +109,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -166,14 +166,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
_alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
_alert("sp: %08x\n", sp);
@@ -187,14 +187,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
}
diff --git a/arch/avr/src/avr32/up_initialstate.c b/arch/avr/src/avr32/up_initialstate.c
index ee33df6..eea5c8c 100644
--- a/arch/avr/src/avr32/up_initialstate.c
+++ b/arch/avr/src/avr32/up_initialstate.c
@@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -85,7 +85,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Set the initial stack pointer to the top of the allocated stack */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/avr/src/avr32/up_stackframe.c b/arch/avr/src/avr32/up_stackframe.c
index 67ea2cd..b01ea52 100644
--- a/arch/avr/src/avr32/up_stackframe.c
+++ b/arch/avr/src/avr32/up_stackframe.c
@@ -79,9 +79,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -96,6 +95,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c
index ef3b1d4..c253226 100644
--- a/arch/avr/src/avr32/up_usestack.c
+++ b/arch/avr/src/avr32/up_usestack.c
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -69,7 +69,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -106,7 +106,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* referenced as positive word offsets from sp.
*/
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The AVR32 stack must be aligned at word (4 byte)
* boundaries. If necessary top_of_stack must be rounded
@@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c
index d0f89b9..3fe163f 100644
--- a/arch/hc/src/common/up_createstack.c
+++ b/arch/hc/src/common/up_createstack.c
@@ -61,8 +61,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,10 +88,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* stack address.
*/
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The CPU12 stack should be aligned at half-word (2 byte)
* boundaries. If necessary top_of_stack must be rounded
@@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack &= ~1;
- size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->alloc_stack_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/hc/src/common/up_stackframe.c b/arch/hc/src/common/up_stackframe.c
index d8fd239..b57de5c 100644
--- a/arch/hc/src/common/up_stackframe.c
+++ b/arch/hc/src/common/up_stackframe.c
@@ -79,9 +79,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -96,6 +95,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,17 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8;
- tcb->xcp.regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c
index 87523e9..d7173b8 100644
--- a/arch/hc/src/common/up_usestack.c
+++ b/arch/hc/src/common/up_usestack.c
@@ -52,8 +52,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -66,9 +66,9 @@
*
****************************************************************************/
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* stack address.
*/
- top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The CPU12 stack should be aligned at half-word (2 byte)
* boundaries. If necessary top_of_stack must be rounded
@@ -113,16 +113,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
*/
top_of_stack &= ~1;
- size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c
index 8e778f6..c14faa8 100644
--- a/arch/hc/src/m9s12/m9s12_assert.c
+++ b/arch/hc/src/m9s12/m9s12_assert.c
@@ -184,7 +184,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint16_t)rtcb->stack_base_ptr;
ustacksize = (uint16_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -238,14 +238,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/hc/src/m9s12/m9s12_initialstate.c b/arch/hc/src/m9s12/m9s12_initialstate.c
index 25f8313..7cb6d69 100644
--- a/arch/hc/src/m9s12/m9s12_initialstate.c
+++ b/arch/hc/src/m9s12/m9s12_initialstate.c
@@ -52,6 +52,7 @@
void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
+ uintptr_t sp;
/* Initialize the idle thread stack */
@@ -59,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -69,8 +70,10 @@ void up_initial_state(struct tcb_s *tcb)
/* Save the initial stack pointer */
- xcp->regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8;
- xcp->regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff;
+ sp = (uintptr_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
+ xcp->regs[REG_SPH] = sp >> 8;
+ xcp->regs[REG_SPL] = sp & 0xff;
/* Save the task entry point */
diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c
index f3c9ea5..b906a0d 100644
--- a/arch/mips/src/common/mips_createstack.c
+++ b/arch/mips/src/common/mips_createstack.c
@@ -82,8 +82,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -109,10 +109,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -151,16 +147,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -169,14 +163,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -212,7 +206,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The MIPS stack must be aligned at word (4 byte) boundaries; for
* floating point use, the stack must be aligned to 8-byte addresses.
@@ -228,17 +222,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* The size need not be aligned.
*/
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/mips/src/common/mips_stackframe.c b/arch/mips/src/common/mips_stackframe.c
index df6287a..3fdfcc4 100644
--- a/arch/mips/src/common/mips_stackframe.c
+++ b/arch/mips/src/common/mips_stackframe.c
@@ -82,9 +82,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -99,6 +98,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -110,16 +111,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c
index 531e7c5..e6e4e60 100644
--- a/arch/mips/src/common/mips_usestack.c
+++ b/arch/mips/src/common/mips_usestack.c
@@ -73,8 +73,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -89,7 +89,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -125,7 +125,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The MIPS stack must be aligned at word (4 byte) or double word (8 byte)
* boundaries. If necessary top_of_stack must be rounded down to the
@@ -140,16 +140,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* The size need not be aligned.
*/
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/mips/src/mips32/mips_dumpstate.c b/arch/mips/src/mips32/mips_dumpstate.c
index 0268698..b850e85 100644
--- a/arch/mips/src/mips32/mips_dumpstate.c
+++ b/arch/mips/src/mips32/mips_dumpstate.c
@@ -139,7 +139,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -193,14 +193,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/mips/src/mips32/mips_initialstate.c b/arch/mips/src/mips32/mips_initialstate.c
index 65fc6c2..0a3d0c2 100644
--- a/arch/mips/src/mips32/mips_initialstate.c
+++ b/arch/mips/src/mips32/mips_initialstate.c
@@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -78,7 +78,8 @@ void up_initial_state(struct tcb_s *tcb)
* only the start function would do that and we have control over that one.
*/
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/mips/src/mips32/mips_vfork.c b/arch/mips/src/mips32/mips_vfork.c
index 536b78d..65aa693 100644
--- a/arch/mips/src/mips32/mips_vfork.c
+++ b/arch/mips/src/mips32/mips_vfork.c
@@ -69,16 +69,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* this consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
@@ -102,15 +102,13 @@ pid_t up_vfork(const struct vfork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
- size_t stacksize;
uint32_t newsp;
#ifdef CONFIG_MIPS32_FRAMEPOINTER
uint32_t newfp;
#endif
+ uint32_t newtop;
+ uint32_t stacktop;
uint32_t stackutil;
- size_t argsize;
- void *argv;
- int ret;
sinfo("s0:%08" PRIx32 " s1:%08" PRIx32 " s2:%08" PRIx32
" s3:%08" PRIx32 " s4:%08" PRIx32 "\n",
@@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */
- child = nxtask_setup_vfork((start_t)context->ra, &argsize);
+ child = nxtask_setup_vfork((start_t)context->ra);
if (!child)
{
sinfo("nxtask_setup_vfork failed\n");
@@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context)
sinfo("Parent=%p Child=%p\n", parent, child);
- /* Get the size of the parent task's stack. Due to alignment operations,
- * the adjusted stack size may be smaller than the stack size originally
- * requested.
- */
-
- stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
-
- /* Allocate the stack for the TCB */
-
- ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
- parent->flags & TCB_FLAG_TTYPE_MASK);
- if (ret != OK)
- {
- serr("ERROR: up_create_stack failed: %d\n", ret);
- nxtask_abort_vfork(child, -ret);
- return (pid_t)ERROR;
- }
-
- /* Allocate the memory and copy argument from parent task */
-
- argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
- memcpy(argv, parent->adj_stack_ptr, argsize);
-
/* How much of the parent's stack was utilized? The MIPS uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
- DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
- stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+ stacktop = (uint32_t)parent->stack_base_ptr +
+ parent->adj_stack_size;
+ DEBUGASSERT(stacktop > context->sp);
+ stackutil = stacktop - context->sp;
- sinfo("stacksize:%zd stackutil:%" PRId32 "\n", stacksize, stackutil);
+ sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
/* Make some feeble effort to perserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
@@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context)
* effort is overkill.
*/
- newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+ newtop = (uintptr_t)child->cmn.stack_base_ptr +
+ child->cmn.adj_stack_size;
+ newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);
/* Was there a frame pointer in place before? */
#ifdef CONFIG_MIPS32_FRAMEPOINTER
- if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
- context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+ if (context->fp >= context->sp && context->fp < stacktop)
{
- uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
- newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+ uint32_t frameutil = stacktop - context->fp;
+ newfp = newtop - frameutil;
}
else
{
newfp = context->fp;
}
- sinfo("Old stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
- parent->adj_stack_ptr, context->sp, context->fp);
- sinfo("New stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
- child->cmn.adj_stack_ptr, newsp, newfp);
+ sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+ stacktop, context->sp, context->fp);
+ sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+ newtop, newsp, newfp);
#else
- sinfo("Old stack base:%p SP:%08" PRIx32 "\n",
- parent->adj_stack_ptr, context->sp);
- sinfo("New stack base:%p SP:%08" PRIx32 "\n",
- child->cmn.adj_stack_ptr, newsp);
+ sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 "\n",
+ stacktop, context->sp);
+ sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 "\n",
+ newtop, newsp);
#endif
/* Update the stack pointer, frame pointer, global pointer and saved
diff --git a/arch/mips/src/mips32/vfork.S b/arch/mips/src/mips32/vfork.S
index aa7f96c..4dfa94a 100644
--- a/arch/mips/src/mips32/vfork.S
+++ b/arch/mips/src/mips32/vfork.S
@@ -56,16 +56,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c
index 8e354ab..e00f5ab 100644
--- a/arch/misoc/src/lm32/lm32_createstack.c
+++ b/arch/misoc/src/lm32/lm32_createstack.c
@@ -97,8 +97,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -124,10 +124,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -166,16 +162,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -184,14 +178,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -209,7 +203,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -227,7 +221,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The LM32 stack must be aligned at word (4 byte) boundaries; for
* floating point use, the stack must be aligned to 8-byte addresses.
@@ -236,17 +230,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c
index fa44403..6dded3d 100644
--- a/arch/misoc/src/lm32/lm32_dumpstate.c
+++ b/arch/misoc/src/lm32/lm32_dumpstate.c
@@ -141,7 +141,7 @@ void lm32_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -195,14 +195,14 @@ void lm32_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c
index 45024e6..525cd7a 100644
--- a/arch/misoc/src/lm32/lm32_initialstate.c
+++ b/arch/misoc/src/lm32/lm32_initialstate.c
@@ -77,7 +77,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -91,7 +91,8 @@ void up_initial_state(struct tcb_s *tcb)
* only the start function would do that and we have control over that one
*/
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/misoc/src/lm32/lm32_stackframe.c b/arch/misoc/src/lm32/lm32_stackframe.c
index c436f5a..624c6fe 100644
--- a/arch/misoc/src/lm32/lm32_stackframe.c
+++ b/arch/misoc/src/lm32/lm32_stackframe.c
@@ -90,9 +90,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -107,6 +106,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/misoc/src/lm32/lm32_usestack.c b/arch/misoc/src/lm32/lm32_usestack.c
index 13aa6af..c55a100 100644
--- a/arch/misoc/src/lm32/lm32_usestack.c
+++ b/arch/misoc/src/lm32/lm32_usestack.c
@@ -51,8 +51,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -67,7 +67,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
* top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c
index a46539a..186e564 100644
--- a/arch/misoc/src/minerva/minerva_createstack.c
+++ b/arch/misoc/src/minerva/minerva_createstack.c
@@ -89,8 +89,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -116,10 +116,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -159,16 +155,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -177,14 +171,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -202,7 +196,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -220,7 +214,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The MINERVA stack must be aligned at word (4 byte) boundaries; for
* floating point use, the stack must be aligned to 8-byte addresses.
@@ -229,17 +223,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR uint32_t *) top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/misoc/src/minerva/minerva_dumpstate.c b/arch/misoc/src/minerva/minerva_dumpstate.c
index c3de5f9..4e5331c 100644
--- a/arch/misoc/src/minerva/minerva_dumpstate.c
+++ b/arch/misoc/src/minerva/minerva_dumpstate.c
@@ -148,7 +148,7 @@ void minerva_dumpstate(void)
* == NULL)
*/
- ustackbase = (uint32_t) rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t) rtcb->stack_base_ptr;
ustacksize = (uint32_t) rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -200,14 +200,14 @@ void minerva_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/misoc/src/minerva/minerva_initialstate.c b/arch/misoc/src/minerva/minerva_initialstate.c
index 7bcd29b..21953eb 100644
--- a/arch/misoc/src/minerva/minerva_initialstate.c
+++ b/arch/misoc/src/minerva/minerva_initialstate.c
@@ -81,7 +81,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -95,11 +95,12 @@ void up_initial_state(struct tcb_s *tcb)
* only the start function would do that and we have control over that one.
*/
- xcp->regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
- xcp->regs[REG_CSR_MEPC] = (uint32_t) tcb->start;
+ xcp->regs[REG_CSR_MEPC] = (uint32_t)tcb->start;
xcp->regs[REG_CSR_MSTATUS] = CSR_MSTATUS_MPIE;
diff --git a/arch/misoc/src/minerva/minerva_stackframe.c b/arch/misoc/src/minerva/minerva_stackframe.c
index ba8b5cb..3dc536e 100644
--- a/arch/misoc/src/minerva/minerva_stackframe.c
+++ b/arch/misoc/src/minerva/minerva_stackframe.c
@@ -90,9 +90,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -107,6 +106,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
+
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
tcb->adj_stack_size -= frame_size;
- /* Reset the initial stack pointer */
-
- tcb->xcp.regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr;
-
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/misoc/src/minerva/minerva_usestack.c b/arch/misoc/src/minerva/minerva_usestack.c
index fbb2de1..3d1c6d7 100644
--- a/arch/misoc/src/minerva/minerva_usestack.c
+++ b/arch/misoc/src/minerva/minerva_usestack.c
@@ -51,8 +51,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -67,7 +67,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
* top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/or1k/src/common/up_assert.c b/arch/or1k/src/common/up_assert.c
index 6df9c2c..fe9ff7a 100644
--- a/arch/or1k/src/common/up_assert.c
+++ b/arch/or1k/src/common/up_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -266,14 +266,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp < ustackbase && sp >= ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
_alert("ERROR: Stack pointer is not within the allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#else
@@ -288,14 +288,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#endif
diff --git a/arch/or1k/src/common/up_checkstack.c b/arch/or1k/src/common/up_checkstack.c
index c9fb7ec..2562ae5 100644
--- a/arch/or1k/src/common/up_checkstack.c
+++ b/arch/or1k/src/common/up_checkstack.c
@@ -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)
diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c
index 2202947..9a440ce 100644
--- a/arch/or1k/src/common/up_createstack.c
+++ b/arch/or1k/src/common/up_createstack.c
@@ -74,8 +74,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -102,10 +102,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -145,16 +141,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -163,14 +157,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -188,36 +182,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
-#if defined(CONFIG_STACK_COLORATION)
- uintptr_t stack_base;
-#endif
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
- stack_base = (uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s);
- stack_size = tcb->adj_stack_size -
- sizeof(struct tls_info_s);
- up_stack_color((FAR void *)stack_base, stack_size);
+ up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
diff --git a/arch/or1k/src/common/up_initialstate.c b/arch/or1k/src/common/up_initialstate.c
index a884c78..28c9827 100644
--- a/arch/or1k/src/common/up_initialstate.c
+++ b/arch/or1k/src/common/up_initialstate.c
@@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -87,7 +87,8 @@ void up_initial_state(struct tcb_s *tcb)
memset(xcp, 0, sizeof(struct xcptcontext));
- xcp->regs[REG_R1] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_R1] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[REG_PC] = (uint32_t)tcb->start;
mfspr(SPR_SYS_SR, sr);
diff --git a/arch/or1k/src/common/up_stackframe.c b/arch/or1k/src/common/up_stackframe.c
index 98903ec..c6e8485 100644
--- a/arch/or1k/src/common/up_stackframe.c
+++ b/arch/or1k/src/common/up_stackframe.c
@@ -71,9 +71,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,6 +87,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_R1] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/or1k/src/common/up_usestack.c b/arch/or1k/src/common/up_usestack.c
index 1ccdaf2..9866c4c 100644
--- a/arch/or1k/src/common/up_usestack.c
+++ b/arch/or1k/src/common/up_usestack.c
@@ -51,8 +51,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -67,7 +67,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
* top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c
index dbdfb3d..c504371 100644
--- a/arch/renesas/src/common/up_createstack.c
+++ b/arch/renesas/src/common/up_createstack.c
@@ -61,8 +61,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,10 +88,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The SH stack must be aligned at word (4 byte)
* boundaries. If necessary top_of_stack must be rounded
@@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/renesas/src/common/up_stackframe.c b/arch/renesas/src/common/up_stackframe.c
index 7ad96a7..ebc7ead 100644
--- a/arch/renesas/src/common/up_stackframe.c
+++ b/arch/renesas/src/common/up_stackframe.c
@@ -78,9 +78,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -95,6 +94,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -106,16 +107,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
+
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
tcb->adj_stack_size -= frame_size;
- /* Reset the initial state */
-
- up_initial_state(tcb);
-
/* And return a pointer to allocated memory */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c
index bd7a120..b447b3e 100644
--- a/arch/renesas/src/common/up_usestack.c
+++ b/arch/renesas/src/common/up_usestack.c
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -69,7 +69,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The SH stack must be aligned at word (4 byte) boundaries. If necessary
* top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c
index 52dbcf1..a5c8ff5 100644
--- a/arch/renesas/src/m16c/m16c_dumpstate.c
+++ b/arch/renesas/src/m16c/m16c_dumpstate.c
@@ -136,7 +136,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint16_t)rtcb->stack_base_ptr;
ustacksize = (uint16_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory.
@@ -197,14 +197,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- m16c_stackdump(ustackbase - ustacksize, ustackbase);
+ m16c_stackdump(sp, ustackbase + ustacksize);
}
else
{
- m16c_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ m16c_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/renesas/src/m16c/m16c_initialstate.c b/arch/renesas/src/m16c/m16c_initialstate.c
index 9a5f9e5..5c88e0f 100644
--- a/arch/renesas/src/m16c/m16c_initialstate.c
+++ b/arch/renesas/src/m16c/m16c_initialstate.c
@@ -54,6 +54,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
{
FAR struct xcptcontext *xcp = &tcb->xcp;
FAR uint8_t *regs = xcp->regs;
+ uintptr_t sp;
/* Initialize the idle thread stack */
@@ -61,7 +62,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -90,7 +91,9 @@ void up_initial_state(FAR struct tcb_s *tcb)
/* Offset 18-20: User stack pointer */
+ sp = (uintptr_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
regs = &xcp->regs[REG_SP];
- *regs++ = (uint32_t)tcb->adj_stack_ptr >> 8; /* Bits 8-15 of SP */
- *regs = (uint32_t)tcb->adj_stack_ptr; /* Bits 0-7 of SP */
+ *regs++ = sp >> 8; /* Bits 8-15 of SP */
+ *regs = sp; /* Bits 0-7 of SP */
}
diff --git a/arch/renesas/src/rx65n/rx65n_dumpstate.c b/arch/renesas/src/rx65n/rx65n_dumpstate.c
index 0fa573b..ebf9905 100644
--- a/arch/renesas/src/rx65n/rx65n_dumpstate.c
+++ b/arch/renesas/src/rx65n/rx65n_dumpstate.c
@@ -143,7 +143,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint16_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
@@ -194,14 +194,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- rx65n_stackdump(ustackbase - ustacksize, ustackbase);
+ rx65n_stackdump(sp, ustackbase + ustacksize);
}
else
{
- rx65n_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ rx65n_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/renesas/src/rx65n/rx65n_initialstate.c b/arch/renesas/src/rx65n/rx65n_initialstate.c
index e371367..c6808b1 100644
--- a/arch/renesas/src/rx65n/rx65n_initialstate.c
+++ b/arch/renesas/src/rx65n/rx65n_initialstate.c
@@ -67,7 +67,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
memset(xcp, 0, sizeof(struct xcptcontext));
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[REG_PC] = (uint32_t)tcb->start;
/* Enable or disable interrupts, based on user configuration */
diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c
index 5988d25..215100f 100644
--- a/arch/renesas/src/sh1/sh1_dumpstate.c
+++ b/arch/renesas/src/sh1/sh1_dumpstate.c
@@ -123,7 +123,7 @@ void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -177,14 +177,14 @@ void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- sh1_stackdump(ustackbase - ustacksize, ustackbase);
+ sh1_stackdump(sp, ustackbase + ustacksize);
}
else
{
- sh1_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ sh1_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/renesas/src/sh1/sh1_initialstate.c b/arch/renesas/src/sh1/sh1_initialstate.c
index e097f6d..d52e09a 100644
--- a/arch/renesas/src/sh1/sh1_initialstate.c
+++ b/arch/renesas/src/sh1/sh1_initialstate.c
@@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -89,7 +89,8 @@ void up_initial_state(struct tcb_s *tcb)
/* Set the initial stack pointer to the "top" of the allocated stack */
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/risc-v/src/common/riscv_checkstack.c b/arch/risc-v/src/common/riscv_checkstack.c
index eec04ae..ca35375 100644
--- a/arch/risc-v/src/common/riscv_checkstack.c
+++ b/arch/risc-v/src/common/riscv_checkstack.c
@@ -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)
diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c
index 4754520..2086b85 100644
--- a/arch/risc-v/src/common/riscv_createstack.c
+++ b/arch/risc-v/src/common/riscv_createstack.c
@@ -83,8 +83,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -110,10 +110,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -153,16 +149,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -171,14 +165,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -196,10 +190,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
-#if defined(CONFIG_STACK_COLORATION)
- uintptr_t stack_base;
-#endif
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* RISCV uses a push-down stack: the stack grows toward lower
@@ -221,24 +212,16 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
- stack_base = (uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s);
- stack_size = tcb->adj_stack_size -
- sizeof(struct tls_info_s);
- riscv_stack_color((FAR void *)stack_base, stack_size);
+ riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
diff --git a/arch/risc-v/src/common/riscv_stackframe.c b/arch/risc-v/src/common/riscv_stackframe.c
index 193adcb..5b4b7f3 100644
--- a/arch/risc-v/src/common/riscv_stackframe.c
+++ b/arch/risc-v/src/common/riscv_stackframe.c
@@ -83,9 +83,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -100,6 +99,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -111,16 +112,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/risc-v/src/common/riscv_usestack.c b/arch/risc-v/src/common/riscv_usestack.c
index 7cdb9fb..d6debd5 100644
--- a/arch/risc-v/src/common/riscv_usestack.c
+++ b/arch/risc-v/src/common/riscv_usestack.c
@@ -74,8 +74,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,9 +88,9 @@
*
****************************************************************************/
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -130,22 +130,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uintptr_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#if defined(CONFIG_STACK_COLORATION)
/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
- riscv_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s)),
- size_of_stack - sizeof(struct tls_info_s));
+ riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif
return OK;
diff --git a/arch/risc-v/src/k210/k210_cpuidlestack.c b/arch/risc-v/src/k210/k210_cpuidlestack.c
index 9872182..1c59e18 100644
--- a/arch/risc-v/src/k210/k210_cpuidlestack.c
+++ b/arch/risc-v/src/k210/k210_cpuidlestack.c
@@ -67,8 +67,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/arch/risc-v/src/rv32im/riscv_assert.c b/arch/risc-v/src/rv32im/riscv_assert.c
index 5b55b6d..a541082 100644
--- a/arch/risc-v/src/rv32im/riscv_assert.c
+++ b/arch/risc-v/src/rv32im/riscv_assert.c
@@ -184,7 +184,7 @@ static void riscv_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -238,14 +238,14 @@ static void riscv_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- riscv_stackdump(ustackbase - ustacksize, ustackbase);
+ riscv_stackdump(sp, ustackbase + ustacksize);
}
else
{
- riscv_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ riscv_stackdump(ustackbase, ustackbase + ustacksize);
}
}
diff --git a/arch/risc-v/src/rv32im/riscv_initialstate.c b/arch/risc-v/src/rv32im/riscv_initialstate.c
index 6338b30..4106125 100644
--- a/arch/risc-v/src/rv32im/riscv_initialstate.c
+++ b/arch/risc-v/src/rv32im/riscv_initialstate.c
@@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb)
* only the start function would do that and we have control over that one
*/
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/risc-v/src/rv32im/riscv_vfork.c b/arch/risc-v/src/rv32im/riscv_vfork.c
index 3ed4b8d..bb390fa 100644
--- a/arch/risc-v/src/rv32im/riscv_vfork.c
+++ b/arch/risc-v/src/rv32im/riscv_vfork.c
@@ -68,16 +68,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
@@ -105,15 +105,13 @@ pid_t up_vfork(const struct vfork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
- size_t stacksize;
uint32_t newsp;
#ifdef CONFIG_RISCV_FRAMEPOINTER
uint32_t newfp;
#endif
+ uint32_t newtop;
+ uint32_t stacktop;
uint32_t stackutil;
- size_t argsize;
- void *argv;
- int ret;
sinfo("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n",
context->s0, context->s1, context->s2, context->s3, context->s4);
@@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */
- child = nxtask_setup_vfork((start_t)context->ra, &argsize);
+ child = nxtask_setup_vfork((start_t)context->ra);
if (!child)
{
sinfo("nxtask_setup_vfork failed\n");
@@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context)
sinfo("Parent=%p Child=%p\n", parent, child);
- /* Get the size of the parent task's stack. Due to alignment operations,
- * the adjusted stack size may be smaller than the stack size originally
- * requested.
- */
-
- stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
-
- /* Allocate the stack for the TCB */
-
- ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
- parent->flags & TCB_FLAG_TTYPE_MASK);
- if (ret != OK)
- {
- serr("ERROR: up_create_stack failed: %d\n", ret);
- nxtask_abort_vfork(child, -ret);
- return (pid_t)ERROR;
- }
-
- /* Allocate the memory and copy argument from parent task */
-
- argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
- memcpy(argv, parent->adj_stack_ptr, argsize);
-
/* How much of the parent's stack was utilized? The RISC-V uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
- DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
- stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+ stacktop = (uint32_t)parent->stack_base_ptr +
+ parent->adj_stack_size;
+ DEBUGASSERT(stacktop > context->sp);
+ stackutil = stacktop - context->sp;
- sinfo("stacksize:%d stackutil:%d\n", stacksize, stackutil);
+ sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
/* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
@@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context)
* effort is overkill.
*/
- newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+ newtop = (uint32_t)child->cmn.stack_base_ptr +
+ child->cmn.adj_stack_size;
+ newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);
/* Was there a frame pointer in place before? */
#ifdef CONFIG_RISCV_FRAMEPOINTER
- if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
- context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+ if (context->fp >= context->sp && context->fp < stacktop)
{
- uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
- newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+ uint32_t frameutil = stacktop - context->fp;
+ newfp = newtop - frameutil;
}
else
{
newfp = context->fp;
}
- sinfo("Old stack base:%08x SP:%08x FP:%08x\n",
- parent->adj_stack_ptr, context->sp, context->fp);
- sinfo("New stack base:%08x SP:%08x FP:%08x\n",
- child->cmn.adj_stack_ptr, newsp, newfp);
+ sinfo("Old stack top:%08x SP:%08x FP:%08x\n",
+ stacktop, context->sp, context->fp);
+ sinfo("New stack top:%08x SP:%08x FP:%08x\n",
+ newtop, newsp, newfp);
#else
- sinfo("Old stack base:%08x SP:%08x\n",
- parent->adj_stack_ptr, context->sp);
- sinfo("New stack base:%08x SP:%08x\n",
- child->cmn.adj_stack_ptr, newsp);
+ sinfo("Old stack top:%08x SP:%08x\n",
+ stacktop, context->sp);
+ sinfo("New stack top:%08x SP:%08x\n",
+ newtop, newsp);
#endif
/* Update the stack pointer, frame pointer, global pointer and saved
diff --git a/arch/risc-v/src/rv64gc/riscv_assert.c b/arch/risc-v/src/rv64gc/riscv_assert.c
index 1ba121b..d7a9b80 100644
--- a/arch/risc-v/src/rv64gc/riscv_assert.c
+++ b/arch/risc-v/src/rv64gc/riscv_assert.c
@@ -195,7 +195,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uintptr_t)rtcb->adj_stack_ptr;
+ ustackbase = (uintptr_t)rtcb->stack_base_ptr;
ustacksize = (uintptr_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -247,14 +247,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
_alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
}
diff --git a/arch/risc-v/src/rv64gc/riscv_initialstate.c b/arch/risc-v/src/rv64gc/riscv_initialstate.c
index afd13f6..d20b187 100644
--- a/arch/risc-v/src/rv64gc/riscv_initialstate.c
+++ b/arch/risc-v/src/rv64gc/riscv_initialstate.c
@@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb)
* only the start function would do that and we have control over that one
*/
- xcp->regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uintptr_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/sim/src/sim/up_checkstack.c b/arch/sim/src/sim/up_checkstack.c
index 8d276e9..1cd6165 100644
--- a/arch/sim/src/sim/up_checkstack.c
+++ b/arch/sim/src/sim/up_checkstack.c
@@ -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)
diff --git a/arch/sim/src/sim/up_cpuidlestack.c b/arch/sim/src/sim/up_cpuidlestack.c
index e878f2c..ce9e7c1 100644
--- a/arch/sim/src/sim/up_cpuidlestack.c
+++ b/arch/sim/src/sim/up_cpuidlestack.c
@@ -63,8 +63,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
@@ -82,6 +82,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
tcb->adj_stack_size = 0;
tcb->stack_alloc_ptr = NULL;
- tcb->adj_stack_ptr = NULL;
+ tcb->stack_base_ptr = NULL;
return OK;
}
diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c
index 20b6d2a..dcfd0d2 100644
--- a/arch/sim/src/sim/up_createstack.c
+++ b/arch/sim/src/sim/up_createstack.c
@@ -66,8 +66,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -91,10 +91,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
FAR uint8_t *stack_alloc_ptr;
int ret = ERROR;
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -109,43 +105,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Move up to next even word boundary if necessary */
- size_t adj_stack_size = STACK_ALIGN_UP(stack_size);
+ size_t adj_stack_size = STACK_ALIGN_UP(stack_size);
/* Allocate the memory for the stack */
#ifdef CONFIG_TLS_ALIGNED
- stack_alloc_ptr = (FAR uint8_t *)kumm_memalign(TLS_STACK_ALIGN,
- adj_stack_size);
+ stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, adj_stack_size);
#else
- stack_alloc_ptr = (FAR uint8_t *)kumm_malloc(adj_stack_size);
+ stack_alloc_ptr = kumm_malloc(adj_stack_size);
#endif
/* Was the allocation successful? */
if (stack_alloc_ptr)
{
-#if defined(CONFIG_STACK_COLORATION)
- uintptr_t stack_base;
-#endif
-
- /* This is the address of the last aligned word in the allocation.
- * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte
- * outside of the stack. This is okay for an initial state; the
- * first pushed values will be within the stack allocation.
- */
-
- uintptr_t adj_stack_addr =
- STACK_ALIGN_DOWN((uintptr_t)stack_alloc_ptr + adj_stack_size);
-
/* Save the values in the TCB */
tcb->adj_stack_size = adj_stack_size;
tcb->stack_alloc_ptr = stack_alloc_ptr;
- tcb->adj_stack_ptr = (FAR void *)adj_stack_addr;
-
- /* Initialize the TLS data structure */
-
- memset(stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
@@ -153,10 +131,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* water marks.
*/
- stack_base = (uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s);
- stack_size = tcb->adj_stack_size - sizeof(struct tls_info_s);
- up_stack_color((FAR void *)stack_base, stack_size);
+ up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif /* CONFIG_STACK_COLORATION */
diff --git a/arch/sim/src/sim/up_initialstate.c b/arch/sim/src/sim/up_initialstate.c
index 0a4a94c..bca7c25 100644
--- a/arch/sim/src/sim/up_initialstate.c
+++ b/arch/sim/src/sim/up_initialstate.c
@@ -55,11 +55,12 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(sim_getsp() -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)sim_getsp();
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
memset(&tcb->xcp, 0, sizeof(struct xcptcontext));
- tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t);
+ tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start;
}
diff --git a/arch/sim/src/sim/up_releasestack.c b/arch/sim/src/sim/up_releasestack.c
index a9e33c2..179b699 100644
--- a/arch/sim/src/sim/up_releasestack.c
+++ b/arch/sim/src/sim/up_releasestack.c
@@ -74,5 +74,5 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
dtcb->stack_alloc_ptr = NULL;
dtcb->adj_stack_size = 0;
- dtcb->adj_stack_ptr = NULL;
+ dtcb->stack_base_ptr = NULL;
}
diff --git a/arch/sim/src/sim/up_stackframe.c b/arch/sim/src/sim/up_stackframe.c
index 8c50d03..5aae8bf 100644
--- a/arch/sim/src/sim/up_stackframe.c
+++ b/arch/sim/src/sim/up_stackframe.c
@@ -69,9 +69,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -86,6 +85,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -97,16 +98,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
+
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
tcb->adj_stack_size -= frame_size;
- /* Reset the initial state */
-
- tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t);
-
/* And return a pointer to the allocated memory */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/sim/src/sim/up_usestack.c b/arch/sim/src/sim/up_usestack.c
index d8ca91a..41952a0 100644
--- a/arch/sim/src/sim/up_usestack.c
+++ b/arch/sim/src/sim/up_usestack.c
@@ -67,8 +67,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -83,7 +83,6 @@
int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
{
- uintptr_t adj_stack_addr;
size_t adj_stack_size;
#ifdef CONFIG_TLS_ALIGNED
@@ -97,23 +96,11 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
adj_stack_size = STACK_ALIGN_DOWN(stack_size);
- /* This is the address of the last word in the allocation.
- * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte
- * outside of the stack. This is okay for an initial state; the
- * first pushed values will be within the stack allocation.
- */
-
- adj_stack_addr = STACK_ALIGN_DOWN((uintptr_t)stack + adj_stack_size);
-
/* Save the values in the TCB */
tcb->adj_stack_size = adj_stack_size;
tcb->stack_alloc_ptr = stack;
- tcb->adj_stack_ptr = (FAR void *)adj_stack_addr;
-
- /* Initialize the TLS data structure */
-
- memset(stack, 0, sizeof(struct tls_info_s));
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#if defined(CONFIG_STACK_COLORATION)
/* If stack debug is enabled, then fill the stack with a
@@ -121,9 +108,7 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
* water marks.
*/
- up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s)),
- adj_stack_size - sizeof(struct tls_info_s));
+ up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif
return OK;
diff --git a/arch/sim/src/sim/up_vfork.c b/arch/sim/src/sim/up_vfork.c
index 116bad2..daa4d7c 100644
--- a/arch/sim/src/sim/up_vfork.c
+++ b/arch/sim/src/sim/up_vfork.c
@@ -56,16 +56,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
@@ -86,13 +86,11 @@ pid_t up_vfork(const xcpt_reg_t *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
- size_t stacksize;
xcpt_reg_t newsp;
xcpt_reg_t newfp;
+ xcpt_reg_t newtop;
+ xcpt_reg_t stacktop;
xcpt_reg_t stackutil;
- size_t argsize;
- void *argv;
- int ret;
sinfo("vfork context [%p]:\n", context);
sinfo(" frame pointer:%08" PRIxPTR " sp:%08" PRIxPTR " pc:%08" PRIxPTR ""
@@ -100,7 +98,7 @@ pid_t up_vfork(const xcpt_reg_t *context)
/* Allocate and initialize a TCB for the child task. */
- child = nxtask_setup_vfork((start_t)(context[JB_PC]), &argsize);
+ child = nxtask_setup_vfork((start_t)context[JB_PC]);
if (!child)
{
serr("ERROR: nxtask_setup_vfork failed\n");
@@ -109,38 +107,18 @@ pid_t up_vfork(const xcpt_reg_t *context)
sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
- /* Get the size of the parent task's stack. */
-
- stacksize = parent->adj_stack_size;
-
- /* Allocate the stack for the TCB */
-
- ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
- parent->flags & TCB_FLAG_TTYPE_MASK);
- if (ret != OK)
- {
- serr("ERROR: up_create_stack failed: %d\n", ret);
- nxtask_abort_vfork(child, -ret);
- return (pid_t)ERROR;
- }
-
- /* Allocate the memory and copy argument from parent task */
-
- argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
-
- memcpy(argv, parent->adj_stack_ptr, argsize);
-
/* How much of the parent's stack was utilized? The ARM uses
* a push-down stack so that the current stack pointer should
* be lower than the initial, adjusted stack pointer. The
* stack usage should be the difference between those two.
*/
- DEBUGASSERT((xcpt_reg_t)parent->adj_stack_ptr > context[JB_SP]);
- stackutil = (xcpt_reg_t)parent->adj_stack_ptr - context[JB_SP];
+ stacktop = (xcpt_reg_t)parent->stack_base_ptr +
+ parent->adj_stack_size;
+ DEBUGASSERT(stacktop > context[JB_SP]);
+ stackutil = stacktop - context[JB_SP];
- sinfo("Parent: stacksize:%zu stackutil:%" PRIdPTR "\n",
- stacksize, stackutil);
+ sinfo("Parent: stackutil:%" PRIuPTR "\n", stackutil);
/* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other
@@ -149,28 +127,27 @@ pid_t up_vfork(const xcpt_reg_t *context)
* effort is overkill.
*/
- newsp = (xcpt_reg_t)child->cmn.adj_stack_ptr - stackutil;
+ newtop = (xcpt_reg_t)child->cmn.stack_base_ptr +
+ child->cmn.adj_stack_size;
+ newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context[JB_SP], stackutil);
/* Was there a frame pointer in place before? */
- if (context[JB_FP] <= (xcpt_reg_t)parent->adj_stack_ptr &&
- context[JB_FP] >= (xcpt_reg_t)parent->adj_stack_ptr -
- stacksize)
+ if (context[JB_FP] >= context[JB_SP] && context[JB_FP] < stacktop)
{
- xcpt_reg_t frameutil = (xcpt_reg_t)parent->adj_stack_ptr -
- context[JB_FP];
- newfp = (xcpt_reg_t)child->cmn.adj_stack_ptr - frameutil;
+ xcpt_reg_t frameutil = stacktop - context[JB_FP];
+ newfp = newtop - frameutil;
}
else
{
newfp = context[JB_FP];
}
- sinfo("Parent: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
- parent->adj_stack_ptr, context[JB_SP], context[JB_FP]);
- sinfo("Child: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
- child->cmn.adj_stack_ptr, newsp, newfp);
+ sinfo("Old stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
+ stacktop, context[JB_SP], context[JB_FP]);
+ sinfo("New stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
+ newtop, newsp, newfp);
/* Update the stack pointer, frame pointer, and volatile registers. When
* the child TCB was initialized, all of the values were set to zero.
@@ -179,8 +156,8 @@ pid_t up_vfork(const xcpt_reg_t *context)
* child thread.
*/
- memcpy(child->cmn.xcp.regs, context, sizeof(xcpt_reg_t) *
- XCPTCONTEXT_REGS);
+ memcpy(child->cmn.xcp.regs, context,
+ sizeof(xcpt_reg_t) * XCPTCONTEXT_REGS);
child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */
child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */
diff --git a/arch/sim/src/sim/up_vfork32.S b/arch/sim/src/sim/up_vfork32.S
index 8dad26b..223a023 100644
--- a/arch/sim/src/sim/up_vfork32.S
+++ b/arch/sim/src/sim/up_vfork32.S
@@ -63,16 +63,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/sim/src/sim/up_vfork64.S b/arch/sim/src/sim/up_vfork64.S
index fa76ac1..48da703 100644
--- a/arch/sim/src/sim/up_vfork64.S
+++ b/arch/sim/src/sim/up_vfork64.S
@@ -63,16 +63,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/sim/src/sim/up_vfork_arm.S b/arch/sim/src/sim/up_vfork_arm.S
index b75870c..a60faff 100644
--- a/arch/sim/src/sim/up_vfork_arm.S
+++ b/arch/sim/src/sim/up_vfork_arm.S
@@ -55,16 +55,16 @@
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
- * 2) up_vfork()and calls nxtask_setup_vfork().
+ * 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/x86/src/common/up_assert.c b/arch/x86/src/common/up_assert.c
index 2f090d1..b7abe09 100644
--- a/arch/x86/src/common/up_assert.c
+++ b/arch/x86/src/common/up_assert.c
@@ -145,7 +145,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -199,14 +199,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- up_stackdump(ustackbase - ustacksize, ustackbase);
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
#ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c
index 31b2372..ed4a22b 100644
--- a/arch/x86/src/i486/up_createstack.c
+++ b/arch/x86/src/i486/up_createstack.c
@@ -63,8 +63,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -90,10 +90,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -133,16 +129,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -151,14 +145,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -194,24 +188,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The i486 stack must be aligned at word (4 byte) boundaries. If
* necessary top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/x86/src/i486/up_initialstate.c b/arch/x86/src/i486/up_initialstate.c
index 254bf9f..fe40db4 100644
--- a/arch/x86/src/i486/up_initialstate.c
+++ b/arch/x86/src/i486/up_initialstate.c
@@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -73,7 +73,8 @@ void up_initial_state(struct tcb_s *tcb)
* that depends on if a priority change is required or not.
*/
- xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/x86/src/i486/up_stackframe.c b/arch/x86/src/i486/up_stackframe.c
index e1b1d36..ebd5b00 100644
--- a/arch/x86/src/i486/up_stackframe.c
+++ b/arch/x86/src/i486/up_stackframe.c
@@ -80,9 +80,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -97,6 +96,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c
index 1e73f62..ac40aeb 100644
--- a/arch/x86/src/i486/up_usestack.c
+++ b/arch/x86/src/i486/up_usestack.c
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -69,7 +69,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
* top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/x86_64/src/common/up_assert.c b/arch/x86_64/src/common/up_assert.c
index e4a88fb..88f5a72 100644
--- a/arch/x86_64/src/common/up_assert.c
+++ b/arch/x86_64/src/common/up_assert.c
@@ -123,7 +123,7 @@ static void up_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint64_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint64_t)rtcb->stack_base_ptr;
ustacksize = (uint64_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -172,15 +172,14 @@ static void up_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
-#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
- _alert("ERROR: Stack pointer is not within allocated stack\n");
-#endif
+ up_stackdump(sp, ustackbase + ustacksize);
}
else
{
- up_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ up_stackdump(ustackbase, ustackbase + ustacksize);
}
/* Then dump the registers (if available) */
diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c
index e56e739..958e072 100644
--- a/arch/x86_64/src/intel64/up_createstack.c
+++ b/arch/x86_64/src/intel64/up_createstack.c
@@ -63,8 +63,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -90,10 +90,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -133,16 +129,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -151,14 +145,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive quad-words offsets from sp.
*/
- top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The intel64 stack must be aligned at word (16 byte) boundaries. If
* necessary top_of_stack must be rounded down to the next boundary.
@@ -203,17 +197,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack &= ~0x0f;
- size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint64_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/x86_64/src/intel64/up_initialstate.c b/arch/x86_64/src/intel64/up_initialstate.c
index a4fff01..a517c04 100644
--- a/arch/x86_64/src/intel64/up_initialstate.c
+++ b/arch/x86_64/src/intel64/up_initialstate.c
@@ -51,12 +51,9 @@
*
****************************************************************************/
-extern uintptr_t tux_mm_new_pd1(void);
-
void up_initial_state(struct tcb_s *tcb)
{
struct xcptcontext *xcp = &tcb->xcp;
- struct tcb_s *rtcb;
/* Initialize the idle thread stack */
@@ -64,7 +61,7 @@ void up_initial_state(struct tcb_s *tcb)
{
tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
CONFIG_IDLETHREAD_STACKSIZE);
- tcb->adj_stack_ptr = (void *)g_idle_topstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -80,17 +77,14 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[3] = (uint64_t)0x0000000000001f80;
- /* set page table to share space with current process */
-
- rtcb = this_task();
- UNUSED(rtcb);
-
/* Save the initial stack pointer... the value of the stackpointer before
* the "interrupt occurs."
*/
- xcp->regs[REG_RSP] = (uint64_t)tcb->adj_stack_ptr;
- xcp->regs[REG_RBP] = (uint64_t)tcb->adj_stack_ptr;
+ xcp->regs[REG_RSP] = (uint64_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
+ xcp->regs[REG_RBP] = (uint64_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
/* Save the task entry point */
diff --git a/arch/x86_64/src/intel64/up_stackframe.c b/arch/x86_64/src/intel64/up_stackframe.c
index b8256de..2fc0b97 100644
--- a/arch/x86_64/src/intel64/up_stackframe.c
+++ b/arch/x86_64/src/intel64/up_stackframe.c
@@ -80,9 +80,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -97,6 +96,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, tcb->adj_stack_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_RSP] = (uint64_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c
index 26ee3b7..6a1bbed 100644
--- a/arch/x86_64/src/intel64/up_usestack.c
+++ b/arch/x86_64/src/intel64/up_usestack.c
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -69,7 +69,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* referenced as positive word offsets from sp.
*/
- top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The intel64 stack must be aligned at word (16 byte) boundaries. If
* necessary top_of_stack must be rounded down to the next boundary.
@@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
*/
top_of_stack &= ~0x0f;
- size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint64_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/xtensa/src/common/xtensa_checkstack.c b/arch/xtensa/src/common/xtensa_checkstack.c
index b27d9b1..2e2a434 100644
--- a/arch/xtensa/src/common/xtensa_checkstack.c
+++ b/arch/xtensa/src/common/xtensa_checkstack.c
@@ -31,7 +31,6 @@
#include <debug.h>
#include <nuttx/arch.h>
-#include <nuttx/tls.h>
#include <nuttx/board.h>
#include "xtensa.h"
@@ -87,10 +86,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
* Skip over the TLS data structure at the bottom of the stack
*/
-#ifdef CONFIG_TLS_ALIGNED
- DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
-#endif
- start = STACK_ALIGN_UP(alloc + sizeof(struct tls_info_s));
+ start = STACK_ALIGN_UP(alloc);
end = STACK_ALIGN_DOWN(alloc + size);
/* Get the adjusted size based on the top and bottom of the stack */
@@ -173,12 +169,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
size_t up_check_tcbstack(FAR struct tcb_s *tcb)
{
- return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size);
+ return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
}
ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
{
- return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+ return tcb->adj_stack_size - up_check_tcbstack(tcb);
}
size_t up_check_stack(void)
diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c
index 9a42dfb..b3a6556 100644
--- a/arch/xtensa/src/common/xtensa_createstack.c
+++ b/arch/xtensa/src/common/xtensa_createstack.c
@@ -71,8 +71,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -103,10 +103,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
uintptr_t cpstart;
#endif
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -156,16 +152,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -174,14 +168,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)UMM_MALLOC(stack_size);
+ tcb->stack_alloc_ptr = UMM_MALLOC(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -243,26 +237,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
*/
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#ifdef CONFIG_STACK_COLORATION
/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
- up_stack_color((FAR void *)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s),
- tcb->adj_stack_size - sizeof(struct tls_info_s));
+ up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif
board_autoled_on(LED_STACKCREATED);
diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c
index bd05c45..34e70e0 100644
--- a/arch/xtensa/src/common/xtensa_dumpstate.c
+++ b/arch/xtensa/src/common/xtensa_dumpstate.c
@@ -291,7 +291,7 @@ void xtensa_dumpstate(void)
/* Get the limits on the user stack memory */
- ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+ ustackbase = (uint32_t)rtcb->stack_base_ptr;
ustacksize = (uint32_t)rtcb->adj_stack_size;
/* Get the limits on the interrupt stack memory */
@@ -362,14 +362,14 @@ void xtensa_dumpstate(void)
* stack memory.
*/
- if (sp >= ustackbase || sp < ustackbase - ustacksize)
+ if (sp >= ustackbase && sp < ustackbase + ustacksize)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- xtensa_stackdump(ustackbase - ustacksize, ustackbase);
+ xtensa_stackdump(sp, ustackbase + ustacksize);
}
else
{
- xtensa_stackdump(sp, ustackbase);
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ xtensa_stackdump(ustackbase, ustackbase + ustacksize);
}
/* Dump the state of all tasks (if available) */
diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c
index 1dc939e..772ad0e 100644
--- a/arch/xtensa/src/common/xtensa_initialstate.c
+++ b/arch/xtensa/src/common/xtensa_initialstate.c
@@ -63,8 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
if (tcb->pid == 0)
{
tcb->stack_alloc_ptr = g_idlestack;
- tcb->adj_stack_ptr = (char *)g_idlestack +
- CONFIG_IDLETHREAD_STACKSIZE;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -74,9 +73,10 @@ void up_initial_state(struct tcb_s *tcb)
/* Set initial values of registers */
- xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Task entrypoint */
- xcp->regs[REG_A0] = 0; /* To terminate GDB backtrace */
- xcp->regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr; /* Physical top of stack frame */
+ xcp->regs[REG_PC] = (uint32_t)tcb->start; /* Task entrypoint */
+ xcp->regs[REG_A0] = 0; /* To terminate GDB backtrace */
+ xcp->regs[REG_A1] = (uint32_t)tcb->stack_base_ptr + /* Physical top of stack frame */
+ tcb->adj_stack_size;
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user
* mode.
diff --git a/arch/xtensa/src/common/xtensa_stackframe.c b/arch/xtensa/src/common/xtensa_stackframe.c
index e7589ec..7707168 100644
--- a/arch/xtensa/src/common/xtensa_stackframe.c
+++ b/arch/xtensa/src/common/xtensa_stackframe.c
@@ -68,9 +68,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -85,6 +84,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -96,16 +97,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer (A1) */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return the pointer to the allocated region */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c
index e3b6677..647b2bb 100644
--- a/arch/xtensa/src/common/xtensa_usestack.c
+++ b/arch/xtensa/src/common/xtensa_usestack.c
@@ -67,8 +67,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -83,7 +83,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -111,33 +111,27 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The XTENSA stack must be aligned at 16 bytes boundaries. If necessary
* top_of_stack must be rounded down to the next boundary.
*/
top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
#if defined(CONFIG_STACK_COLORATION)
/* If stack debug is enabled, then fill the stack with a
* recognizable value that we can use later to test for high
* water marks.
*/
- up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
- sizeof(struct tls_info_s)),
- size_of_stack - sizeof(struct tls_info_s));
+ up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
#endif
return OK;
diff --git a/arch/xtensa/src/esp32/esp32_cpuidlestack.c b/arch/xtensa/src/esp32/esp32_cpuidlestack.c
index 3aad0cf..a12d774 100644
--- a/arch/xtensa/src/esp32/esp32_cpuidlestack.c
+++ b/arch/xtensa/src/esp32/esp32_cpuidlestack.c
@@ -73,8 +73,8 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS]
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
@@ -88,8 +88,6 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS]
int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
{
- uintptr_t topofstack;
-
/* XTENSA uses a push-down stack: the stack grows toward lower* addresses
* in memory. The stack pointer register points to the lowest, valid
* working address (the "top" of the stack). Items on the stack are
@@ -100,9 +98,7 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
tcb->stack_alloc_ptr = g_cpu1_idlestack;
tcb->adj_stack_size = CPU1_IDLETHREAD_STACKSIZE;
- topofstack = (uintptr_t)g_cpu1_idlestack +
- CPU1_IDLETHREAD_STACKSIZE;
- tcb->adj_stack_ptr = (uint32_t *)topofstack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
#if XCHAL_CP_NUM > 0
/* REVISIT: Does it make since to have co-processors enabled on the IDLE
diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c
index 8fa169d..742f078 100644
--- a/arch/xtensa/src/esp32/esp32_cpustart.c
+++ b/arch/xtensa/src/esp32/esp32_cpustart.c
@@ -158,7 +158,7 @@ void xtensa_appcpu_start(void)
* is to switch to a well-known IDLE thread stack.
*/
- sp = (uint32_t)tcb->adj_stack_ptr;
+ sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size;
__asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
sinfo("CPU%d Started\n", up_cpu_index());
diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c
index 8630069..5c3004d 100644
--- a/arch/z16/src/common/z16_createstack.c
+++ b/arch/z16/src/common/z16_createstack.c
@@ -62,8 +62,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -84,10 +84,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -127,16 +123,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -145,14 +139,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -170,7 +164,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -188,24 +182,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* Align the stack to word (4 byte) boundaries. This is probably
* a greater alignment than is required.
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/z16/src/common/z16_initialstate.c b/arch/z16/src/common/z16_initialstate.c
index bff0656..216823c 100644
--- a/arch/z16/src/common/z16_initialstate.c
+++ b/arch/z16/src/common/z16_initialstate.c
@@ -59,6 +59,7 @@ void up_initial_state(struct tcb_s *tcb)
#ifndef CONFIG_SUPPRESS_INTERRUPTS
tcb->xcp.regs[REG_FLAGS] = (uint16_t)Z16F_CNTRL_FLAGS_IRQE; /* IRQE flag will enable interrupts */
#endif
- reg32[REG_SP / 2] = (uint32_t)tcb->adj_stack_ptr;
+ reg32[REG_SP / 2] = (uint32_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
reg32[REG_PC / 2] = (uint32_t)tcb->start;
}
diff --git a/arch/z16/src/common/z16_stackdump.c b/arch/z16/src/common/z16_stackdump.c
index 73648d0..705aa67 100644
--- a/arch/z16/src/common/z16_stackdump.c
+++ b/arch/z16/src/common/z16_stackdump.c
@@ -50,7 +50,7 @@ static void z16_stackdump(void)
{
struct tcb_s *rtcb = this_task();
chipreg_t sp = z16_getsp();
- chipreg_t stack_base = (chipreg_t)rtcb->adj_stack_ptr;
+ chipreg_t stack_base = (chipreg_t)rtcb->stack_base_ptr;
chipreg_t stack_size = (chipreg_t)rtcb->adj_stack_size;
chipreg_t stack;
@@ -58,18 +58,18 @@ static void z16_stackdump(void)
_alert("stack_size: %08x\n", stack_size);
_alert("sp: %08x\n", sp);
- if (sp >= stack_base || sp < stack_base - stack_size)
+ if (sp >= stack_base && sp < stack_base + stack_size)
{
- _err("ERROR: Stack pointer is not within allocated stack\n");
- stack = stack_base - stack_size;
+ stack = sp;
}
else
{
- stack = sp;
+ _err("ERROR: Stack pointer is not within allocated stack\n");
+ stack = stack_base;
}
for (stack = stack & ~0x0f;
- stack < stack_base;
+ stack < stack_base + stack_size;
stack += 8 * sizeof(chipreg_t))
{
chipreg_t *ptr = (chipreg_t *)stack;
diff --git a/arch/z16/src/common/z16_stackframe.c b/arch/z16/src/common/z16_stackframe.c
index a421704..6b1e09d 100644
--- a/arch/z16/src/common/z16_stackframe.c
+++ b/arch/z16/src/common/z16_stackframe.c
@@ -71,9 +71,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,6 +87,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
- /* 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;
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
- /* Reset the initial stack pointer */
+ /* Save the adjusted stack values in the struct tcb_s */
- tcb->xcp.regs[REG_SP / 2] = (uint32_t)tcb->adj_stack_ptr;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+ tcb->adj_stack_size -= frame_size;
/* And return a pointer to the allocated memory */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/z16/src/common/z16_usestack.c b/arch/z16/src/common/z16_usestack.c
index bfdc548..a5a374c 100644
--- a/arch/z16/src/common/z16_usestack.c
+++ b/arch/z16/src/common/z16_usestack.c
@@ -53,8 +53,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -67,9 +67,9 @@
*
****************************************************************************/
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* the stack are referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* Align the stack to word (4 byte) boundaries. This is probably
* a greater alignment than is required.
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_size = top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c
index 3585f3c..4826af9 100644
--- a/arch/z80/src/common/z80_createstack.c
+++ b/arch/z80/src/common/z80_createstack.c
@@ -61,8 +61,8 @@
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -88,10 +88,6 @@
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
- /* Add the size of the TLS information structure */
-
- stack_size += sizeof(struct tls_info_s);
-
#ifdef CONFIG_TLS_ALIGNED
/* The allocated stack size must not exceed the maximum possible for the
* TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr =
- (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr =
- (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+ tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (ttype == TCB_FLAG_TTYPE_KERNEL)
{
- tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kmm_malloc(stack_size);
}
else
#endif
{
/* Use the user-space allocator if this is a task or pthread */
- tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+ tcb->stack_alloc_ptr = kumm_malloc(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
if (tcb->stack_alloc_ptr)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
/* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,24 +187,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
* referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The Z80 stack does not need to be aligned. Here is is aligned at
* word (4 byte) boundary.
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
board_autoled_on(LED_STACKCREATED);
return OK;
}
diff --git a/arch/z80/src/common/z80_stackdump.c b/arch/z80/src/common/z80_stackdump.c
index 189c5a9..093696e 100644
--- a/arch/z80/src/common/z80_stackdump.c
+++ b/arch/z80/src/common/z80_stackdump.c
@@ -45,7 +45,7 @@ void up_stackdump(void)
{
FAR struct tcb_s *rtcb = this_task();
uintptr_t sp = z80_getsp();
- uintptr_t stack_base = (uintptr_t)rtcb->adj_stack_ptr;
+ uintptr_t stack_base = (uintptr_t)rtcb->stack_base_ptr;
uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size;
uintptr_t stack;
@@ -53,17 +53,17 @@ void up_stackdump(void)
_alert("stack_size: %06x\n", stack_size);
_alert("sp: %06x\n", sp);
- if (sp >= stack_base || sp < stack_base - stack_size)
+ if (sp >= stack_base && sp < stack_base + stack_size)
{
- _alert("ERROR: Stack pointer is not within allocated stack\n");
- stack = stack_base - stack_size;
+ stack = sp;
}
else
{
- stack = sp;
+ _alert("ERROR: Stack pointer is not within allocated stack\n");
+ stack = stack_base;
}
- for (stack = stack & ~0x0f; stack < stack_base; stack += 16)
+ for (stack = stack & ~0x0f; stack < stack_base + stack_size; stack += 16)
{
FAR uint8_t *ptr = (FAR uint8_t *)stack;
diff --git a/arch/z80/src/common/z80_stackframe.c b/arch/z80/src/common/z80_stackframe.c
index 2120bb9..3756200 100644
--- a/arch/z80/src/common/z80_stackframe.c
+++ b/arch/z80/src/common/z80_stackframe.c
@@ -70,9 +70,8 @@
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -87,6 +86,8 @@
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
{
+ FAR void *ret;
+
/* Align the frame_size */
frame_size = STACK_ALIGN_UP(frame_size);
@@ -98,16 +99,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
return NULL;
}
+ ret = tcb->stack_base_ptr;
+ memset(ret, 0, frame_size);
+
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_ptr = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+ tcb->stack_base_ptr = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
tcb->adj_stack_size -= frame_size;
- /* Reset the initial stack pointer */
-
- tcb->xcp.regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
-
/* And return a pointer to the allocated memory */
- return tcb->adj_stack_ptr;
+ return ret;
}
diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c
index 260d884..40b212b 100644
--- a/arch/z80/src/common/z80_usestack.c
+++ b/arch/z80/src/common/z80_usestack.c
@@ -52,8 +52,8 @@
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -68,7 +68,7 @@
int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
{
- size_t top_of_stack;
+ uintptr_t top_of_stack;
size_t size_of_stack;
#ifdef CONFIG_TLS_ALIGNED
@@ -104,23 +104,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
* the stack are* referenced as positive word offsets from sp.
*/
- top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+ top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
/* The Z80 stack does not need to be aligned. Here is is aligned at
* word (4 byte) boundary.
*/
top_of_stack &= ~3;
- size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+ size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
/* Save the adjusted stack values in the struct tcb_s */
- tcb->adj_stack_size = top_of_stack;
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = size_of_stack;
- /* Initialize the TLS data structure */
-
- memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
return OK;
}
diff --git a/arch/z80/src/ez80/ez80_initialstate.c b/arch/z80/src/ez80/ez80_initialstate.c
index d6d0573..cd97727 100644
--- a/arch/z80/src/ez80/ez80_initialstate.c
+++ b/arch/z80/src/ez80/ez80_initialstate.c
@@ -52,7 +52,7 @@
void up_initial_state(FAR struct tcb_s *tcb)
{
- struct xcptcontext *xcp = &tcb->xcp;
+ FAR struct xcptcontext *xcp = &tcb->xcp;
/* Initialize the initial exception register context structure */
@@ -61,9 +61,10 @@ void up_initial_state(FAR struct tcb_s *tcb)
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Parity/Overflow flag will enable interrupts */
- ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG;
+ ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG;
#endif
- xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+ xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
}
diff --git a/arch/z80/src/z180/z180_initialstate.c b/arch/z80/src/z180/z180_initialstate.c
index 43f4c52..f05ce92 100644
--- a/arch/z80/src/z180/z180_initialstate.c
+++ b/arch/z80/src/z180/z180_initialstate.c
@@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb)
if (tcb->pid == 0)
{
tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE;
- tcb->adj_stack_ptr = (void *)(CONFIG_STACK_BASE +
- CONFIG_IDLETHREAD_STACKSIZE);
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb)
#ifndef CONFIG_SUPPRESS_INTERRUPTS
xcp->regs[XCPT_I] = Z180_PV_FLAG; /* Parity flag will enable interrupts */
#endif
- xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+ xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
}
diff --git a/arch/z80/src/z8/z8_initialstate.c b/arch/z80/src/z8/z8_initialstate.c
index d62c4b9..187e162 100644
--- a/arch/z80/src/z8/z8_initialstate.c
+++ b/arch/z80/src/z8/z8_initialstate.c
@@ -74,6 +74,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
xcp->regs[XCPT_IRQCTL] = 0x0080; /* IRQE bit will enable interrupts */
#endif
xcp->regs[XCPT_RPFLAGS] = 0xe000; /* RP=%e0 */
- xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+ xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
}
diff --git a/arch/z80/src/z80/z80_initialstate.c b/arch/z80/src/z80/z80_initialstate.c
index 05c2df3..9b24a65 100644
--- a/arch/z80/src/z80/z80_initialstate.c
+++ b/arch/z80/src/z80/z80_initialstate.c
@@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb)
if (tcb->pid == 0)
{
tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE;
- tcb->adj_stack_ptr = (void *)(CONFIG_STACK_BASE +
- CONFIG_IDLETHREAD_STACKSIZE);
+ tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
}
@@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb)
#ifndef CONFIG_SUPPRESS_INTERRUPTS
xcp->regs[XCPT_I] = Z80_PV_FLAG; /* Parity flag will enable interrupts */
#endif
- xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+ xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+ tcb->adj_stack_size;
xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
}
diff --git a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
index 83117c3..8ccf65f 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
@@ -181,7 +181,8 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
pdump->info.stacks.user.sp = currentsp;
}
- pdump->info.stacks.user.top = (uint32_t)rtcb->adj_stack_ptr;
+ pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+ rtcb->adj_stack_size;
pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
index df58f75..fb14e79 100644
--- a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
+++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
@@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
pdump->info.stacks.user.sp = currentsp;
}
- pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
- pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+ pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+ rtcb->adj_stack_size;
+ pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
index 87e2f1a..b3a1600 100644
--- a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
+++ b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
@@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
pdump->info.stacks.user.sp = currentsp;
}
- pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
- pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+ pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+ rtcb->adj_stack_size;
+ pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
diff --git a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
index 0118242..31153f7 100644
--- a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
+++ b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
@@ -403,8 +403,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
pdump->info.stacks.user.sp = currentsp;
}
- pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
- pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+ pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+ rtcb->adj_stack_size;
+ pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
diff --git a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
index cda6328..04a8ab3 100644
--- a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
+++ b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
@@ -401,8 +401,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
pdump->info.stacks.user.sp = currentsp;
}
- pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
- pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+ pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+ rtcb->adj_stack_size;
+ pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index a3af61f..8301867 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -857,7 +857,7 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
/* Show the stack base address */
linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s0x%p\n",
- "StackBase:", tcb->adj_stack_ptr);
+ "StackBase:", tcb->stack_base_ptr);
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
&offset);
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 379146e..f9e5bda 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -232,8 +232,8 @@ void up_initial_state(FAR struct tcb_s *tcb);
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -274,8 +274,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype);
* processor, etc. This value is retained only for debug
* purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The
- * initial value of the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -308,9 +308,24 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size);
*
* - adj_stack_size: Stack size after removal of the stack frame from
* the stack
- * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- * been removed from the stack. This will still be the initial value
- * of the stack pointer when the task is started.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
+ *
+ * Here is the diagram after some allocation(tls, arg):
+ *
+ * +-------------+ <-stack_alloc_ptr(lowest)
+ * | TLS Data |
+ * +-------------+
+ * | Arguments |
+ * stack_base_ptr-> +-------------+\
+ * | Available | +
+ * | Stack | |
+ * | | | |
+ * | | | +->adj_stack_size
+ * v | | |
+ * | | |
+ * | | +
+ * +-------------+/
*
* Input Parameters:
* - tcb: The TCB of new task
@@ -1847,8 +1862,8 @@ int up_cpu_index(void);
* - adj_stack_size: Stack size after adjustment for hardware, processor,
* etc. This value is retained only for debug purposes.
* - stack_alloc_ptr: Pointer to allocated stack
- * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of
- * the stack pointer.
+ * - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ * Arguments has been removed from the stack allocation.
*
* Input Parameters:
* - cpu: CPU index that indicates which CPU the IDLE task is
diff --git a/include/nuttx/lib/libvars.h b/include/nuttx/lib/libvars.h
deleted file mode 100644
index 47612cc..0000000
--- a/include/nuttx/lib/libvars.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
- * include/nuttx/lib/libvars.h
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __INCLUDE_NUTTX_LIB_LIBVARS_H
-#define __INCLUDE_NUTTX_LIB_LIBVARS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdbool.h>
-
-#include <nuttx/lib/getopt.h>
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-#ifndef CONFIG_BUILD_KERNEL
-/* This structure encapsulates all task-specific variables needed by the C
- * Library. This structure is retained at the beginning of the main thread
- * of and is accessed via a reference stored in the TLS of all threads in
- * the task group.
- *
- * NOTE: task-specific variables are not needed in the KERNEL build. In
- * that build mode, all global variables are inherently process-specific.
- */
-
-struct libvars_s
-{
- struct getopt_s lv_getopt; /* Globals used by getopt() */
-};
-#endif
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __INCLUDE_NUTTX_LIB_LIBVARS_H */
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 4e06514..4f7f647 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -38,7 +38,6 @@
#include <nuttx/clock.h>
#include <nuttx/irq.h>
#include <nuttx/wdog.h>
-#include <nuttx/lib/libvars.h>
#include <nuttx/mm/shm.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
@@ -401,8 +400,9 @@ struct stackinfo_s
/* (for debug purposes only) */
FAR void *stack_alloc_ptr; /* Pointer to allocated stack */
/* Needed to deallocate stack */
- FAR void *adj_stack_ptr; /* Adjusted stack_alloc_ptr for HW */
- /* The initial stack pointer value */
+ FAR void *stack_base_ptr; /* Adjusted initial stack pointer */
+ /* after the frame has been removed */
+ /* from the stack. */
};
/* struct exitinfo_s ************************************************************/
@@ -530,12 +530,6 @@ struct task_group_s
tls_ndxset_t tg_tlsset; /* Set of TLS data indexes allocated */
#endif
- /* Task-specific Data *********************************************************/
-
-#ifndef CONFIG_BUILD_KERNEL
- FAR struct libvars_s *tg_libvars; /* C library global variables */
-#endif
-
/* POSIX Signal Control Fields ************************************************/
sq_queue_t tg_sigactionq; /* List of actions for signals */
@@ -662,8 +656,9 @@ struct tcb_s
/* (for debug purposes only) */
FAR void *stack_alloc_ptr; /* Pointer to allocated stack */
/* Needed to deallocate stack */
- FAR void *adj_stack_ptr; /* Adjusted stack_alloc_ptr for HW */
- /* The initial stack pointer value */
+ FAR void *stack_base_ptr; /* Adjusted initial stack pointer */
+ /* after the frame has been removed */
+ /* from the stack. */
/* External Module Support ****************************************************/
@@ -1030,10 +1025,10 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - Initialization of the TCB (including call to up_initial_state())
* 4) vfork() provides any additional operating context. vfork must:
- * - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork()
@@ -1043,7 +1038,7 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
*
********************************************************************************/
-FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize);
+FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr);
pid_t nxtask_start_vfork(FAR struct task_tcb_s *child);
void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode);
@@ -1330,7 +1325,7 @@ int nxsched_set_affinity(pid_t pid, size_t cpusetsize,
*
* Input Parameters:
* pid - Identifies the thread to query. Zero is interpreted as the
- * the calling thread
+ * the calling thread, -1 is interpreted as the calling task.
* stackinfo - User-provided location to return the stack information.
*
* Returned Value:
diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h
index bd729d3..79f0e78 100644
--- a/include/nuttx/tls.h
+++ b/include/nuttx/tls.h
@@ -27,7 +27,7 @@
#include <nuttx/config.h>
-#include <sys/types.h>
+#include <nuttx/lib/getopt.h>
/****************************************************************************
* Pre-processor Definitions
@@ -71,6 +71,26 @@
*
* The stack memory is fully accessible to user mode threads. TLS is not
* available from interrupt handlers (nor from the IDLE thread).
+ *
+ * The following diagram represent the typic stack layout:
+ *
+ * Push Down Push Up
+ * +-------------+ +-------------+ <- Stack memory allocation
+ * | TLS Data | | TLS Data |
+ * +-------------+ +-------------+
+ * | Task Data* | | Task Data* |
+ * +-------------+ +-------------+
+ * | Arguments | | Arguments |
+ * +-------------+ +-------------+ |
+ * | | | | v
+ * | Available | | Available |
+ * | Stack | | Stack |
+ * | | | |
+ * | | | |
+ * | | ^ | |
+ * +-------------+ | +-------------+
+ *
+ * Task data is allocated in the main's thread's stack only
*/
struct tls_info_s
@@ -78,10 +98,17 @@ struct tls_info_s
#if CONFIG_TLS_NELEM > 0
uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */
#endif
- FAR struct libvars_s *tl_libvars; /* Task-specific C library data */
int tl_errno; /* Per-thread error number */
};
+struct task_info_s
+{
+ struct tls_info_s ta_tls; /* Must be first field */
+#ifndef CONFIG_BUILD_KERNEL
+ struct getopt_s ta_getopt; /* Globals used by getopt() */
+#endif
+};
+
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -189,4 +216,21 @@ int tls_set_value(int tlsindex, uintptr_t tlsvalue);
FAR struct tls_info_s *tls_get_info(void);
#endif
+/****************************************************************************
+ * Name: task_get_info
+ *
+ * Description:
+ * Return a reference to the task_info_s structure.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * A reference to the task-specific task_info_s structure is return on
+ * success. NULL would be returned in the event of any failure.
+ *
+ ****************************************************************************/
+
+FAR struct task_info_s *task_get_info(void);
+
#endif /* __INCLUDE_NUTTX_TLS_H */
diff --git a/libs/libc/pthread/pthread_get_stackaddr_np.c b/libs/libc/pthread/pthread_get_stackaddr_np.c
index e2be546..a8a570b 100644
--- a/libs/libc/pthread/pthread_get_stackaddr_np.c
+++ b/libs/libc/pthread/pthread_get_stackaddr_np.c
@@ -74,5 +74,5 @@ FAR void *pthread_get_stackaddr_np(pthread_t thread)
return NULL;
}
- return stackinfo.adj_stack_ptr;
+ return stackinfo.stack_base_ptr;
}
diff --git a/libs/libc/tls/Make.defs b/libs/libc/tls/Make.defs
index 0e125f8..504d2c6 100644
--- a/libs/libc/tls/Make.defs
+++ b/libs/libc/tls/Make.defs
@@ -18,6 +18,8 @@
#
############################################################################
+CSRCS += task_getinfo.c
+
ifneq ($(CONFIG_TLS_NELEM),0)
CSRCS += tls_setvalue.c tls_getvalue.c
endif
diff --git a/sched/group/group_taskdata.c b/libs/libc/tls/task_getinfo.c
similarity index 68%
rename from sched/group/group_taskdata.c
rename to libs/libc/tls/task_getinfo.c
index 392cb3d..8ae77a1 100644
--- a/sched/group/group_taskdata.c
+++ b/libs/libc/tls/task_getinfo.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * sched/group/group_taskdata.c
+ * libs/libc/tls/task_getinfo.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -25,51 +25,39 @@
#include <nuttx/config.h>
#include <sched.h>
-#include <assert.h>
#include <nuttx/tls.h>
-#include "group/group.h"
-
-#ifndef CONFIG_BUILD_KERNEL
-
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
- * Name: tls_set_taskdata
+ * Name: task_get_info
*
* Description:
- * Set task-specific data pointer in TLS.
+ * Return a reference to the task_info_s structure.
*
* Input Parameters:
- * tcb - Identifies task to set TLS data
+ * None
*
* Returned Value:
- * None
+ * A reference to the task-specific task_info_s structure is return on
+ * success. NULL would be returned in the event of any failure.
*
****************************************************************************/
-void tls_set_taskdata(FAR struct tcb_s *tcb)
+FAR struct task_info_s *task_get_info(void)
{
- FAR struct tls_info_s *info;
- FAR struct task_group_s *group;
+ FAR struct task_info_s *info = NULL;
+ struct stackinfo_s stackinfo;
+ int ret;
- DEBUGASSERT(tcb != NULL && tcb->group != NULL);
- group = tcb->group;
+ ret = nxsched_get_stackinfo(-1, &stackinfo);
+ if (ret >= 0)
+ {
+ info = (FAR struct task_info_s *)stackinfo.stack_alloc_ptr;
+ }
- /* This currently assumes a push-down stack. The TLS data lies at the
- * lowest address of the stack allocation.
- */
-
- info = (FAR struct tls_info_s *)tcb->stack_alloc_ptr;
-
- /* Copy the task data point buffer in the group structure into the
- * thread's TLS data.
- */
-
- info->tl_libvars = group->tg_libvars;
+ return info;
}
-
-#endif /* !CONFIG_BUILD_KERNEL */
\ No newline at end of file
diff --git a/libs/libc/tls/tls.h b/libs/libc/tls/tls.h
deleted file mode 100644
index d935baf..0000000
--- a/libs/libc/tls/tls.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************************
- * libs/libc/tls/tls.h
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __SCHED_TLS_TLS_H
-#define __SCHED_TLS_TLS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#endif /* __SCHED_TLS_TLS_H */
diff --git a/libs/libc/unistd/lib_getoptvars.c b/libs/libc/unistd/lib_getoptvars.c
index 1e15925..cc0fde2 100644
--- a/libs/libc/unistd/lib_getoptvars.c
+++ b/libs/libc/unistd/lib_getoptvars.c
@@ -24,16 +24,11 @@
#include <nuttx/config.h>
-#include <unistd.h>
#include <assert.h>
#include <nuttx/tls.h>
-#include <nuttx/lib/libvars.h>
-
-#include <arch/tls.h>
#include "unistd.h"
-#include "libc.h"
/****************************************************************************
* Private Data
@@ -70,13 +65,13 @@ FAR struct getopt_s g_getopt_vars =
FAR struct getopt_s *getoptvars(void)
{
#ifndef CONFIG_BUILD_KERNEL
- FAR struct tls_info_s *tlsinfo;
+ FAR struct task_info_s *info;
/* Get the structure of getopt() variables using the key. */
- tlsinfo = up_tls_info();
- DEBUGASSERT(tlsinfo != NULL && tlsinfo->tl_libvars != NULL);
- return &tlsinfo->tl_libvars->lv_getopt;
+ info = task_get_info();
+ DEBUGASSERT(info != NULL);
+ return &info->ta_getopt;
#else
return &g_getopt_vars;
#endif
diff --git a/sched/group/Make.defs b/sched/group/Make.defs
index 9d2e676..14f1225 100644
--- a/sched/group/Make.defs
+++ b/sched/group/Make.defs
@@ -57,10 +57,6 @@ ifneq ($(CONFIG_TLS_NELEM),0)
CSRCS += group_tlsalloc.c group_tlsfree.c
endif
-ifndef CONFIG_BUILD_KERNEL
-CSRCS += group_taskdata.c
-endif
-
# Include group build support
DEPPATH += --dep-path group
diff --git a/sched/group/group.h b/sched/group/group.h
index 94b49bf..3449891 100644
--- a/sched/group/group.h
+++ b/sched/group/group.h
@@ -140,10 +140,4 @@ int group_setuptaskfiles(FAR struct task_tcb_s *tcb);
int group_setupstreams(FAR struct task_tcb_s *tcb);
#endif
-#ifndef CONFIG_BUILD_KERNEL
-/* Task specific data */
-
-void tls_set_taskdata(FAR struct tcb_s *tcb);
-#endif
-
#endif /* __SCHED_GROUP_GROUP_H */
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index 007c7bf..1c4af3b 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -40,6 +40,7 @@
#include <nuttx/semaphore.h>
#include <nuttx/kmalloc.h>
#include <nuttx/pthread.h>
+#include <nuttx/tls.h>
#include "sched/sched.h"
#include "group/group.h"
@@ -218,6 +219,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
pthread_startroutine_t start_routine, pthread_addr_t arg)
{
FAR struct pthread_tcb_s *ptcb;
+ FAR struct tls_info_s *info;
FAR struct join_s *pjoin;
struct sched_param param;
int policy;
@@ -291,7 +293,8 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
{
/* Allocate the stack for the TCB */
- ret = up_create_stack((FAR struct tcb_s *)ptcb, attr->stacksize,
+ ret = up_create_stack((FAR struct tcb_s *)ptcb,
+ sizeof(struct tls_info_s) + attr->stacksize,
TCB_FLAG_TTYPE_PTHREAD);
}
@@ -301,11 +304,16 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
goto errout_with_join;
}
-#ifndef CONFIG_BUILD_KERNEL
- /* Save the allocated task data in TLS */
+ /* Initialize thread local storage */
- tls_set_taskdata(&ptcb->cmn);
-#endif
+ info = up_stack_frame(&ptcb->cmn, sizeof(struct tls_info_s));
+ if (info == NULL)
+ {
+ errcode = ENOMEM;
+ goto errout_with_join;
+ }
+
+ DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr);
/* Should we use the priority and scheduler specified in the pthread
* attributes? Or should we use the current thread's priority and
diff --git a/sched/sched/sched_get_stackinfo.c b/sched/sched/sched_get_stackinfo.c
index 1220964..7d6bda0 100644
--- a/sched/sched/sched_get_stackinfo.c
+++ b/sched/sched/sched_get_stackinfo.c
@@ -42,7 +42,7 @@
*
* Input Parameters:
* pid - Identifies the thread to query. Zero is interpreted as the
- * the calling thread
+ * the calling thread, -1 is interpreted as the calling task.
* stackinfo - User-provided location to return the stack information.
*
* Returned Value:
@@ -69,6 +69,16 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo)
qtcb = rtcb;
}
+ else if (pid == -1)
+ {
+ /* We can always query our main thread */
+
+ qtcb = nxsched_get_tcb(rtcb->group->tg_pid);
+ if (qtcb == NULL)
+ {
+ return -ENOENT;
+ }
+ }
else
{
/* Get the task to be queried */
@@ -100,6 +110,7 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo)
stackinfo->adj_stack_size = qtcb->adj_stack_size;
stackinfo->stack_alloc_ptr = qtcb->stack_alloc_ptr;
- stackinfo->adj_stack_ptr = qtcb->adj_stack_ptr;
+ stackinfo->stack_base_ptr = qtcb->stack_base_ptr;
+
return OK;
}
diff --git a/sched/task/task_init.c b/sched/task/task_init.c
index bd6a9bc..ba34b93 100644
--- a/sched/task/task_init.c
+++ b/sched/task/task_init.c
@@ -32,7 +32,7 @@
#include <nuttx/arch.h>
#include <nuttx/sched.h>
-#include <nuttx/lib/libvars.h>
+#include <nuttx/tls.h>
#include "sched/sched.h"
#include "group/group.h"
@@ -85,9 +85,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
main_t entry, FAR char * const argv[])
{
uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK;
-#ifndef CONFIG_BUILD_KERNEL
- FAR struct task_group_s *group;
-#endif
+ FAR struct task_info_s *info;
int ret;
#ifndef CONFIG_DISABLE_PTHREAD
@@ -122,7 +120,9 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
{
/* Allocate the stack for the TCB */
- ret = up_create_stack(&tcb->cmn, stack_size, ttype);
+ ret = up_create_stack(&tcb->cmn,
+ sizeof(struct task_info_s) + stack_size,
+ ttype);
}
if (ret < OK)
@@ -130,21 +130,16 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
goto errout_with_group;
}
-#ifndef CONFIG_BUILD_KERNEL
- /* Allocate a stack frame to hold task-specific data */
-
- group = tcb->cmn.group;
- group->tg_libvars = up_stack_frame(&tcb->cmn, sizeof(struct libvars_s));
- DEBUGASSERT(group->tg_libvars != NULL);
-
- /* Initialize the task-specific data */
-
- memset(group->tg_libvars, 0, sizeof(struct libvars_s));
+ /* Initialize thread local storage */
- /* Save the allocated task data in TLS */
+ info = up_stack_frame(&tcb->cmn, sizeof(struct task_info_s));
+ if (info == NULL)
+ {
+ ret = -ENOMEM;
+ goto errout_with_group;
+ }
- tls_set_taskdata(&tcb->cmn);
-#endif
+ DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr);
/* Initialize the task control block */
diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c
index 9dd874d..b31b732 100644
--- a/sched/task/task_vfork.c
+++ b/sched/task/task_vfork.c
@@ -34,191 +34,16 @@
#include <debug.h>
#include <nuttx/sched.h>
+#include <nuttx/tls.h>
#include "sched/sched.h"
#include "group/group.h"
#include "task/task.h"
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
/* vfork() requires architecture-specific support as well as waipid(). */
#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID)
-/* This is an artificial limit to detect error conditions where an argv[]
- * list is not properly terminated.
- */
-
-#define MAX_VFORK_ARGS 256
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nxvfork_setup_name
- *
- * Description:
- * Copy the task name.
- *
- * Input Parameters:
- * tcb - Address of the new task's TCB
- * name - Name of the new task
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-#if CONFIG_TASK_NAME_SIZE > 0
-static inline void nxvfork_setup_name(FAR struct tcb_s *parent,
- FAR struct task_tcb_s *child)
-{
- /* Copy the name from the parent into the child TCB */
-
- strncpy(child->cmn.name, parent->name, CONFIG_TASK_NAME_SIZE);
-}
-#else
-# define nxvfork_setup_name(p,c)
-#endif /* CONFIG_TASK_NAME_SIZE */
-
-/****************************************************************************
- * Name: nxvfork_setup_stackargs
- *
- * Description:
- * Clone the task arguments in the same relative positions on the child's
- * stack.
- *
- * Input Parameters:
- * parent - Address of the parent task's TCB
- * child - Address of the child task's TCB
- *
- * Returned Value:
- * Zero (OK) on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-static inline int nxvfork_setup_stackargs(FAR struct tcb_s *parent,
- FAR struct task_tcb_s *child)
-{
- /* Is the parent a task? or a pthread? Only tasks (and kernel threads)
- * have command line arguments.
- */
-
- child->argv = NULL;
- if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
- {
- FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent;
- uintptr_t offset;
- int argc;
-
- /* Get the address correction */
-
- offset = (uintptr_t)child->cmn.adj_stack_ptr -
- (uintptr_t)parent->adj_stack_ptr;
-
- /* Change the child argv[] to point into its stack (instead of its
- * parent's stack).
- */
-
- child->argv = (FAR char **)((uintptr_t)ptcb->argv + offset);
-
- /* Copy the adjusted address for each argument */
-
- argc = 0;
- while (ptcb->argv[argc])
- {
- uintptr_t newaddr = (uintptr_t)ptcb->argv[argc] + offset;
- child->argv[argc] = (FAR char *)newaddr;
-
- /* Increment the number of args. Here is a sanity check to
- * prevent running away with an unterminated argv[] list.
- * MAX_VFORK_ARGS should be sufficiently large that this never
- * happens in normal usage.
- */
-
- if (++argc > MAX_VFORK_ARGS)
- {
- return -E2BIG;
- }
- }
-
- /* Put a terminator entry at the end of the child argv[] array. */
-
- child->argv[argc] = NULL;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: nxvfork_setup_arguments
- *
- * Description:
- * Clone the argument list from the parent to the child.
- *
- * Input Parameters:
- * parent - Address of the parent task's TCB
- * child - Address of the child task's TCB
- *
- * Returned Value:
- * Zero (OK) on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-static inline int nxvfork_setup_arguments(FAR struct tcb_s *parent,
- FAR struct task_tcb_s *child)
-{
- /* Clone the task name */
-
- nxvfork_setup_name(parent, child);
-
- /* Adjust and copy the argv[] array. */
-
- return nxvfork_setup_stackargs(parent, child);
-}
-
-/****************************************************************************
- * Name: nxvfork_sizeof_arguments
- *
- * Description:
- * Get the parent's argument size.
- *
- * Input Parameters:
- * parent - Address of the parent task's TCB
- *
- * Return Value:
- * The parent's argument size.
- *
- ****************************************************************************/
-
-static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
-{
- if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
- {
- FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent;
- size_t strtablen = 0;
- int argc = 0;
-
- while (ptcb->argv[argc])
- {
- /* Add the size of this argument (with NUL terminator) */
-
- strtablen += strlen(ptcb->argv[argc++]) + 1;
- }
-
- /* Return the size to hold argv[] array and the strings. */
-
- return (argc + 1) * sizeof(FAR char *) + strtablen;
- }
- else
- {
- return 0;
- }
-}
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -246,10 +71,10 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - 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
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
@@ -266,29 +91,48 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
*
****************************************************************************/
-FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
+FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
{
- FAR struct tcb_s *parent = this_task();
+ FAR struct tcb_s *ptcb = this_task();
+ FAR struct task_tcb_s *parent;
FAR struct task_tcb_s *child;
+ FAR struct task_info_s *info;
+ FAR const char *name = NULL;
+ size_t stack_size;
uint8_t ttype;
int priority;
int ret;
- DEBUGASSERT(retaddr != NULL && argsize != NULL);
+ DEBUGASSERT(retaddr != NULL);
/* Get the type of the fork'ed task (kernel or user) */
- if ((parent->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
+ if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
{
/* Fork'ed from a kernel thread */
ttype = TCB_FLAG_TTYPE_KERNEL;
+ parent = (FAR struct task_tcb_s *)ptcb;
}
else
{
/* Fork'ed from a user task or pthread */
ttype = TCB_FLAG_TTYPE_TASK;
+ if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK)
+ {
+ parent = (FAR struct task_tcb_s *)ptcb;
+ }
+ else
+ {
+ parent = (FAR struct task_tcb_s *)
+ nxsched_get_tcb(ptcb->group->tg_pid);
+ if (parent == NULL)
+ {
+ ret = -ENOENT;
+ goto errout;
+ }
+ }
}
/* Allocate a TCB for the child task. */
@@ -297,13 +141,13 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
if (!child)
{
serr("ERROR: Failed to allocate TCB\n");
- set_errno(ENOMEM);
- return NULL;
+ ret = -ENOMEM;
+ goto errout;
}
/* Allocate a new task group with the same privileges as the parent */
- ret = group_allocate(child, parent->flags);
+ ret = group_allocate(child, ttype);
if (ret < 0)
{
goto errout_with_tcb;
@@ -317,33 +161,71 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
goto errout_with_tcb;
}
+ /* Allocate the stack for the TCB */
+
+ stack_size = (uintptr_t)ptcb->stack_base_ptr -
+ (uintptr_t)ptcb->stack_alloc_ptr + ptcb->adj_stack_size;
+
+ ret = up_create_stack(&child->cmn, stack_size, ttype);
+ if (ret < OK)
+ {
+ goto errout_with_tcb;
+ }
+
+ /* Setup thread local storage */
+
+ info = up_stack_frame(&child->cmn, sizeof(struct task_info_s));
+ if (info == NULL)
+ {
+ ret = -ENOMEM;
+ goto errout_with_tcb;
+ }
+
+ DEBUGASSERT(info == child->cmn.stack_alloc_ptr);
+ memcpy(info, parent->cmn.stack_alloc_ptr, sizeof(struct task_info_s));
+
/* Get the priority of the parent task */
#ifdef CONFIG_PRIORITY_INHERITANCE
- priority = parent->base_priority; /* "Normal," unboosted priority */
+ priority = ptcb->base_priority; /* "Normal," unboosted priority */
#else
- priority = parent->sched_priority; /* Current priority */
+ priority = ptcb->sched_priority; /* Current priority */
#endif
/* Initialize the task control block. This calls up_initial_state() */
sinfo("Child priority=%d start=%p\n", priority, retaddr);
- ret = nxtask_setup_scheduler(child, priority, retaddr, parent->entry.main,
- ttype);
+ ret = nxtask_setup_scheduler(child, priority, retaddr,
+ ptcb->entry.main, ttype);
if (ret < OK)
{
goto errout_with_tcb;
}
- /* Return the argument size */
+ /* Setup to pass parameters to the new task */
+
+#if CONFIG_TASK_NAME_SIZE > 0
+ name = parent->cmn.name;
+#endif
+
+ nxtask_setup_arguments(child, name, parent->argv);
+
+ /* Now we have enough in place that we can join the group */
- *argsize = nxvfork_sizeof_arguments(parent);
+ ret = group_initialize(child);
+ if (ret < OK)
+ {
+ goto errout_with_list;
+ }
sinfo("parent=%p, returning child=%p\n", parent, child);
return child;
+errout_with_list:
+ dq_rem((FAR dq_entry_t *)child, (FAR dq_queue_t *)&g_inactivetasks);
errout_with_tcb:
nxsched_release_tcb((FAR struct tcb_s *)child, ttype);
+errout:
set_errno(-ret);
return NULL;
}
@@ -371,10 +253,10 @@ errout_with_tcb:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
+ * - Allocate and initialize the stack
* - Setup the input parameters for the task.
- * - Initialization of the TCB (including call to up_initial_state()
+ * - Initialization of the TCB (including call to up_initial_state())
* 4) vfork() provides any additional operating context. vfork must:
- * - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork()
@@ -394,32 +276,13 @@ errout_with_tcb:
pid_t nxtask_start_vfork(FAR struct task_tcb_s *child)
{
- FAR struct tcb_s *parent = this_task();
pid_t pid;
- int rc;
+ int rc = 0;
int ret;
- sinfo("Starting Child TCB=%p, parent=%p\n", child, this_task());
+ sinfo("Starting Child TCB=%p\n", child);
DEBUGASSERT(child);
- /* Duplicate the original argument list in the forked child TCB */
-
- ret = nxvfork_setup_arguments(parent, child);
- if (ret < 0)
- {
- nxtask_abort_vfork(child, -ret);
- return ERROR;
- }
-
- /* Now we have enough in place that we can join the group */
-
- ret = group_initialize(child);
- if (ret < 0)
- {
- nxtask_abort_vfork(child, -ret);
- return ERROR;
- }
-
/* Get the assigned pid before we start the task */
pid = (int)child->cmn.pid;
@@ -453,17 +316,11 @@ pid_t nxtask_start_vfork(FAR struct task_tcb_s *child)
* opportunity to run.
*/
- rc = 0;
-
-#ifdef CONFIG_DEBUG_FEATURES
ret = waitpid(pid, &rc, 0);
if (ret < 0)
{
serr("ERROR: waitpid failed: %d\n", get_errno());
}
-#else
- waitpid(pid, &rc, 0);
-#endif
sched_unlock();
return pid;
@@ -489,7 +346,7 @@ void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode)
/* Release the TCB */
nxsched_release_tcb((FAR struct tcb_s *)child,
- child->cmn.flags & TCB_FLAG_TTYPE_MASK);
+ child->cmn.flags & TCB_FLAG_TTYPE_MASK);
set_errno(errcode);
}