diff options
Diffstat (limited to 'arch/riscv64/kernel')
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 35 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 2 |
2 files changed, 25 insertions, 12 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S index 1bd6046..8ff642a 100644 --- a/arch/riscv64/kernel/entry.S +++ b/arch/riscv64/kernel/entry.S @@ -86,25 +86,42 @@ handle_syscall: /* add 4 (size of ecall) to EPC to avoid running the same instruction * twice */ csrr s0, CSR_SEPC - addi s0, s0, 4 + addi s0, s0, 4 csrw CSR_SEPC, s0 + /* 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 + mv a6, a5 + mv a5, a4 + mv a4, a3 + mv a3, a2 + mv a2, a1 + mv a1, a0 + mv a0, sp jal syscall_dispatch + /* move structure from stack into registers. */ + lr a0, offsetof_s(sp) + lr a1, offsetof_ar0(sp) + lr a2, offsetof_ar1(sp) + lr a3, offsetof_ar2(sp) + lr a4, offsetof_ar3(sp) + lr a5, offsetof_ar4(sp) + addi sp, sp, sizeof_sys_ret /* if we had a thread switch, load kernel stack of current thread and * restore its context */ - /* TODO: is a whole function call necessary? */ - mv s0, a0 - mv s1, a1 /* get associated kernel stack */ mv sp, tp addi sp, sp, -sizeof_registers /* restore system call result */ - mv a0, s0 - mv a1, s1 j restore_noreturn restore_all: lr a0, offsetof_a0(sp) lr a1, offsetof_a1(sp) + lr a2, offsetof_a2(sp) + lr a3, offsetof_a3(sp) + lr a4, offsetof_a4(sp) + lr a5, offsetof_a5(sp) restore_noreturn: /* restore registers besides possible return value, assume instruction @@ -117,11 +134,7 @@ restore_noreturn: lr t0, offsetof_t0(sp) lr t1, offsetof_t1(sp) lr t2, offsetof_t2(sp) - /* a0 and a1 should not be restored when coming from a syscall */ - lr a2, offsetof_a2(sp) - lr a3, offsetof_a3(sp) - lr a4, offsetof_a4(sp) - lr a5, offsetof_a5(sp) + /* a0 - a5 should not be restored when coming from a syscall */ lr a6, offsetof_a6(sp) lr s0, offsetof_s0(sp) lr s1, offsetof_s1(sp) diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 1abc58d..a029f6a 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -306,7 +306,7 @@ vm_t setup_kernel_io(struct vmem *b, vm_t paddr) { pm_t top_page = paddr / TOP_PAGE_SIZE; b->leaf[IO_PAGE] = (struct vmem *)to_pte(top_page * TOP_PAGE_SIZE, - VM_V | VM_R | VM_W); + VM_V | VM_R | VM_W); return -TOP_PAGE_SIZE + paddr - (top_page * TOP_PAGE_SIZE); } #endif |
