diff options
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 6 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 7 | ||||
| -rw-r--r-- | common/proc.c | 2 | ||||
| -rw-r--r-- | common/tcb.c | 5 | ||||
| -rw-r--r-- | common/uapi/proc.c | 6 | ||||
| -rw-r--r-- | include/apos/tcb.h | 11 | ||||
| -rw-r--r-- | include/arch/proc.h | 8 |
7 files changed, 28 insertions, 17 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S index 8ff642a..db662bb 100644 --- a/arch/riscv64/kernel/entry.S +++ b/arch/riscv64/kernel/entry.S @@ -87,7 +87,8 @@ handle_syscall: * twice */ csrr s0, CSR_SEPC addi s0, s0, 4 - csrw CSR_SEPC, s0 + /* store execution continuation point */ + sr s0, 0(tp) /* allocate space for sys_ret structure on stack and shift argument * registers down one to make room for the pointer to this structure */ addi sp, sp, -sizeof_sys_ret @@ -112,6 +113,9 @@ handle_syscall: /* get associated kernel stack */ mv sp, tp addi sp, sp, -sizeof_registers + /* set execution continuation */ + lr s0, 0(tp) + csrw CSR_SEPC, s0 /* restore system call result */ j restore_noreturn diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index ab833b2..f85f597 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -15,6 +15,7 @@ stat_t run_init(struct tcb *t, void *fdt) { /** \todo actually map fdt into the target address space */ csr_write(CSR_SSCRATCH, t); + csr_write(CSR_SEPC, t->exec); __asm__ volatile ("mv sp, %0\n" : : "r" (t->thread_stack_top) : "memory"); __asm__ volatile ("mv a0, %0\n" : : "r" (fdt) : ); __asm__ volatile ("sret\n" ::: "memory"); @@ -22,12 +23,6 @@ stat_t run_init(struct tcb *t, void *fdt) return ERR_ADDR; } -stat_t set_return(vm_t v) -{ - csr_write(CSR_SEPC, v); - return OK; -} - stat_t set_ipc(struct tcb *t, id_t pid, id_t tid) { struct riscv_regs *r = (struct riscv_regs *)(--t); diff --git a/common/proc.c b/common/proc.c index b2caa54..6a3bedf 100644 --- a/common/proc.c +++ b/common/proc.c @@ -23,7 +23,7 @@ stat_t prepare_proc(struct tcb *t, vm_t bin, vm_t interp) alloc_stacks(t); set_thread(t); - set_return(entry); + set_return(t, entry); return OK; } diff --git a/common/tcb.c b/common/tcb.c index 8ff86ab..f618cd6 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -342,3 +342,8 @@ stat_t clone_proc_maps(struct tcb *r) return OK; } + +void set_return(struct tcb *t, vm_t v) +{ + t->exec = v; +} diff --git a/common/uapi/proc.c b/common/uapi/proc.c index d1d2bd7..a668246 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -91,7 +91,11 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ */ SYSCALL_DEFINE2(spawn)(sys_arg_t bin, sys_arg_t interp) { - /* @todo implement */ + struct tcb *t = create_proc(NULL); + if (!t) + return (struct sys_ret){ERR_OOMEM, 0, 0, 0, 0, 0}; + + return (struct sys_ret){prepare_proc(t, bin, interp), t->pid, 0, 0, 0, 0}; } /** diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 63bf037..a31e308 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -75,6 +75,9 @@ enum tcb_notify { /** Thread control block. Main way to handle threads. */ struct tcb { + /** Execution continuation point. Important that it is first. */ + vm_t exec; + /** Arch-specific data. */ struct arch_tcbd tcbd; @@ -319,4 +322,12 @@ stat_t clone_rpc_maps(struct tcb *r); */ stat_t alloc_stacks(struct tcb *t); +/** + * Set address to jump to when returning to userspace. + * + * @param t Thread return address to set. + * @param r Address to jump to. + */ +void set_return(struct tcb *t, vm_t r); + #endif /* APOS_TCB_H */ diff --git a/include/arch/proc.h b/include/arch/proc.h index dd739bf..d5367f6 100644 --- a/include/arch/proc.h +++ b/include/arch/proc.h @@ -16,14 +16,6 @@ #endif /** - * Set address to jump to when returning to userspace. - * - * @param r Address to jump to. - * @return \ref OK. - */ -stat_t set_return(vm_t r); - -/** * Attach IPC data to load into argument registers when returning to userspace. * * @param t Thread that will run after return. |
