Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Documentation/guides/kernel_threads_with_custom_stacks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Here is the body of some function. It expects to have the following inputs:
* used to that all fields of the new TCB will be zeroed.
*/

tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s));
tcb = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct task_group_s));
if (tcb == NULL)
{
return -ENOMEM;
Expand Down Expand Up @@ -131,4 +131,4 @@ option is to include it in all cases where you do not expect the custom stack
to be de-allocated.

You must not free the custom stack after ``nxtask_activate()`` returns
successfully and until the kernel thread is terminated.
successfully and until the kernel thread is terminated.
40 changes: 20 additions & 20 deletions arch/arm/src/common/arm_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
pid_t arm_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
struct tcb_s *child;
uint32_t newsp;
uint32_t newfp;
uint32_t newtop;
Expand Down Expand Up @@ -144,17 +144,17 @@ pid_t arm_fork(const struct fork_s *context)
* effort is overkill.
*/

newtop = (uint32_t)child->cmn.stack_base_ptr +
child->cmn.adj_stack_size;
newtop = (uint32_t)child->stack_base_ptr +
child->adj_stack_size;

newsp = newtop - stackutil;

/* Move the register context to newtop. */

memcpy((void *)(newsp - XCPTCONTEXT_SIZE),
child->cmn.xcp.regs, XCPTCONTEXT_SIZE);
child->xcp.regs, XCPTCONTEXT_SIZE);

child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);
child->xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);

memcpy((void *)newsp, (const void *)oldsp, stackutil);

Expand Down Expand Up @@ -182,16 +182,16 @@ pid_t arm_fork(const struct fork_s *context)
* child thread.
*/

child->cmn.xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */
child->cmn.xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */
child->cmn.xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */
child->cmn.xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */
child->cmn.xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */
child->cmn.xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */
child->cmn.xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */
child->cmn.xcp.regs[REG_R11] = context->r11; /* Volatile register r11 */
child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */
child->xcp.regs[REG_R4] = context->r4; /* Volatile register r4 */
child->xcp.regs[REG_R5] = context->r5; /* Volatile register r5 */
child->xcp.regs[REG_R6] = context->r6; /* Volatile register r6 */
child->xcp.regs[REG_R7] = context->r7; /* Volatile register r7 */
child->xcp.regs[REG_R8] = context->r8; /* Volatile register r8 */
child->xcp.regs[REG_R9] = context->r9; /* Volatile register r9 */
child->xcp.regs[REG_R10] = context->r10; /* Volatile register r10 */
child->xcp.regs[REG_R11] = context->r11; /* Volatile register r11 */
child->xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->xcp.regs[REG_SP] = newsp; /* Stack pointer */

#ifdef CONFIG_LIB_SYSCALL
/* If we got here via a syscall, then we are going to have to setup some
Expand All @@ -203,37 +203,37 @@ pid_t arm_fork(const struct fork_s *context)
int index;
for (index = 0; index < parent->xcp.nsyscalls; index++)
{
child->cmn.xcp.syscall[index].sysreturn =
child->xcp.syscall[index].sysreturn =
parent->xcp.syscall[index].sysreturn;

/* REVISIT: This logic is *not* common. */

#if defined(CONFIG_ARCH_ARMV7A)
# ifdef CONFIG_BUILD_KERNEL

child->cmn.xcp.syscall[index].cpsr =
child->xcp.syscall[index].cpsr =
parent->xcp.syscall[index].cpsr;

# endif

#elif defined(CONFIG_ARCH_ARMV7R)
# ifdef CONFIG_BUILD_PROTECTED

child->cmn.xcp.syscall[index].cpsr =
child->xcp.syscall[index].cpsr =
parent->xcp.syscall[index].cpsr;

# endif
#elif defined(CONFIG_ARCH_ARMV6M) || defined(CONFIG_ARCH_ARMV7M) || \
defined(CONFIG_ARCH_ARMV8M)

child->cmn.xcp.syscall[index].excreturn =
child->xcp.syscall[index].excreturn =
parent->xcp.syscall[index].excreturn;
#else
# error Missing logic
#endif
}

child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls;
child->xcp.nsyscalls = parent->xcp.nsyscalls;
}
#endif

Expand Down
80 changes: 40 additions & 40 deletions arch/arm64/src/common/arm64_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void arm64_fork_fpureg_save(struct fork_s *context)
pid_t arm64_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
struct tcb_s *child;
uint64_t newsp;
uint64_t newfp;
uint64_t newtop;
Expand Down Expand Up @@ -156,8 +156,8 @@ pid_t arm64_fork(const struct fork_s *context)
* effort is overkill.
*/

newtop = (uint64_t)child->cmn.stack_base_ptr +
child->cmn.adj_stack_size;
newtop = (uint64_t)child->stack_base_ptr +
child->adj_stack_size;
newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);

Expand All @@ -183,59 +183,59 @@ pid_t arm64_fork(const struct fork_s *context)
/* make the fork stack frame */

#ifdef CONFIG_ARCH_FPU
child->cmn.xcp.fpu_regs = (void *)(newsp - FPU_CONTEXT_SIZE);
memcpy(child->cmn.xcp.fpu_regs, context->fpu, FPU_CONTEXT_SIZE);
child->xcp.fpu_regs = (void *)(newsp - FPU_CONTEXT_SIZE);
memcpy(child->xcp.fpu_regs, context->fpu, FPU_CONTEXT_SIZE);
#endif

child->cmn.xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);

child->cmn.xcp.regs[REG_X0] = 0;
child->cmn.xcp.regs[REG_X8] = context->regs[FORK_REG_X8];
child->cmn.xcp.regs[REG_X9] = context->regs[FORK_REG_X9];
child->cmn.xcp.regs[REG_X10] = context->regs[FORK_REG_X10];
child->cmn.xcp.regs[REG_X11] = context->regs[FORK_REG_X11];
child->cmn.xcp.regs[REG_X12] = context->regs[FORK_REG_X12];
child->cmn.xcp.regs[REG_X13] = context->regs[FORK_REG_X13];
child->cmn.xcp.regs[REG_X14] = context->regs[FORK_REG_X14];
child->cmn.xcp.regs[REG_X15] = context->regs[FORK_REG_X15];
child->cmn.xcp.regs[REG_X16] = context->regs[FORK_REG_X16];
child->cmn.xcp.regs[REG_X17] = context->regs[FORK_REG_X17];
child->cmn.xcp.regs[REG_X18] = context->regs[FORK_REG_X18];
child->cmn.xcp.regs[REG_X19] = context->regs[FORK_REG_X19];
child->cmn.xcp.regs[REG_X20] = context->regs[FORK_REG_X20];
child->cmn.xcp.regs[REG_X21] = context->regs[FORK_REG_X21];
child->cmn.xcp.regs[REG_X22] = context->regs[FORK_REG_X22];
child->cmn.xcp.regs[REG_X23] = context->regs[FORK_REG_X23];
child->cmn.xcp.regs[REG_X24] = context->regs[FORK_REG_X24];
child->cmn.xcp.regs[REG_X25] = context->regs[FORK_REG_X25];
child->cmn.xcp.regs[REG_X26] = context->regs[FORK_REG_X26];
child->cmn.xcp.regs[REG_X27] = context->regs[FORK_REG_X27];
child->cmn.xcp.regs[REG_X28] = context->regs[FORK_REG_X28];
child->cmn.xcp.regs[REG_FP] = newfp;
child->xcp.regs = (void *)(newsp - XCPTCONTEXT_SIZE);

child->xcp.regs[REG_X0] = 0;
child->xcp.regs[REG_X8] = context->regs[FORK_REG_X8];
child->xcp.regs[REG_X9] = context->regs[FORK_REG_X9];
child->xcp.regs[REG_X10] = context->regs[FORK_REG_X10];
child->xcp.regs[REG_X11] = context->regs[FORK_REG_X11];
child->xcp.regs[REG_X12] = context->regs[FORK_REG_X12];
child->xcp.regs[REG_X13] = context->regs[FORK_REG_X13];
child->xcp.regs[REG_X14] = context->regs[FORK_REG_X14];
child->xcp.regs[REG_X15] = context->regs[FORK_REG_X15];
child->xcp.regs[REG_X16] = context->regs[FORK_REG_X16];
child->xcp.regs[REG_X17] = context->regs[FORK_REG_X17];
child->xcp.regs[REG_X18] = context->regs[FORK_REG_X18];
child->xcp.regs[REG_X19] = context->regs[FORK_REG_X19];
child->xcp.regs[REG_X20] = context->regs[FORK_REG_X20];
child->xcp.regs[REG_X21] = context->regs[FORK_REG_X21];
child->xcp.regs[REG_X22] = context->regs[FORK_REG_X22];
child->xcp.regs[REG_X23] = context->regs[FORK_REG_X23];
child->xcp.regs[REG_X24] = context->regs[FORK_REG_X24];
child->xcp.regs[REG_X25] = context->regs[FORK_REG_X25];
child->xcp.regs[REG_X26] = context->regs[FORK_REG_X26];
child->xcp.regs[REG_X27] = context->regs[FORK_REG_X27];
child->xcp.regs[REG_X28] = context->regs[FORK_REG_X28];
child->xcp.regs[REG_FP] = newfp;

#if CONFIG_ARCH_ARM64_EXCEPTION_LEVEL == 3
child->cmn.xcp.regs[REG_SPSR] = SPSR_MODE_EL3H;
child->xcp.regs[REG_SPSR] = SPSR_MODE_EL3H;
#else
child->cmn.xcp.regs[REG_SPSR] = SPSR_MODE_EL1H;
child->xcp.regs[REG_SPSR] = SPSR_MODE_EL1H;
#endif

#ifdef CONFIG_SUPPRESS_INTERRUPTS
child->cmn.xcp.regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT);
child->xcp.regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT);
#endif /* CONFIG_SUPPRESS_INTERRUPTS */

child->cmn.xcp.regs[REG_ELR] = (uint64_t)context->lr;
child->xcp.regs[REG_ELR] = (uint64_t)context->lr;

child->cmn.xcp.regs[REG_SCTLR_EL1] = read_sysreg(sctlr_el1);
child->xcp.regs[REG_SCTLR_EL1] = read_sysreg(sctlr_el1);
#ifdef CONFIG_ARM64_MTE
child->cmn.xcp.regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT;
child->xcp.regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT;
#endif

child->cmn.xcp.regs[REG_EXE_DEPTH] = 0;
child->cmn.xcp.regs[REG_SP_ELX] = newsp - XCPTCONTEXT_SIZE;
child->xcp.regs[REG_EXE_DEPTH] = 0;
child->xcp.regs[REG_SP_ELX] = newsp - XCPTCONTEXT_SIZE;
#ifdef CONFIG_ARCH_KERNEL_STACK
child->cmn.xcp.regs[REG_SP_EL0] = (uint64_t)child->cmn.xcp.ustkptr;
child->xcp.regs[REG_SP_EL0] = (uint64_t)child->xcp.ustkptr;
#else
child->cmn.xcp.regs[REG_SP_EL0] = newsp - XCPTCONTEXT_SIZE;
child->xcp.regs[REG_SP_EL0] = newsp - XCPTCONTEXT_SIZE;
#endif

/* And, finally, start the child task. On a failure, nxtask_start_fork()
Expand Down
26 changes: 13 additions & 13 deletions arch/ceva/src/common/ceva_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pid_t ceva_fork(const uint32_t *regs)
{
#ifdef CONFIG_SCHED_WAITPID
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
struct tcb_s *child;
size_t stacksize;
const void *sp = regs + XCPTCONTEXT_REGS;
void *newsp;
Expand All @@ -114,7 +114,7 @@ pid_t ceva_fork(const uint32_t *regs)

/* Allocate the stack for the TCB */

ret = up_create_stack((struct tcb_s *)child, stacksize + argsize,
ret = up_create_stack(child, stacksize + argsize,
parent->flags & TCB_FLAG_TTYPE_MASK);
if (ret != OK)
{
Expand All @@ -125,7 +125,7 @@ pid_t ceva_fork(const uint32_t *regs)

/* Allocate the memory and copy argument from parent task */

argv = up_stack_frame((struct tcb_s *)child, argsize);
argv = up_stack_frame(child, argsize);
memcpy(argv, parent->stack_base_ptr, argsize);

/* How much of the parent's stack was utilized? The CEVA uses
Expand All @@ -146,22 +146,22 @@ pid_t ceva_fork(const uint32_t *regs)
* effort is overkill.
*/

newsp = child->cmn.stack_base_ptr - stackutil;
newsp = child->stack_base_ptr - stackutil;
memcpy(newsp, sp, stackutil);

/* Allocate the context and copy the parent snapshot */

newsp -= XCPTCONTEXT_SIZE;
memcpy(newsp, regs, XCPTCONTEXT_SIZE);
child->cmn.xcp.regs = newsp;
child->xcp.regs = newsp;

/* Was there a frame pointer in place before? */

if (regs[REG_FP] <= (uint32_t)parent->stack_base_ptr &&
regs[REG_FP] >= (uint32_t)parent->stack_base_ptr - stacksize)
{
uint32_t frameutil = (uint32_t)parent->stack_base_ptr - regs[REG_FP];
newfp = (uint32_t)child->cmn.stack_base_ptr - frameutil;
newfp = (uint32_t)child->stack_base_ptr - frameutil;
}
else
{
Expand All @@ -171,17 +171,17 @@ pid_t ceva_fork(const uint32_t *regs)
sinfo("Parent: stack base:%08x SP:%08x FP:%08x\n",
parent->stack_base_ptr, sp, regs[REG_FP]);
sinfo("Child: stack base:%08x SP:%08x FP:%08x\n",
child->cmn.stack_base_ptr, newsp, newfp);
child->stack_base_ptr, newsp, newfp);

/* Update the stack pointer, frame pointer, and the return value in A0
* should be cleared to zero, providing the indication to the newly started
* child thread.
*/

child->cmn.xcp.regs[REG_A0] = 0; /* Return value */
child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->cmn.xcp.regs[REG_PC] = regs[REG_LR]; /* Program counter */
child->cmn.xcp.regs[REG_SP] = (uint32_t)newsp; /* Stack pointer */
child->xcp.regs[REG_A0] = 0; /* Return value */
child->xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->xcp.regs[REG_PC] = regs[REG_LR]; /* Program counter */
child->xcp.regs[REG_SP] = (uint32_t)newsp; /* Stack pointer */

#ifdef CONFIG_LIB_SYSCALL
/* If we got here via a syscall, then we are going to have to setup some
Expand All @@ -193,10 +193,10 @@ pid_t ceva_fork(const uint32_t *regs)
int index;
for (index = 0; index < parent->xcp.nsyscalls; index++)
{
child->cmn.xcp.syscall[index] = parent->xcp.syscall[index];
child->xcp.syscall[index] = parent->xcp.syscall[index];
}

child->cmn.xcp.nsyscalls = parent->xcp.nsyscalls;
child->xcp.nsyscalls = parent->xcp.nsyscalls;
}
#endif

Expand Down
30 changes: 15 additions & 15 deletions arch/mips/src/mips32/mips_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
pid_t mips_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
struct tcb_s *child;
uint32_t newsp;
#ifdef CONFIG_MIPS32_FRAMEPOINTER
uint32_t newfp;
Expand Down Expand Up @@ -159,8 +159,8 @@ pid_t mips_fork(const struct fork_s *context)
* effort is overkill.
*/

newtop = (uintptr_t)child->cmn.stack_base_ptr +
child->cmn.adj_stack_size;
newtop = (uintptr_t)child->stack_base_ptr +
child->adj_stack_size;
newsp = newtop - stackutil;
memcpy((void *)newsp, (const void *)context->sp, stackutil);

Expand Down Expand Up @@ -195,22 +195,22 @@ pid_t mips_fork(const struct fork_s *context)
* indication to the newly started child thread.
*/

child->cmn.xcp.regs[REG_S0] = context->s0; /* Saved register s0 */
child->cmn.xcp.regs[REG_S1] = context->s1; /* Saved register s1 */
child->cmn.xcp.regs[REG_S2] = context->s2; /* Saved register s2 */
child->cmn.xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */
child->cmn.xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */
child->cmn.xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */
child->cmn.xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */
child->cmn.xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */
child->xcp.regs[REG_S0] = context->s0; /* Saved register s0 */
child->xcp.regs[REG_S1] = context->s1; /* Saved register s1 */
child->xcp.regs[REG_S2] = context->s2; /* Saved register s2 */
child->xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */
child->xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */
child->xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */
child->xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */
child->xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */
#ifdef CONFIG_MIPS32_FRAMEPOINTER
child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */
child->xcp.regs[REG_FP] = newfp; /* Frame pointer */
#else
child->cmn.xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */
child->xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */
#endif
child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */
child->xcp.regs[REG_SP] = newsp; /* Stack pointer */
#ifdef MIPS32_SAVE_GP
child->cmn.xcp.regs[REG_GP] = context->gp; /* Global pointer */
child->xcp.regs[REG_GP] = context->gp; /* Global pointer */
#endif

/* And, finally, start the child task. On a failure, nxtask_start_fork()
Expand Down
Loading
Loading