aboutsummaryrefslogtreecommitdiff
path: root/common/uapi
diff options
context:
space:
mode:
Diffstat (limited to 'common/uapi')
-rw-r--r--common/uapi/conf.c24
-rw-r--r--common/uapi/dispatch.c6
-rw-r--r--common/uapi/ipc.c34
-rw-r--r--common/uapi/mem.c83
-rw-r--r--common/uapi/proc.c41
-rw-r--r--common/uapi/timers.c58
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);