From a717296a2036cede5fccfff544513043a984d614 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Thu, 15 Sep 2022 19:21:14 +0300 Subject: 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. --- arch/riscv64/asm/asm-offsets.c | 9 +++ arch/riscv64/asm/source.mk | 2 +- arch/riscv64/conf/init | Bin 2136 -> 2144 bytes arch/riscv64/conf/init.c | 20 +++--- arch/riscv64/conf/initrd | Bin 2560 -> 2560 bytes arch/riscv64/init/init.c | 3 +- arch/riscv64/kernel/entry.S | 35 +++++++--- arch/riscv64/kernel/vmem.c | 2 +- common/uapi/conf.c | 8 +-- common/uapi/dispatch.c | 18 ++--- common/uapi/ipc.c | 42 ++++++----- common/uapi/mem.c | 24 +++---- common/uapi/proc.c | 34 ++++++--- common/uapi/timers.c | 26 +++---- include/apos/syscalls.h | 4 +- include/apos/tcb.h | 3 + include/apos/uapi.h | 154 ++++++++++++++++++++++++++++++++--------- include/arch/types.h | 2 +- include/arch/vmem.h | 2 + 19 files changed, 263 insertions(+), 125 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 +#include #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 index d9a585d..b75076f 100755 Binary files a/arch/riscv64/conf/init and b/arch/riscv64/conf/init differ 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 #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 index f05e035..3af4d2e 100644 Binary files a/arch/riscv64/conf/initrd and b/arch/riscv64/conf/initrd differ 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 diff --git a/common/uapi/conf.c b/common/uapi/conf.c index 470b81e..bf4b42c 100644 --- a/common/uapi/conf.c +++ b/common/uapi/conf.c @@ -25,7 +25,7 @@ size_t __call_stack_size = SZ_2M; */ SYSCALL_DEFINE1(conf_get)(sys_arg_t param) { - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -43,7 +43,7 @@ SYSCALL_DEFINE2(conf_set)(sys_arg_t param, sys_arg_t val) UNUSED(val); /* no parameters supported atm */ - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -59,8 +59,8 @@ SYSCALL_DEFINE1(poweroff)(sys_arg_t type) case SHUTDOWN: case COLD_REBOOT: case WARM_REBOOT: - return (struct sys_ret){ OK, poweroff(type) }; + return (struct sys_ret){ OK, poweroff(type), 0, 0, 0, 0 }; }; - return (struct sys_ret){ ERR_INVAL, 0 }; + return (struct sys_ret){ ERR_INVAL, 0, 0, 0, 0, 0 }; } diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index fe86df0..f0f6ae0 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -41,7 +41,6 @@ static const sys_t syscall_table[] = { [SYS_CREATE] = sys_create, [SYS_FORK] = sys_fork, [SYS_EXEC] = sys_exec, - [SYS_SIGNAL] = sys_signal, [SYS_SWAP] = sys_swap, /* conf */ @@ -57,7 +56,7 @@ static const sys_t syscall_table[] = { */ SYSCALL_DEFINE0(noop)(){ info("sys_noop\n"); - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -68,35 +67,36 @@ SYSCALL_DEFINE0(noop)(){ */ SYSCALL_DEFINE1(putch)(sys_arg_t a){ const char c[2] = {a, 0}; + MAYBE_UNUSED(c); dbg((const char *)&c); - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } struct sys_ret syscall_dispatch(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, - sys_arg_t c, sys_arg_t d) + sys_arg_t c, sys_arg_t d, sys_arg_t e) { struct tcb *t = cur_tcb(); size_t sc = syscall; if (sc >= ARRAY_SIZE(syscall_table)) { error("Syscall %zu outside allowed range [0 - %zu]\n", sc, - ARRAY_SIZE(syscall_table)); - return (struct sys_ret){ ERR_INVAL, 0 }; + ARRAY_SIZE(syscall_table)); + return (struct sys_ret){ ERR_INVAL, 0, 0, 0, 0, 0 }; } sys_t call = syscall_table[sc]; if (!call) { error("Syscall %zu not legitimate value\n", sc); - return (struct sys_ret){ ERR_INVAL, 0 }; + return (struct sys_ret){ ERR_INVAL, 0, 0, 0, 0, 0 }; } - struct sys_ret r = call(a, b, c, d); + struct sys_ret r = call(a, b, c, d, e); if (check_canary(t)) { bug("Syscall %zu overwrote stack canary\n", syscall); /** @todo should probably halt, as the system is likely in an * unstable state. */ - return (struct sys_ret){ ERR_INT, 0 }; + return (struct sys_ret){ ERR_INT, 0, 0, 0, 0, 0 }; } return r; diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c index 4cdec0c..ecfced5 100644 --- a/common/uapi/ipc.c +++ b/common/uapi/ipc.c @@ -13,17 +13,12 @@ * IPC server notification syscall handler. * * @param callback Address of server callback. - * @return \ref ERR_EXT and \c 0 if process already is a server, - * \ref OK and \c 0 otherwise. + * @return \ref OK and \c 0. */ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback) { - struct tcb *r = cur_tcb(); - if (r->callback) /* server can't be reinitialized */ - return (struct sys_ret){ ERR_EXT, 0 }; - - r->callback = callback; - return (struct sys_ret){ OK, 0 }; + cur_tcb()->callback = callback; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -32,29 +27,37 @@ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback) * @param pid Process to request RPC to. * @param d0 IPC argument 0. * @param d1 IPC argument 1. + * @param d2 IPC argument 2. + * @param d3 IPC argument 3. * @return \c d0 and \c d1. */ -SYSCALL_DEFINE3(ipc_req)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) +SYSCALL_DEFINE5(ipc_req)(sys_arg_t pid, + sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, sys_arg_t d3) { + struct tcb *t = cur_tcb(); struct tcb *r = get_tcb(pid); /** \todo something like jump_to_callback(t) */ /* remember difference between ipc_req and ipc_fwd! */ - return (struct sys_ret){ d0, d1 }; + return (struct sys_ret){ OK, t->tid, d0, d1, d2, d3 }; } /** * IPC forwarding syscall handler. * - * @param pid Process to rquest RPC to. + * @param pid Process to request RPC to. * @param d0 IPC argument 0. * @param d1 IPC argument 1. - * @return \c d0 and \c d1. + * @param d2 IPC argument 2. + * @param d3 IPC argument 3. + * @return \p d0 and \p d1. */ -SYSCALL_DEFINE3(ipc_fwd)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) +SYSCALL_DEFINE5(ipc_fwd)(sys_arg_t pid, + sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, sys_arg_t d3) { - struct tcb *t = get_tcb(pid); + struct tcb *t = cur_tcb(); + struct tcb *r = get_tcb(pid); /* ditto */ - return (struct sys_ret){ d0, d1 }; + return (struct sys_ret){ OK, t->tid, d0, d1, d2, d3 }; } /** @@ -62,11 +65,14 @@ SYSCALL_DEFINE3(ipc_fwd)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) * * @param d0 IPC return value 0. * @param d1 IPC return value 1. + * @param d2 IPC return value 2. + * @param d3 IPC return value 3. * @return \c d0 and \c d1. */ -SYSCALL_DEFINE2(ipc_resp)(sys_arg_t d0, sys_arg_t d1) +SYSCALL_DEFINE4(ipc_resp)(sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, + sys_arg_t d3) { - struct tcb *r = cur_tcb(); + struct tcb *t = cur_tcb(); /* something like return_from_callback(t, r) */ - return (struct sys_ret){ d0, d1 }; + return (struct sys_ret){ OK, t->tid, d0, d1, d2, d3 }; } diff --git a/common/uapi/mem.c b/common/uapi/mem.c index eca3da2..8da0f15 100644 --- a/common/uapi/mem.c +++ b/common/uapi/mem.c @@ -26,9 +26,9 @@ SYSCALL_DEFINE2(req_mem)(sys_arg_t size, sys_arg_t flags) struct tcb *r = cur_proc(); vm_t start = 0; if ((start = alloc_uvmem(r, size, flags))) - return (struct sys_ret){ ERR_OOMEM, NULL }; + return (struct sys_ret){ ERR_OOMEM, NULL, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, start }; + return (struct sys_ret){ OK, start, 0, 0, 0, 0 }; } /** @@ -45,9 +45,9 @@ SYSCALL_DEFINE3(req_fixmem)(sys_arg_t fixed, sys_arg_t size, sys_arg_t flags) struct tcb *r = cur_proc(); vm_t start = 0; if ((start = alloc_fixed_uvmem(r, fixed, size, flags))) - return (struct sys_ret){ ERR_OOMEM, NULL }; + return (struct sys_ret){ ERR_OOMEM, NULL, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, start }; + return (struct sys_ret){ OK, start, 0, 0, 0, 0 }; } /** @@ -68,9 +68,9 @@ SYSCALL_DEFINE1(free_mem)(sys_arg_t start) status = free_devmem(r, vm_start); if (status) - return (struct sys_ret){ ERR_NF, 0 }; + return (struct sys_ret){ ERR_NF, 0, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -92,9 +92,9 @@ SYSCALL_DEFINE3(req_pmem)(sys_arg_t paddr, sys_arg_t size, sys_arg_t flags) struct tcb *r = cur_proc(); vm_t start = 0; if ((start = alloc_devmem(r, paddr, size, flags))) - return (struct sys_ret){ ERR_OOMEM, NULL }; + return (struct sys_ret){ ERR_OOMEM, NULL, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, start }; + return (struct sys_ret){ OK, start, 0, 0, 0, 0 }; } /** @@ -111,9 +111,9 @@ SYSCALL_DEFINE2(req_sharedmem)(sys_arg_t size, sys_arg_t flags) struct tcb *t = cur_proc(); vm_t start = 0; if ((start = alloc_shared_uvmem(t, size, flags))) - return (struct sys_ret){ ERR_OOMEM, NULL }; + return (struct sys_ret){ ERR_OOMEM, NULL, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, start }; + return (struct sys_ret){ OK, start, 0, 0, 0, 0 }; } /** @@ -131,9 +131,9 @@ SYSCALL_DEFINE3(ref_sharedmem)(sys_arg_t tid, sys_arg_t va, sys_arg_t flags) struct tcb *t2 = get_tcb(tid); vm_t start = 0; if ((start = ref_shared_uvmem(t1, t2, va, flags))) - return (struct sys_ret){ ERR_OOMEM, NULL }; + return (struct sys_ret){ ERR_OOMEM, NULL, 0, 0, 0, 0 }; - return (struct sys_ret){ OK, start }; + return (struct sys_ret){ OK, start, 0, 0, 0, 0 }; } /** \todo add some way to specify who gets to access the shared memory? */ diff --git a/common/uapi/proc.c b/common/uapi/proc.c index 60617b4..ba9fb76 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -17,10 +17,13 @@ * * \todo Implement. * + * @param func Function to jump to at thread creation. + * @param arg Argument to pass to the function. + * * @return \ref OK and 0. */ -SYSCALL_DEFINE0(create)(){ - return (struct sys_ret){ OK, 0 }; +SYSCALL_DEFINE2(create)(sys_arg_t func, sys_arg_t arg){ + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -39,7 +42,7 @@ SYSCALL_DEFINE0(create)(){ * @return \ref OK and 0. */ SYSCALL_DEFINE0(fork)(){ - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -56,7 +59,7 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ /* mark binary to be kept */ struct mem_region *b = find_used_region(&r->sp_r, bin); if (!b) - return (struct sys_ret){ERR_INVAL, 0}; + return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0}; set_bit(b->flags, MR_KEEP); struct mem_region *i = 0; @@ -64,7 +67,7 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ /* mark interpreter to be kept */ i = find_used_region(&r->sp_r, interp); if (!i) - return (struct sys_ret){ERR_INVAL, 1}; + return (struct sys_ret){ERR_INVAL, 1, 0, 0, 0, 0}; set_bit(i->flags, MR_KEEP); } @@ -76,7 +79,19 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ if (interp) clear_bit(b->flags, MR_KEEP); - return (struct sys_ret){ prepare_proc(r, bin, interp), 0 }; + return (struct sys_ret){ prepare_proc(r, bin, interp), 0, 0, 0, 0, 0 }; +} + +/** + * Kill syscall handler. + * + * \todo Implement. + * + * @return No? + */ +SYSCALL_DEFINE0(kill)() +{ + return (struct sys_ret){ OK, 0, 0, 0, 0, 0}; } /** @@ -86,10 +101,11 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ * * @param tid Thread ID to signal. * @param signal Signal to send to \c tid. + * @param swap Whether to immediately swap to thread. * @return \ref OK and 0. */ -SYSCALL_DEFINE2(signal)(sys_arg_t tid, sys_arg_t signal){ - return (struct sys_ret){ OK, 0 }; +SYSCALL_DEFINE3(signal)(sys_arg_t tid, sys_arg_t signal, sys_arg_t swap){ + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } /** @@ -106,5 +122,5 @@ SYSCALL_DEFINE1(swap)(sys_arg_t tid){ /** \todo switch to process */ /** \todo should switch return the registers of the new thread that would * be used for message passing? */ - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } diff --git a/common/uapi/timers.c b/common/uapi/timers.c index d6c6286..5c2f58f 100644 --- a/common/uapi/timers.c +++ b/common/uapi/timers.c @@ -35,16 +35,16 @@ static ticks_t scaled_ticks(sys_arg_t ticks, sys_arg_t mult) /** * Timebase syscall handler. * - * @return \ref OK and resolution of system timer in Hz if on 64bit system, - * otherwise high bits of resolutio in first register and low bits in second. + * @return \ref OK and timebase in second argument if 64bit, otherwise high 32 + * bits of timebase in second argument and low 32 bits in third argument. */ SYSCALL_DEFINE0(timebase)() { ticks_t t = secs_to_ticks(1); #if defined(_LP64) - return (struct sys_ret){ OK, t }; + return (struct sys_ret){ OK, t, 0, 0, 0, 0 }; #else - return (struct sys_ret){ t >> 32, t }; + return (struct sys_ret){ OK, t >> 32, t}; #endif } @@ -56,17 +56,15 @@ SYSCALL_DEFINE0(timebase)() * completeness sake. * * @return \ref OK and the current ticks when on 64bit systems, otherwise high - * 32 bits of ticks in first register and low 32 bits in second. - * \todo 32bit systems are arguably a bit unsafe with this method, should I - * instead provide ticks_low and ticks_high or something? + * 32 bits of ticks in second argument and low 32 bits in third. */ SYSCALL_DEFINE0(ticks)() { ticks_t t = current_ticks(); #if defined(_LP64) - return (struct sys_ret){ OK, t }; + return (struct sys_ret){ OK, t, 0, 0, 0, 0}; #else - return (struct sys_ret){ t >> 32, t }; + return (struct sys_ret){ OK, t >> 32, t, 0, 0, 0 }; #endif } @@ -86,7 +84,8 @@ SYSCALL_DEFINE2(req_rel_timer)(sys_arg_t ticks, sys_arg_t mult) return (struct sys_ret){ OK, new_rel_timer(cur_tcb()->tid, - scaled_ticks(ticks, mult)) + scaled_ticks(ticks, mult)), + 0, 0, 0, 0 }; } @@ -103,7 +102,8 @@ SYSCALL_DEFINE2(req_abs_timer)(sys_arg_t ticks, sys_arg_t mult) return (struct sys_ret){ OK, new_abs_timer(cur_tcb()->tid, - scaled_ticks(ticks, mult)) + scaled_ticks(ticks, mult)), + 0, 0, 0, 0 }; } @@ -118,8 +118,8 @@ SYSCALL_DEFINE1(free_timer)(sys_arg_t cid) { struct timer *timer = find_timer(cid); if (!timer) - return (struct sys_ret){ ERR_NF, 0 }; + return (struct sys_ret){ ERR_NF, 0, 0, 0, 0, 0 }; remove_timer(timer); - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ OK, 0, 0, 0, 0, 0 }; } diff --git a/include/apos/syscalls.h b/include/apos/syscalls.h index 4bbcdc5..229e17e 100644 --- a/include/apos/syscalls.h +++ b/include/apos/syscalls.h @@ -95,11 +95,9 @@ enum { /** Kill thread. */ SYS_KILL, - /** Send signal to thread. */ - SYS_SIGNAL, - /** Switch running process. */ SYS_SWAP, + /** @} */ /** @name Kernel management. */ diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 8f8479b..9e63a9a 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -108,6 +108,9 @@ struct tcb { /** Address of callback function in servers. */ vm_t callback; + /** Address of signal callback. */ + vm_t signal; + /** Address of this thread's stack base. */ vm_t thread_stack; diff --git a/include/apos/uapi.h b/include/apos/uapi.h index 29e15dc..5d61966 100644 --- a/include/apos/uapi.h +++ b/include/apos/uapi.h @@ -14,9 +14,9 @@ /** * Syscall function type. - * Let's start with four arguments and see where that goes + * Let's start with five arguments and see where that goes */ -typedef struct sys_ret (*sys_t)(long, long, long, long); +typedef struct sys_ret (*sys_t)(long, long, long, long, long); /** * Syscall argument type. @@ -28,15 +28,27 @@ typedef long sys_arg_t; /** * Return structure of syscall. - * \note Field names are generic, and can be used for two values or two error - * codes, check documentation of whatever you're doing. + * \note Field names are generic, and can be used for whatever, + * check documentation of whatever you're doing. */ struct sys_ret { - /** Error code of syscall. */ - sys_arg_t err; + /** Status. */ + sys_arg_t s; - /** Value returned by syscall. */ - sys_arg_t val; + /** First argument. */ + sys_arg_t ar0; + + /** Second argument. */ + sys_arg_t ar1; + + /** Third argument. */ + sys_arg_t ar2; + + /** Fourth argument. */ + sys_arg_t ar3; + + /** Fifth argument. */ + sys_arg_t ar4; }; /** @@ -48,10 +60,12 @@ struct sys_ret { * * @param name Name of syscall. */ -#define SYSCALL_DECLARE0(name) \ - struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, \ - sys_arg_t c, \ - sys_arg_t d); +#define SYSCALL_DECLARE0(name) \ + struct sys_ret sys_##name(sys_arg_t a, \ + sys_arg_t b, \ + sys_arg_t c, \ + sys_arg_t d, \ + sys_arg_t e); /** * Helper macro for declaring syscalls with one argument. @@ -61,7 +75,7 @@ struct sys_ret { */ #define SYSCALL_DECLARE1(name, a) \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d); + sys_arg_t d, sys_arg_t e); /** * Helper macro for declaring syscalls with two arguments. @@ -72,7 +86,7 @@ struct sys_ret { */ #define SYSCALL_DECLARE2(name, a, b) \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d); + sys_arg_t d, sys_arg_t e); /** * Helper macro for declaring syscalls with three arguments. @@ -84,7 +98,7 @@ struct sys_ret { */ #define SYSCALL_DECLARE3(name, a, b, c) \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d); + sys_arg_t d, sys_arg_t e); /** * Helper macro for declaring syscalls with four arguments. @@ -97,7 +111,21 @@ struct sys_ret { */ #define SYSCALL_DECLARE4(name, a, b, c, d) \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d); + sys_arg_t d, sys_arg_t e); + +/** + * Helper macro for declaring syscalls with five arguments. + * + * @param name Name of syscall. + * @param a Name of first argument. + * @param b Name of second argument. + * @param c Name of third argument. + * @param d Name of fourth argument. + * @param e Name of fifth argument. + */ +#define SYSCALL_DECLARE5(name, a, b, c, d, e) \ + struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ + sys_arg_t d, sys_arg_t e); /** * Helper macro for defining syscall with zero arguments. @@ -107,12 +135,13 @@ struct sys_ret { #define SYSCALL_DEFINE0(name) \ static inline struct sys_ret __##name(); \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d) \ + sys_arg_t d, sys_arg_t e) \ { \ UNUSED(a); \ UNUSED(b); \ UNUSED(c); \ UNUSED(d); \ + UNUSED(e); \ return __##name(); \ } \ static struct sys_ret __##name @@ -125,11 +154,12 @@ struct sys_ret { #define SYSCALL_DEFINE1(name) \ static inline struct sys_ret __##name(sys_arg_t); \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d) \ + sys_arg_t d, sys_arg_t e) \ { \ UNUSED(b); \ UNUSED(c); \ UNUSED(d); \ + UNUSED(e); \ return __##name(a); \ } \ static inline struct sys_ret __##name @@ -142,10 +172,11 @@ struct sys_ret { #define SYSCALL_DEFINE2(name) \ static inline struct sys_ret __##name(sys_arg_t, sys_arg_t); \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d) \ + sys_arg_t d, sys_arg_t e) \ { \ UNUSED(c); \ UNUSED(d); \ + UNUSED(e); \ return __##name(a, b); \ } \ static inline struct sys_ret __##name @@ -159,9 +190,10 @@ struct sys_ret { static inline struct sys_ret __##name(sys_arg_t, sys_arg_t, \ sys_arg_t); \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d) \ + sys_arg_t d, sys_arg_t e) \ { \ UNUSED(d); \ + UNUSED(e); \ return __##name(a, b, c); \ } \ static inline struct sys_ret __##name @@ -175,12 +207,28 @@ struct sys_ret { static inline struct sys_ret __##name(sys_arg_t, sys_arg_t, sys_arg_t, \ sys_arg_t); \ struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ - sys_arg_t d) \ + sys_arg_t d, sys_arg_t e) \ { \ + UNUSED(e); \ return __##name(a, b, c, d); \ } \ static inline struct sys_ret __##name +/** + * Helper macro for defining syscall with five arguments. + * + * @param name Name of syscall. + */ +#define SYSCALL_DEFINE5(name) \ + static inline struct sys_ret __##name(sys_arg_t, sys_arg_t, sys_arg_t, \ + sys_arg_t, sys_arg_t); \ + struct sys_ret sys_##name(sys_arg_t a, sys_arg_t b, sys_arg_t c, \ + sys_arg_t d, sys_arg_t e) \ + { \ + return __##name(a, b, c, d, e); \ + } \ + static inline struct sys_ret __##name + /** @name Misc syscalls. */ /** @{ */ @@ -191,6 +239,7 @@ struct sys_ret { * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE0(noop); @@ -202,6 +251,7 @@ SYSCALL_DECLARE0(noop); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(putch, ch); @@ -220,6 +270,7 @@ SYSCALL_DECLARE1(putch, ch); * @param flags Flags of allocation. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and start of memory allocation. */ SYSCALL_DECLARE2(req_mem, size, flags); @@ -235,6 +286,7 @@ SYSCALL_DECLARE2(req_mem, size, flags); * @param size Size of physical allocation. * @param flags Flags of physical allocation. * @param d Unused. + * @param e Unused. * @return \ref OK and start of memory allocation. */ SYSCALL_DECLARE3(req_pmem, paddr, size, flags); @@ -249,6 +301,7 @@ SYSCALL_DECLARE3(req_pmem, paddr, size, flags); * @param size Size of allocation. * @param flags Flags of allocation. * @param d Unused. + * @param e Unused. * @return \ref OK and start of memory allocation. */ SYSCALL_DECLARE3(req_fixmem, start, size, flags); @@ -265,6 +318,7 @@ SYSCALL_DECLARE3(req_fixmem, start, size, flags); * @param flags Flags of allocation. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and start of memory allocation. */ SYSCALL_DECLARE2(req_sharedmem, size, flags); @@ -278,6 +332,7 @@ SYSCALL_DECLARE2(req_sharedmem, size, flags); * @param va Start address of shared memory. * @param flags Flags to use for reference. * @param d Unused. + * @param e Unused. * @return \ref OK and start of shared memory. */ SYSCALL_DECLARE3(ref_sharedmem, tid, va, flags); @@ -291,6 +346,7 @@ SYSCALL_DECLARE3(ref_sharedmem, tid, va, flags); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(free_mem, start); @@ -305,6 +361,7 @@ SYSCALL_DECLARE1(free_mem, start); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and frequency. * \todo Should this be some kind of config request instead of a separate * syscall? @@ -318,6 +375,7 @@ SYSCALL_DECLARE0(timebase); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return Current ticks. */ SYSCALL_DECLARE0(ticks); @@ -331,6 +389,7 @@ SYSCALL_DECLARE0(ticks); * @param mult Number of times to trigger. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and ID of timer. */ SYSCALL_DECLARE2(req_rel_timer, ticks, mult); @@ -344,6 +403,7 @@ SYSCALL_DECLARE2(req_rel_timer, ticks, mult); * @param mult Multiplier. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and ID of timer. * \todo Check repeat value. */ @@ -356,6 +416,7 @@ SYSCALL_DECLARE2(req_abs_timer, ticks, mult); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(free_timer, cid); @@ -370,6 +431,7 @@ SYSCALL_DECLARE1(free_timer, cid); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(ipc_server, callback); @@ -380,10 +442,11 @@ SYSCALL_DECLARE1(ipc_server, callback); * @param pid Request target process. * @param d0 First request argument. * @param d1 Second request argument. - * @param d Unused. + * @param d2 Third forwarding argument. + * @param d3 Fourth forwarding argument. * @return \c d0 and \c d1. */ -SYSCALL_DECLARE3(ipc_req, pid, d0, d1); +SYSCALL_DECLARE5(ipc_req, pid, d0, d1, d2, d3); /** * Forwarding syscall. @@ -394,21 +457,23 @@ SYSCALL_DECLARE3(ipc_req, pid, d0, d1); * @param pid Forwarding target process. * @param d0 First forwarding argument. * @param d1 Second forwarding argument. - * @param d Unused. + * @param d2 Third forwarding argument. + * @param d3 Fourth forwarding argument. * @return \c d0 and \c d1. */ -SYSCALL_DECLARE3(ipc_fwd, pid, d0, d1); +SYSCALL_DECLARE5(ipc_fwd, pid, d0, d1, d2, d3); /** * Response syscall. * * @param d0 First response argument. * @param d1 Second response argument. - * @param c Unused. - * @param d Unused. + * @param d2 Third response argument. + * @param d3 Fourth response argument. + * @param e Unused. * @return \c d0 and \c d1. */ -SYSCALL_DECLARE2(ipc_resp, d0, d1); +SYSCALL_DECLARE4(ipc_resp, d0, d1, d2, d3); /** @} */ /** @name Process handling syscalls. */ @@ -418,14 +483,15 @@ SYSCALL_DECLARE2(ipc_resp, d0, d1); * * Creates thread in current effective process context. * - * @param a Unused. - * @param b Unused. + * @param func Function to call on startup. + * @param arg Argument to pass to function. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. * \todo Should this take stack size etc? */ -SYSCALL_DECLARE0(create); +SYSCALL_DECLARE2(create, func, arg); /** * Fork process syscall. @@ -436,6 +502,7 @@ SYSCALL_DECLARE0(create); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE0(fork); @@ -449,21 +516,35 @@ SYSCALL_DECLARE0(fork); * @param interp Optional address of interpreter. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. * \todo Check other return codes. */ SYSCALL_DECLARE2(exec, bin, interp); +/** + * Kill syscall. + * + * @param a Unused. + * @param b Unused. + * @param c Unused. + * @param d Unused. + * @param e Unused. + * @return No. + */ +SYSCALL_DECLARE0(kill); + /** * Signal process syscall. * * @param tid Thread ID to signal. * @param signal Signal to send. - * @param c Unused. + * @param swap Whether to immediately swap. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ -SYSCALL_DECLARE2(signal, tid, signal); +SYSCALL_DECLARE3(signal, tid, signal, swap); /** * Swap syscall. @@ -474,6 +555,7 @@ SYSCALL_DECLARE2(signal, tid, signal); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(swap, tid); @@ -490,6 +572,7 @@ SYSCALL_DECLARE1(swap, tid); * @param val Value to set parameter to. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE2(conf_set, param, val); @@ -503,6 +586,7 @@ SYSCALL_DECLARE2(conf_set, param, val); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return \ref OK and 0. */ SYSCALL_DECLARE1(conf_get, param); @@ -516,6 +600,7 @@ SYSCALL_DECLARE1(conf_get, param); * @param b Unused. * @param c Unused. * @param d Unused. + * @param e Unused. * @return Shouldn't return at all. */ SYSCALL_DECLARE1(poweroff, type); @@ -529,10 +614,11 @@ SYSCALL_DECLARE1(poweroff, type); * @param b Syscall argument 1. * @param c Syscall argument 2. * @param d Syscall argument 3. + * @param e Syscall argument 4. * @return Whatever the specified syscall returns. */ struct sys_ret syscall_dispatch(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, - sys_arg_t c, sys_arg_t d); + sys_arg_t c, sys_arg_t d, sys_arg_t e); /** \todo Should I add variable names as well, to make the documentation a bit * more readable? */ diff --git a/include/arch/types.h b/include/arch/types.h index 78b001d..8732be2 100644 --- a/include/arch/types.h +++ b/include/arch/types.h @@ -17,7 +17,7 @@ #if defined(riscv64) #include "../../arch/riscv64/include/types.h" #elif defined(riscv32) -#include "../../arch/riscv64/include/types.h" +#include "../../arch/riscv32/include/types.h" #endif #endif /* APOS_ARCH_TYPES_H */ diff --git a/include/arch/vmem.h b/include/arch/vmem.h index 832d47e..bbaf9c4 100644 --- a/include/arch/vmem.h +++ b/include/arch/vmem.h @@ -16,6 +16,8 @@ #include "../../arch/riscv32/include/vmem.h" #endif +#include + /** * Map one virtual page to physical page. * -- cgit v1.3