diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-30 00:57:33 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-30 00:57:33 +0200 |
| commit | 44a73ecab6e91519627786a5101cd4f1a2f2b0d7 (patch) | |
| tree | f5c811050a4d5ee832f5883c4d0c27efddd60817 /arch | |
| parent | 5976ad390a15726c3ddfacf8c8b282c8350f9554 (diff) | |
| download | kmi-44a73ecab6e91519627786a5101cd4f1a2f2b0d7.tar.gz kmi-44a73ecab6e91519627786a5101cd4f1a2f2b0d7.zip | |
most of the way to passing tests
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 19 | ||||
| -rw-r--r-- | arch/riscv64/kernel/except.c | 21 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 14 | ||||
| -rw-r--r-- | arch/riscv64/kernel/smp.c | 1 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 17 |
5 files changed, 66 insertions, 6 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S index 0bc999e..f894e0d 100644 --- a/arch/riscv64/kernel/entry.S +++ b/arch/riscv64/kernel/entry.S @@ -62,6 +62,7 @@ handle_trap: bnez tp, continue_trap /* the trap came from the kernel, should never happen so just panic * and abort or whatever */ + csrw CSR_SSCRATCH, x0 csrr a0, CSR_SEPC csrr a1, CSR_STVAL csrr a2, CSR_SCAUSE @@ -92,8 +93,16 @@ continue_trap: save_caller mv a0, s10 + /* get actual kernel stack into sp */ + mv sp, tp call riscv_handle_interrupt + lr sp, offsetof_regs(tp) + addi sp, sp, -sizeof_registers + /* set execution continuation */ + lr s10, offsetof_exec(tp) + csrw CSR_SEPC, s10 + j _load_context handle_exception: @@ -108,7 +117,14 @@ handle_exception: csrr a0, CSR_SEPC csrr a1, CSR_STVAL csrr a2, CSR_SCAUSE - call unhandled_panic + mv sp, tp + call riscv_handle_exception + + lr sp, offsetof_regs(tp) + addi sp, sp, -sizeof_registers + /* set execution continuation */ + lr s10, offsetof_exec(tp) + csrw CSR_SEPC, s10 j _load_context @@ -129,6 +145,7 @@ fast_dispatch: csrr s10, CSR_SEPC sr s10, offsetof_exec(tp) /* jump to C */ + mv sp, tp call dispatch /* if we had a thread switch, load kernel stack of current thread and * restore its context */ diff --git a/arch/riscv64/kernel/except.c b/arch/riscv64/kernel/except.c new file mode 100644 index 0000000..e46b584 --- /dev/null +++ b/arch/riscv64/kernel/except.c @@ -0,0 +1,21 @@ +#include <kmi/types.h> +#include <kmi/panic.h> +#include <kmi/vmem.h> +#include <kmi/bkl.h> + +void riscv_handle_exception(void *pc, void *addr, unsigned long id) +{ + switch (id) { + case 12: + case 13: + case 15: { + bkl_lock(); + handle_pagefault((vm_t)addr); + bkl_unlock(); + break; + } + + default: + unhandled_panic(pc, addr, id); + } +} diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index f012b20..3ae2e15 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -81,7 +81,7 @@ void set_thread(struct tcb *t) struct riscv_regs *r = (struct riscv_regs *)(t->regs) - 1; /* insert important values into register slots */ - r->sp = (long)t->thread_stack + t->thread_stack_size; + r->sp = (long)t->rpc_stack - BASE_PAGE_SIZE; } void set_stack(struct tcb *t, vm_t s) @@ -99,9 +99,15 @@ vm_t get_stack(struct tcb *t) void copy_regs(struct tcb *d, struct tcb *s) { - struct riscv_regs *rd = (struct riscv_regs *)(d->regs) - 1; - struct riscv_regs *rs = (struct riscv_regs *)(s->regs) - 1; - *rd = *rs; + struct riscv_regs rs = *((struct riscv_regs *)(s->regs) - 1); + /* again, not a fan of this, I guess we could query the underlying + * physical page? Would that be any faster? */ + use_vmem(d->rpc.vmem); + + struct riscv_regs *rd = ((struct riscv_regs *)(d->regs) - 1); + *rd = rs; + + use_vmem(s->rpc.vmem); } void adjust_ipi(struct tcb *t) diff --git a/arch/riscv64/kernel/smp.c b/arch/riscv64/kernel/smp.c index acb5f04..5e30fee 100644 --- a/arch/riscv64/kernel/smp.c +++ b/arch/riscv64/kernel/smp.c @@ -139,7 +139,6 @@ __noreturn void core_bringup(long hartid) struct tcb *t = create_thread(init); assert(t); - alloc_stack(t); /* init is special in that all threads jump to the entrypoint of the * program */ t->exec = init->exec; diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index cf1391e..5a44f53 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -563,6 +563,23 @@ size_t max_rpc_size() return SZ_512K; } +void copy_rpc_stack(struct tcb *t, struct tcb *c) +{ + /* this is of terrible, copying 2MiB for every fork, not + * great. TODO: use the direct pointer to the rpc stack element? */ + for (size_t i = 0; i < rpc_pages; ++i) { + pm_t p1, p2; + stat_t ok1 = stat_vpage(t->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i, + &p1, NULL, NULL); + + stat_t ok2 = stat_vpage(c->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i, + &p2, NULL, NULL); + + assert(ok1 == OK && ok2 == OK); + memcpy((void *)p2, (void *)p1, BASE_PAGE_SIZE); + } +} + stat_t setup_rpc_stack(struct tcb *t) { /* by default rpc stack is marked inaccessible to generate segfaults on |
