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 /common | |
| 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 'common')
| -rw-r--r-- | common/uapi/conf.c | 8 | ||||
| -rw-r--r-- | common/uapi/dispatch.c | 18 | ||||
| -rw-r--r-- | common/uapi/ipc.c | 42 | ||||
| -rw-r--r-- | common/uapi/mem.c | 24 | ||||
| -rw-r--r-- | common/uapi/proc.c | 34 | ||||
| -rw-r--r-- | common/uapi/timers.c | 26 |
6 files changed, 87 insertions, 65 deletions
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 }; } |
