aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-10-21 16:06:00 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-10-21 16:06:00 +0300
commita06dbb8a63d825ebb1ad65372ce1ce1f572891bc (patch)
tree342f74db0777a76eed64830ded71db16399e983d
parent00d3ae26dfd7c91c0817e71d71636982680d0b28 (diff)
downloadkmi-a06dbb8a63d825ebb1ad65372ce1ce1f572891bc.tar.gz
kmi-a06dbb8a63d825ebb1ad65372ce1ce1f572891bc.zip
initial spawn implementation
-rw-r--r--arch/riscv64/kernel/entry.S6
-rw-r--r--arch/riscv64/kernel/proc.c7
-rw-r--r--common/proc.c2
-rw-r--r--common/tcb.c5
-rw-r--r--common/uapi/proc.c6
-rw-r--r--include/apos/tcb.h11
-rw-r--r--include/arch/proc.h8
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.