| 84 | ****************************************************************************/ |
| 85 | |
| 86 | pid_t ceva_fork(const uint32_t *regs) |
| 87 | { |
| 88 | #ifdef CONFIG_SCHED_WAITPID |
| 89 | struct tcb_s *parent = this_task(); |
| 90 | struct tcb_s *child; |
| 91 | size_t stacksize; |
| 92 | const void *sp = regs + XCPTCONTEXT_REGS; |
| 93 | void *newsp; |
| 94 | uint32_t newfp; |
| 95 | uint32_t stackutil; |
| 96 | size_t argsize; |
| 97 | void *argv; |
| 98 | int ret; |
| 99 | |
| 100 | /* Allocate and initialize a TCB for the child task. */ |
| 101 | |
| 102 | child = nxtask_setup_fork(parent->start, &argsize); |
| 103 | if (!child) |
| 104 | { |
| 105 | serr("ERROR: nxtask_setup_fork failed\n"); |
| 106 | return (pid_t)ERROR; |
| 107 | } |
| 108 | |
| 109 | sinfo("TCBs: Parent=%p Child=%p\n", parent, child); |
| 110 | |
| 111 | /* Get the size of the parent task's stack. */ |
| 112 | |
| 113 | stacksize = parent->adj_stack_size; |
| 114 | |
| 115 | /* Allocate the stack for the TCB */ |
| 116 | |
| 117 | ret = up_create_stack(child, stacksize + argsize, |
| 118 | parent->flags & TCB_FLAG_TTYPE_MASK); |
| 119 | if (ret != OK) |
| 120 | { |
| 121 | serr("ERROR: up_create_stack failed: %d\n", ret); |
| 122 | nxtask_abort_fork(child, -ret); |
| 123 | return (pid_t)ERROR; |
| 124 | } |
| 125 | |
| 126 | /* Allocate the memory and copy argument from parent task */ |
| 127 | |
| 128 | argv = up_stack_frame(child, argsize); |
| 129 | memcpy(argv, parent->stack_base_ptr, argsize); |
| 130 | |
| 131 | /* How much of the parent's stack was utilized? The CEVA uses |
| 132 | * a push-down stack so that the current stack pointer should |
| 133 | * be lower than the initial, adjusted stack pointer. The |
| 134 | * stack usage should be the difference between those two. |
| 135 | */ |
| 136 | |
| 137 | DEBUGASSERT(parent->stack_base_ptr >= sp); |
| 138 | stackutil = parent->stack_base_ptr - sp; |
| 139 | |
| 140 | sinfo("Parent: stacksize:%d stackutil:%d\n", stacksize, stackutil); |
| 141 | |
| 142 | /* Make some feeble effort to preserve the stack contents. This is |
| 143 | * feeble because the stack surely contains invalid pointers and other |
nothing calls this directly
no test coverage detected