diff options
Diffstat (limited to 'common/uapi')
| -rw-r--r-- | common/uapi/conf.c | 24 | ||||
| -rw-r--r-- | common/uapi/dispatch.c | 6 | ||||
| -rw-r--r-- | common/uapi/ipc.c | 34 | ||||
| -rw-r--r-- | common/uapi/mem.c | 83 | ||||
| -rw-r--r-- | common/uapi/proc.c | 41 | ||||
| -rw-r--r-- | common/uapi/timers.c | 58 |
6 files changed, 224 insertions, 22 deletions
diff --git a/common/uapi/conf.c b/common/uapi/conf.c index 47a7a0f..470b81e 100644 --- a/common/uapi/conf.c +++ b/common/uapi/conf.c @@ -15,11 +15,28 @@ size_t __thread_stack_size = SZ_2M; size_t __call_stack_size = SZ_2M; +/** + * Configuration parameter read syscall handler. + * + * \todo Implement parameters. + * + * @param param Parameter to read. + * @return \ref OK and parameter value. + */ SYSCALL_DEFINE1(conf_get)(sys_arg_t param) { return (struct sys_ret){ OK, 0 }; } +/** + * Configuration parameter write syscall handler. + * + * \todo Implement parameters. + * + * @param param Parameter to write. + * @param val Value to set \c param to. + * @return \ref OK and \c 0. + */ SYSCALL_DEFINE2(conf_set)(sys_arg_t param, sys_arg_t val) { UNUSED(param); @@ -29,6 +46,13 @@ SYSCALL_DEFINE2(conf_set)(sys_arg_t param, sys_arg_t val) return (struct sys_ret){ OK, 0 }; } +/** + * Poweroff syscall handler. + * + * @param type Type of poweroff. + * @return \ref ERR_INVAL and \c 0 if incorrect poweroff \c type give, otherwise + * does not return. + */ SYSCALL_DEFINE1(poweroff)(sys_arg_t type) { switch (type) { diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index 52cf8d9..c2ddbcf 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -9,6 +9,7 @@ #include <apos/debug.h> #include <apos/uapi.h> +/** Syscall number to syscall handler conversion. */ static const sys_t syscall_table[] = { /* noop */ [SYS_NOOP] = sys_noop, @@ -43,6 +44,11 @@ static const sys_t syscall_table[] = { [SYS_POWEROFF] = sys_poweroff, }; +/** + * Noop syscall handler. + * + * @return \ref OK and \c 0. + */ SYSCALL_DEFINE0(noop)(){ info("sys_noop\n"); return (struct sys_ret){ OK, 0 }; diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c index 8584673..4cdec0c 100644 --- a/common/uapi/ipc.c +++ b/common/uapi/ipc.c @@ -9,6 +9,13 @@ #include <apos/uapi.h> #include <apos/tcb.h> +/** + * 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. + */ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback) { struct tcb *r = cur_tcb(); @@ -19,6 +26,14 @@ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback) return (struct sys_ret){ OK, 0 }; } +/** + * IPC request syscall handler. + * + * @param pid Process to request RPC to. + * @param d0 IPC argument 0. + * @param d1 IPC argument 1. + * @return \c d0 and \c d1. + */ SYSCALL_DEFINE3(ipc_req)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) { struct tcb *r = get_tcb(pid); @@ -27,13 +42,28 @@ SYSCALL_DEFINE3(ipc_req)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) return (struct sys_ret){ d0, d1 }; } -SYSCALL_DEFINE3(ipc_fwd)(sys_arg_t tid, sys_arg_t d0, sys_arg_t d1) +/** + * IPC forwarding syscall handler. + * + * @param pid Process to rquest RPC to. + * @param d0 IPC argument 0. + * @param d1 IPC argument 1. + * @return \c d0 and \c d1. + */ +SYSCALL_DEFINE3(ipc_fwd)(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1) { - struct tcb *t = get_tcb(tid); + struct tcb *t = get_tcb(pid); /* ditto */ return (struct sys_ret){ d0, d1 }; } +/** + * IPC response syscall handler. + * + * @param d0 IPC return value 0. + * @param d1 IPC return value 1. + * @return \c d0 and \c d1. + */ SYSCALL_DEFINE2(ipc_resp)(sys_arg_t d0, sys_arg_t d1) { struct tcb *r = cur_tcb(); diff --git a/common/uapi/mem.c b/common/uapi/mem.c index 374e722..71686d6 100644 --- a/common/uapi/mem.c +++ b/common/uapi/mem.c @@ -4,6 +4,7 @@ /** * @file mem.c * Memory handling syscall implementations. + * \todo Should we return more error information? */ #include <apos/uapi.h> @@ -11,33 +12,76 @@ #include <apos/vmem.h> #include <apos/dmem.h> +/** + * Memory request syscall handler. + * + * @param size Minimum size of allocation. + * @param flags Flags of allocation. + * @return \ref OK and start of allocation when succesful, + * \ref ERR_OOMEM and \c NULL otherwise. + */ SYSCALL_DEFINE2(req_mem)(sys_arg_t size, sys_arg_t flags) { /* get current effective process */ struct tcb *r = cur_proc(); - return (struct sys_ret){ OK, alloc_uvmem(r, size, flags) }; + vm_t start = 0; + if ((start = alloc_uvmem(r, size, flags))) + return (struct sys_ret){ ERR_OOMEM, NULL }; + + return (struct sys_ret){ OK, start }; } +/** + * Fixed memory request syscall handler. + * + * @param start Address which should be included in allocation. + * @param size Minimum size of allocation after \c start. + * @param flags Flags of allocation. + * @return \ref OK and start of allocation when succesful, + * \ref ERR_OOMEM and \c NULL otherwise. + */ SYSCALL_DEFINE3(req_fixmem)(sys_arg_t start, sys_arg_t size, sys_arg_t flags) { struct tcb *r = cur_proc(); - /* should probably check if the allocation succeeded...? \todo */ - return (struct sys_ret){ OK, alloc_fixed_uvmem(r, start, size, flags) }; + vm_t start = 0; + if ((start = alloc_fixed_uvmem(r, start, size, flags))) + return (sys_ret){ ERR_OOMEM, NULL }; + + return (struct sys_ret){ OK, start }; } +/** + * Free memory syscall handler. + * + * @param start Start of allocation to free. + * @return \ref OK and \c 0 when succesful, \ref ERR_NF and \c 0 otherwise. + */ SYSCALL_DEFINE1(free_mem)(sys_arg_t start) { struct tcb *r = cur_proc(); vm_t vm_start = (vm_t)start; + stat_t status = OK; if (vm_start > __pre_top && vm_start < __post_base) - free_uvmem(r, vm_start); + status = free_uvmem(r, vm_start); else - free_devmem(r, vm_start); + status = free_devmem(r, vm_start); + + if (status) + return (struct sys_ret){ ERR_NF, 0 }; return (struct sys_ret){ OK, 0 }; } +/** + * Request physical memory syscall handler. + * + * @param paddr Physical address to map. + * @param size Minimum size of allocation. + * @param flags Flags of allocation. + * @return \ref OK and start of allocation when succesful, + * \ref ERR_OOMEM and \c NULL otherwise. + */ SYSCALL_DEFINE3(req_pmem)(sys_arg_t paddr, sys_arg_t size, sys_arg_t flags) { /* this will require some pondering, but essentially this syscall should @@ -46,29 +90,48 @@ SYSCALL_DEFINE3(req_pmem)(sys_arg_t paddr, sys_arg_t size, sys_arg_t flags) * that keeps track of used regions outside of RAM. We'll see. */ struct tcb *r = cur_proc(); - return (struct sys_ret){ OK, alloc_devmem(r, paddr, size, flags) }; + vm_t start = 0; + if ((start = alloc_devmem(r, paddr, size, flags))) + return (struct sys_ret){ ERR_OOMEM, NULL }; + + return (struct sys_ret){ OK, start }; } +/** + * Request shared memory syscall handler. + * + * @param size Minimum size of allocation. + * @param flags Flags of allocation. + * @return \ref OK and start of allocation when succesful, + * \ref ERR_OOMEM and \c NULL otherwise. + */ SYSCALL_DEFINE2(req_sharedmem)(sys_arg_t size, sys_arg_t flags) { /** \todo check that requester is server */ struct tcb *t = cur_proc(); vm_t start = 0; if ((start = alloc_shared_uvmem(t, size, flags))) - return (struct sys_ret){ ERR_OOMEM, 0 }; + return (struct sys_ret){ ERR_OOMEM, NULL }; return (struct sys_ret){ OK, start }; } -/* add a syscall like ref_sharedmem that adds a reference to an existing shared - * memory region to a new tid? */ +/** + * Reference shared memory syscall handler. + * + * @param tid Thread ID of shared memory owner. + * @param va Start of shared memory in \c tid. + * @param flags Flags of reference. + * @return \ref OK and start of reference when succesful, + * \ref ERR_OOMEM and \c NULL otherwise. + */ SYSCALL_DEFINE3(ref_sharedmem)(sys_arg_t tid, sys_arg_t va, sys_arg_t flags) { struct tcb *t1 = cur_tcb(); 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, 0 }; + return (struct sys_ret){ ERR_OOMEM, NULL }; return (struct sys_ret){ OK, start }; } diff --git a/common/uapi/proc.c b/common/uapi/proc.c index 79d243f..60617b4 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -12,11 +12,21 @@ #include <apos/bits.h> #include <apos/mem_regions.h> +/** + * Create syscall handler. + * + * \todo Implement. + * + * @return \ref OK and 0. + */ SYSCALL_DEFINE0(create)(){ return (struct sys_ret){ OK, 0 }; } -/* Not entirely sure how I should handle forks/execs etc, mostly whether I +/** + * Fork syscall handler. + * + * \todo Not entirely sure how I should handle forks/execs etc, mostly whether I * should allow forks/execs to be called directly or only though the process * manager. Probably though the process manager, although that will add in a * slight bit of delay. @@ -25,11 +35,20 @@ SYSCALL_DEFINE0(create)(){ * that would allow them to be called directly, and then the process manager * would have to periodically ask the kernel about all threads it is aware of * via sys_sync. Dunno. + * + * @return \ref OK and 0. */ SYSCALL_DEFINE0(fork)(){ return (struct sys_ret){ OK, 0 }; } +/** + * Exec syscall handler. + * + * @param bin Binary to execute. + * @param interp Optional interpreter binary. + * @return \see prepare_proc() and 0. + */ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ /** \todo execute new process, probably with more sensible argc passing */ struct tcb *r = cur_tcb(); @@ -60,11 +79,29 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ return (struct sys_ret){ prepare_proc(r, bin, interp), 0 }; } +/** + * Signal syscall handler. + * + * \todo Implement. + * + * @param tid Thread ID to signal. + * @param signal Signal to send to \c tid. + * @return \ref OK and 0. + */ SYSCALL_DEFINE2(signal)(sys_arg_t tid, sys_arg_t signal){ - /** \todo signals? */ return (struct sys_ret){ OK, 0 }; } +/** + * Swap syscall handler. + * + * \todo Implement. + * \todo Should swap return the registers of the new thread that would be used + * for message passing? + * + * @param tid Thread ID to swap to. + * @return \ref OK and 0. + */ SYSCALL_DEFINE1(swap)(sys_arg_t tid){ /** \todo switch to process */ /** \todo should switch return the registers of the new thread that would diff --git a/common/uapi/timers.c b/common/uapi/timers.c index bc3ef59..b6f9b95 100644 --- a/common/uapi/timers.c +++ b/common/uapi/timers.c @@ -9,39 +9,81 @@ #include <apos/timer.h> #include <apos/uapi.h> -static ticks_t scaled_ticks(sys_arg_t ticks, sys_arg_t repeat) +/** + * Convert arch-specific register values \c ticks and \c repeat to \c ticks_t. + * + * If we're on a 32bit system, one register can't contain a tick value, + * so we use two registers and combine them into one value and let the compiler + * handle the rest. + * + * @param ticks Register width tick value. + * @param mult Register width repeat value. + * @return Corresponding \c ticks_t value. + */ +static ticks_t scaled_ticks(sys_arg_t ticks, sys_arg_t mult) { -#if __WORDSIZE == 64 - UNUSED(repeat); +#if defined(_LP64) + UNUSED(mult); return ticks; #else - return ((ticks_t)ticks << 32) + repeat; + return (ticks_t)ticks * (ticks_t)mult; #endif } +/** + * Timebase syscall handler. + * + * @return \ref OK and resolution of system timer in Hz. + */ SYSCALL_DEFINE0(timebase)() { return (struct sys_ret){ OK, secs_to_ticks(1) }; } -SYSCALL_DEFINE2(req_rel_timer)(sys_arg_t ticks, sys_arg_t repeat) +/** + * Relative timer request syscall handler. + * + * \note On 64bit systems, \c repeat is ignored as \c ticks register is large + * enough to contain essentially any timepoint we want. A couple thousand years + * when the clock runs at 5GHz, if I'm not completely mistaken. + * + * @param ticks Number of ticks from now. + * @param mult Multiply \c ticks by this value. + * @return \ref OK and \c cid of created timer. + */ +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, repeat)) + scaled_ticks(ticks, mult)) }; } -SYSCALL_DEFINE2(req_abs_timer)(sys_arg_t ticks, sys_arg_t repeat) +/** + * Absolute timer request syscall handler. + * + * @param ticks Absolute timepoint relative to some start point defined at boot. + * @param mult Multiply \c ticks by this value. + * @return \ref OK and \c cid of created timer. + * \see req_rel_timer(). + */ +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, repeat)) + scaled_ticks(ticks, mult)) }; } +/** + * Free timer request syscall handler. + * + * @param cid \c cid of timer to free. + * @return \ref ERR_NF and \c 0if no timer could be found with \c cid, \ref OK + * and 0 otherwise. + */ SYSCALL_DEFINE1(free_timer)(sys_arg_t cid) { struct timer *timer = find_timer(cid); |
