diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-09-15 19:21:14 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-09-15 19:46:07 +0300 |
| commit | a717296a2036cede5fccfff544513043a984d614 (patch) | |
| tree | 68f75a23adc298628fb9cab41fd47402a99dd19d /arch/riscv64 | |
| parent | 619725a5f2f5272f9cbb547ed95c87312c2765a9 (diff) | |
| download | kmi-a717296a2036cede5fccfff544513043a984d614.tar.gz kmi-a717296a2036cede5fccfff544513043a984d614.zip | |
change syscalls to take 5 params and return 6
+ In total, a syscall is built up of 6 values, with the first being the
syscall number. Symmetrically, the first value is now a status and the
following five values return "values". This allows us to cram in more
info into the ipc_* functions. The performance difference is
absolutely minimal, at least from my testing in qemu.
Diffstat (limited to 'arch/riscv64')
| -rw-r--r-- | arch/riscv64/asm/asm-offsets.c | 9 | ||||
| -rw-r--r-- | arch/riscv64/asm/source.mk | 2 | ||||
| -rwxr-xr-x | arch/riscv64/conf/init | bin | 2136 -> 2144 bytes | |||
| -rw-r--r-- | arch/riscv64/conf/init.c | 20 | ||||
| -rw-r--r-- | arch/riscv64/conf/initrd | bin | 2560 -> 2560 bytes | |||
| -rw-r--r-- | arch/riscv64/init/init.c | 3 | ||||
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 35 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 2 |
8 files changed, 49 insertions, 22 deletions
diff --git a/arch/riscv64/asm/asm-offsets.c b/arch/riscv64/asm/asm-offsets.c index 8852d8f..3619765 100644 --- a/arch/riscv64/asm/asm-offsets.c +++ b/arch/riscv64/asm/asm-offsets.c @@ -8,6 +8,7 @@ */ #include <apos/utils.h> +#include <apos/uapi.h> #include "../kernel/regs.h" /** @@ -74,4 +75,12 @@ void asm_offsets() OFFSETOF(t5, struct riscv_regs); OFFSETOF(t6, struct riscv_regs); SIZEOF(registers, struct riscv_regs); + + OFFSETOF(s, struct sys_ret); + OFFSETOF(ar0, struct sys_ret); + OFFSETOF(ar1, struct sys_ret); + OFFSETOF(ar2, struct sys_ret); + OFFSETOF(ar3, struct sys_ret); + OFFSETOF(ar4, struct sys_ret); + SIZEOF(sys_ret, struct sys_ret); } diff --git a/arch/riscv64/asm/source.mk b/arch/riscv64/asm/source.mk index 9b463b7..87bcf24 100644 --- a/arch/riscv64/asm/source.mk +++ b/arch/riscv64/asm/source.mk @@ -9,7 +9,7 @@ $(OFFSET_HEADER): $(OFFSET_SOURCE) echo " * @file asm-offsets.h" >> $(OFFSET_HEADER) echo " * This comment is to shut up warnings." >> $(OFFSET_HEADER) echo " */" >> $(OFFSET_HEADER) - $(COMPILER) $(INCLUDE_FLAGS) -S $(OFFSET_SOURCE) -o - |\ + $(COMPILER) $(CFLAGS) $(INCLUDE_FLAGS) -S $(OFFSET_SOURCE) -o - |\ awk '($$1 == "#->") { print "#define " $$2 " " $$3 }' >> $(OFFSET_HEADER) echo "#endif /* APOS_ASM_OFFSETS_H */" >> $(OFFSET_HEADER) diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init Binary files differindex d9a585d..b75076f 100755 --- a/arch/riscv64/conf/init +++ b/arch/riscv64/conf/init diff --git a/arch/riscv64/conf/init.c b/arch/riscv64/conf/init.c index 4bd6a4e..feb5177 100644 --- a/arch/riscv64/conf/init.c +++ b/arch/riscv64/conf/init.c @@ -9,30 +9,33 @@ #include <stdint.h> #include "../../../include/apos/syscalls.h" +#define ecall() do { asm ("ecall" : : : "a0", "a1", "a2", "a3", "a4", "a5"); \ +} while (0) static void sys_noop() { long register a0 asm ("a0") = SYS_NOOP; - asm ("ecall" : : : "a0", "a1"); + ecall(); } static void sys_putch(char c) { long register a0 asm ("a0") = SYS_PUTCH; long register a1 asm ("a1") = c; - asm ("ecall" : : : "a0", "a1"); + ecall(); } static uint64_t sys_timebase() { long register a0 asm ("a0") = SYS_TIMEBASE; long register a1 asm ("a1") = 0; - asm ("ecall" : : : "a0", "a1"); + long register a2 asm ("a2") = 0; + ecall(); #if defined(_LP64) return a1; #else - uint64_t t = a0; + uint64_t t = a1; t <<= 32; - return t + a1; + return t + a2; #endif } @@ -40,13 +43,14 @@ static uint64_t sys_ticks() { long register a0 asm ("a0") = SYS_TICKS; long register a1 asm ("a1") = 0; - asm ("ecall" : : : "a0", "a1"); + long register a2 asm ("a2") = 0; + ecall(); #if defined(_LP64) return a1; #else - uint64_t t = a0; + uint64_t t = a1; t <<= 32; - return t + a1; + return t + a2; #endif } diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd Binary files differindex f05e035..3af4d2e 100644 --- a/arch/riscv64/conf/initrd +++ b/arch/riscv64/conf/initrd diff --git a/arch/riscv64/init/init.c b/arch/riscv64/init/init.c index 0680296..498023a 100644 --- a/arch/riscv64/init/init.c +++ b/arch/riscv64/init/init.c @@ -44,7 +44,8 @@ static void init_bootmem() /* direct mapping (temp) */ for (size_t i = 0; i < CSTACK_PAGE; ++i) - root_branch->leaf[i] = (struct vmem *)to_pte(TOP_PAGE_SIZE * i, flags); + root_branch->leaf[i] = (struct vmem *)to_pte(TOP_PAGE_SIZE * i, + flags); /* kernel (also sort of direct mapping) */ flags |= VM_G; 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 |
