aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarch/riscv64/conf/initbin3832 -> 3512 bytes
-rw-r--r--arch/riscv64/conf/init.c157
-rw-r--r--arch/riscv64/conf/initrdbin4096 -> 4096 bytes
-rw-r--r--arch/riscv64/kernel/proc.c14
-rw-r--r--common/uapi/cap.c16
-rw-r--r--common/uapi/conf.c18
-rw-r--r--common/uapi/dispatch.c6
-rw-r--r--common/uapi/ipc.c21
-rw-r--r--common/uapi/mem.c28
-rw-r--r--common/uapi/proc.c36
-rw-r--r--common/uapi/timers.c20
-rw-r--r--include/arch/proc.h2
-rw-r--r--include/kmi/uapi.h29
13 files changed, 198 insertions, 149 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init
index 6e28b9b..d04c492 100755
--- a/arch/riscv64/conf/init
+++ b/arch/riscv64/conf/init
Binary files differ
diff --git a/arch/riscv64/conf/init.c b/arch/riscv64/conf/init.c
index 001d5eb..f9dfca3 100644
--- a/arch/riscv64/conf/init.c
+++ b/arch/riscv64/conf/init.c
@@ -39,40 +39,69 @@ char *strcpy(char * restrict dst, const char * restrict src)
return dst;
}
-struct sys_ret ecall(struct sys_ret s)
+static inline struct sys_ret ecall(size_t n,
+ long arg0, long arg1, long arg2, long arg3,
+ long arg4, long arg5)
{
- register long a0 asm ("a0") = s.a0;
- register long a1 asm ("a1") = s.a1;
- register long a2 asm ("a2") = s.a2;
- register long a3 asm ("a3") = s.a3;
- register long a4 asm ("a4") = s.a4;
- register long a5 asm ("a5") = s.a5;
+ /* here a static assert of n <= 6 && n >= 1 would be ideal */
- asm volatile ("ecall"
- : "=r" (a0), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4),
- "=r" (a5)
- : "r" (a0), "r" (a1), "r" (a2), "r" (a3), "r" (a4),
- "r" (a5));
+ register long a0 asm ("a0") = arg0;
+ register long a1 asm ("a1") = arg1;
+ register long a2 asm ("a2") = arg2;
+ register long a3 asm ("a3") = arg3;
+ register long a4 asm ("a4") = arg4;
+ register long a5 asm ("a5") = arg5;
+#define OUTPUTS "+r" (a0), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4), "=r" (a5)
+
+ if (n == 1)
+ asm volatile ("ecall" : OUTPUTS : "r" (a0));
+
+ else if (n == 2)
+ asm volatile ("ecall" : OUTPUTS : "r" (a0), "r" (a1));
+
+ else if (n == 3)
+ asm volatile ("ecall" : OUTPUTS : "r" (a0), "r" (a1), "r" (a2));
+
+ else if (n == 4)
+ asm volatile ("ecall" : OUTPUTS
+ : "r" (a0), "r" (a1), "r" (a2), "r" (a3));
+
+ else if (n == 5)
+ asm volatile ("ecall" : OUTPUTS
+ : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
+ "r" (a4));
+
+ else if (n == 6)
+ asm volatile ("ecall"
+ : OUTPUTS
+ : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
+ "r" (a4), "r" (a5));
+
+#undef OUTPUTS
return (struct sys_ret){a0, a1, a2, a3, a4, a5};
}
+#define ecall1(a) ecall(1, a, 0, 0, 0, 0, 0)
+#define ecall2(a, b) ecall(2, a, b, 0, 0, 0, 0)
+#define ecall3(a, b, c) ecall(3, a, b, c, 0, 0, 0)
+#define ecall4(a, b, c, d) ecall(4, a, b, c, d, 0, 0)
+#define ecall5(a, b, c, d, e) ecall(5, a, b, c, d, e, 0)
+#define ecall6(a, b, c, d, e, f) ecall(6, a, b, c, d, e, f)
+
static void sys_noop()
{
- struct sys_ret r = {.a0 = SYS_NOOP};
- ecall(r);
+ ecall1(SYS_NOOP);
}
static void sys_putch(char c)
{
- struct sys_ret r = {.a0 = SYS_PUTCH, .a1 = c};
- ecall(r);
+ ecall2(SYS_PUTCH, c);
}
static uint64_t sys_timebase()
{
- struct sys_ret r = {.a0 = SYS_TIMEBASE};
- r = ecall(r);
+ struct sys_ret r = ecall1(SYS_TIMEBASE);
#if defined(_LP64)
return r.a1;
#else
@@ -84,8 +113,7 @@ static uint64_t sys_timebase()
static uint64_t sys_ticks()
{
- struct sys_ret r = {.a0 = SYS_TICKS};
- r = ecall(r);
+ struct sys_ret r = ecall1(SYS_TICKS);
#if defined(_LP64)
return r.a1;
#else
@@ -131,30 +159,31 @@ static void print_value(const char *s, uint64_t v)
static uint64_t sys_fork()
{
- struct sys_ret r = {.a0 = SYS_FORK};
- r = ecall(r);
+ struct sys_ret r = ecall1(SYS_FORK);
- if (r.a0 != 0)
+ if (r.a0 != 0) {
print_value("fork() failed with error ", r.a0);
+ return r.a0;
+ }
return r.a1;
}
static uint64_t sys_swap(long tid)
{
- struct sys_ret r = {.a0 = SYS_SWAP, .a1 = tid};
- r = ecall(r);
+ struct sys_ret r = ecall2(SYS_SWAP, tid);
- if (r.a0 != 0)
+ if (r.a0 != 0) {
print_value("swap() failed with error ", r.a0);
+ return r.a0;
+ }
- return r.a0;
+ return 0;
}
static void sys_ipc_server(void *f)
{
- struct sys_ret r = {.a0 = SYS_IPC_SERVER, .a1 = (long)f};
- r = ecall(r);
+ struct sys_ret r = ecall2(SYS_IPC_SERVER, (long)f);
if (r.a0 != 0)
print_value("ipc_server() failed with error ", r.a0);
@@ -162,59 +191,47 @@ static void sys_ipc_server(void *f)
/** Helper for ipc arguments/return values. */
struct ipc_args {
- long a0, a1, a2, a3;
+ long s; long a0, a1, a2, a3;
};
-static struct ipc_args sys_ipc_req(long tid, long d0, long d1, long d2, long d3)
+static inline struct ipc_args sys_ipc_req(long tid, long d0, long d1, long d2,
+ long d3)
{
- struct sys_ret r = {.a0 = SYS_IPC_REQ,
- .a1 = tid,
- .a2 = d0,
- .a3 = d1,
- .a4 = d2,
- .a5 = d3};
+ struct sys_ret r = ecall6(SYS_IPC_REQ, tid, d0, d1, d2, d3);
- r = ecall(r);
-
- if (r.a0)
+ if (r.a0) {
print_value("ipc_req() failed with error ", r.a0);
+ return (struct ipc_args){r.a0, 0, 0, 0, 0};
+ }
- return (struct ipc_args){r.a1, r.a2, r.a3, r.a4};
+ return (struct ipc_args){r.a0, r.a1, r.a2, r.a3, r.a4};
}
static void sys_ipc_resp(long d0, long d1, long d2, long d3)
{
- struct sys_ret r = {.a0 = SYS_IPC_RESP,
- .a1 = d0,
- .a2 = d1,
- .a3 = d2,
- .a4 = d3};
-
- ecall(r);
+ ecall5(SYS_IPC_RESP, d0, d1, d2, d3);
}
static void sys_poweroff(long type)
{
- struct sys_ret r = {.a0 = SYS_POWEROFF, .a1 = type};
- ecall(r);
+ ecall2(SYS_POWEROFF, type);
}
static void *sys_req_mem(size_t count)
{
- struct sys_ret r = {.a0 = SYS_REQ_MEM, .a1 = count,
- .a2 = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)};
- r = ecall(r);
-
- if (r.a0)
+ struct sys_ret r = ecall3(SYS_REQ_MEM, count,
+ (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4));
+ if (r.a0) {
print_value("sys_req_mem() failed with error ", r.a0);
+ return NULL;
+ }
return (void *)r.a1;
}
static void sys_free_mem(void *p)
{
- struct sys_ret r = {.a0 = SYS_FREE_MEM, .a1 = (long)p};
- r = ecall(r);
+ struct sys_ret r = ecall2(SYS_FREE_MEM, (long)p);
if (r.a0)
print_value("sys_free_mem() failed with error ", r.a0);
@@ -222,13 +239,13 @@ static void sys_free_mem(void *p)
static void *sys_req_sharedmem(long tid, unsigned long size, void **cbuf)
{
- struct sys_ret r = {.a0 = SYS_REQ_SHAREDMEM, .a1 = tid, .a2 = size,
- .a3 = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4),
- .a4 = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)};
- r = ecall(r);
-
- if (r.a0)
+ struct sys_ret r = ecall5(SYS_REQ_SHAREDMEM, tid, size,
+ (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4),
+ (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4));
+ if (r.a0) {
print_value("sys_req_sharedmem() failed with error ", r.a0);
+ return NULL;
+ }
*cbuf = (void *)r.a2;
return (void *)r.a1;
@@ -242,14 +259,20 @@ void callback(long status, long tid, long d0, long d1, long d2, long d3)
{
(void)status;
- void *cbuf = 0;
- if (d0 == 1)
+ if (d0 == 1) {
+ void *cbuf = 0;
rw_buf = sys_req_sharedmem(tid, rw_buf_size, &cbuf);
+ sys_ipc_resp((long)cbuf, rw_buf_size, 0, 0);
+ __builtin_unreachable();
- if (d0 == 2)
+ } else if (d0 == 2) {
puts(rw_buf);
+ sys_ipc_resp(0, 0, 0, 0);
+ __builtin_unreachable();
+ }
- sys_ipc_resp((long)cbuf, rw_buf_size, 0, 0);
+ sys_ipc_resp(0, 0, 0, 0);
+ __builtin_unreachable();
}
#define CSR_TIME "0xc01"
diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd
index eaefce2..c8d7253 100644
--- a/arch/riscv64/conf/initrd
+++ b/arch/riscv64/conf/initrd
Binary files differ
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c
index 2cc3f36..a7721e2 100644
--- a/arch/riscv64/kernel/proc.c
+++ b/arch/riscv64/kernel/proc.c
@@ -35,15 +35,15 @@ void run_init(struct tcb *t, void *fdt)
unreachable();
}
-void set_args(struct tcb *t, struct sys_ret a)
+void set_args(struct tcb *t, size_t n, struct sys_ret a)
{
struct riscv_regs *r = (struct riscv_regs *)(t->regs) - 1;
- r->a0 = a.s;
- r->a1 = a.ar0;
- r->a2 = a.ar1;
- r->a3 = a.ar2;
- r->a4 = a.ar3;
- r->a5 = a.ar4;
+ if (n >= 1) r->a0 = a.s;
+ if (n >= 2) r->a1 = a.ar0;
+ if (n >= 3) r->a2 = a.ar1;
+ if (n >= 4) r->a3 = a.ar2;
+ if (n >= 5) r->a4 = a.ar3;
+ if (n >= 6) r->a5 = a.ar4;
}
struct sys_ret get_args(struct tcb *t)
diff --git a/common/uapi/cap.c b/common/uapi/cap.c
index 825022a..157ef47 100644
--- a/common/uapi/cap.c
+++ b/common/uapi/cap.c
@@ -42,14 +42,14 @@ SYSCALL_DEFINE3(set_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off,
sys_arg_t caps)
{
if (!is_set(t->caps, CAP_CAPS))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
capflags_t *c;
if (!(c = __get_tcb_caps(tid, off)))
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
set_caps(*c, off, caps);
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
/**
@@ -64,9 +64,9 @@ SYSCALL_DEFINE2(get_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off)
{
capflags_t *c;
if (!(c = __get_tcb_caps(tid, off)))
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
- return_args(t, SYS_RET2(OK, get_caps(*c, off)));
+ return_args2(t, OK, get_caps(*c, off));
}
/**
@@ -83,12 +83,12 @@ SYSCALL_DEFINE3(clear_cap)(struct tcb *t, sys_arg_t tid, sys_arg_t off,
sys_arg_t caps)
{
if (!is_set(t->caps, CAP_CAPS))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
capflags_t *c;
if (!(c = __get_tcb_caps(tid, off)))
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
clear_caps(*c, off, caps);
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
diff --git a/common/uapi/conf.c b/common/uapi/conf.c
index ea06e06..13be3ee 100644
--- a/common/uapi/conf.c
+++ b/common/uapi/conf.c
@@ -41,7 +41,7 @@ enum conf_param {
SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
{
if (!has_cap(t->caps, CAP_CONF))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
long val = 0;
switch (param) {
@@ -58,10 +58,10 @@ SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
break;
default:
- return_args(t, SYS_RET1(ERR_NF));
+ return_args1(t, ERR_NF);
}
- return_args(t, SYS_RET2(OK, val));
+ return_args2(t, OK, val);
}
/**
@@ -77,7 +77,7 @@ SYSCALL_DEFINE1(conf_get)(struct tcb *t, sys_arg_t param)
SYSCALL_DEFINE2(conf_set)(struct tcb *t, sys_arg_t param, sys_arg_t val)
{
if (!has_cap(t->caps, CAP_CONF))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
size_t size = 0;
switch (param) {
@@ -96,13 +96,13 @@ SYSCALL_DEFINE2(conf_set)(struct tcb *t, sys_arg_t param, sys_arg_t val)
case CONF_RPC_STACK:
size = align_up(val, BASE_PAGE_SIZE);
if (size > __call_stack_size)
- return_args(t, SYS_RET1(ERR_MISC));
+ return_args1(t, ERR_MISC);
__rpc_stack_size = size;
break;
}
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
/**
@@ -116,14 +116,14 @@ SYSCALL_DEFINE2(conf_set)(struct tcb *t, sys_arg_t param, sys_arg_t val)
SYSCALL_DEFINE1(poweroff)(struct tcb *t, sys_arg_t type)
{
if (!(has_cap(t->caps, CAP_POWER)))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
switch (type) {
case SHUTDOWN:
case COLD_REBOOT:
case WARM_REBOOT:
- return_args(t, SYS_RET2(OK, poweroff(type)));
+ return_args2(t, OK, poweroff(type));
};
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
}
diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c
index d071db3..a9caa1e 100644
--- a/common/uapi/dispatch.c
+++ b/common/uapi/dispatch.c
@@ -23,7 +23,7 @@
SYSCALL_DEFINE0(noop)(struct tcb *t)
{
info("sys_noop\n");
- set_args(t, SYS_RET1(OK));
+ set_args1(t, OK);
}
/**
@@ -37,7 +37,7 @@ SYSCALL_DEFINE0(noop)(struct tcb *t)
SYSCALL_DEFINE1(putch)(struct tcb *t, sys_arg_t a)
{
dbg("%c", (char)a);
- set_args(t, SYS_RET1(OK));
+ set_args1(t, OK);
}
void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
@@ -79,7 +79,7 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
default:
error("Syscall %zu outside allowed range [0 - %i]\n", syscall,
SYS_NUM - 1);
- set_args(t, SYS_RET1(ERR_INVAL));
+ set_args1(t, ERR_INVAL);
};
if (check_canary(t)) {
diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c
index c2548e9..f9b2817 100644
--- a/common/uapi/ipc.c
+++ b/common/uapi/ipc.c
@@ -134,7 +134,7 @@ static struct stack_diff enter_rpc(struct tcb *t, struct sys_ret a,
/* try to get rid of args as fast as possible to free up registers for
* later use */
- set_args(t, a);
+ set_args(t, 6, a);
ctx->exec = t->exec;
ctx->pid = t->pid;
@@ -185,7 +185,7 @@ static void leave_rpc(struct tcb *t, struct sys_ret a)
t->regs = ctx->regs;
/* again, get rid of args as fast as possible */
- set_args(t, a);
+ set_args(t, 6, a);
set_return(t, ctx->exec);
/* if we're returning from a failed rpc, this should essentially be a
@@ -230,7 +230,7 @@ static bool enough_rpc_stack(struct tcb *t)
SYSCALL_DEFINE1(ipc_server)(struct tcb *t, sys_arg_t callback)
{
get_cproc(t)->callback = callback;
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
/**
@@ -261,7 +261,7 @@ static void do_ipc(struct tcb *t,
enum ipc_kind kind)
{
if (unlikely(!enough_rpc_stack(t)))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
struct stack_diff sd =
enter_rpc(t, SYS_RET6(OK, t->eid, d0, d1, d2, d3), kind);
@@ -283,6 +283,9 @@ static void do_ipc(struct tcb *t,
t->eid = t->pid;
finalize_rpc(t, r, sd);
+ /* I tested out passing the return values as arguments to
+ * ret_userspace_fast, but apparently that causes enough stack shuffling
+ * to be slower overall. */
ret_userspace_fast();
}
/**
@@ -354,7 +357,7 @@ SYSCALL_DEFINE4(ipc_resp)(struct tcb *t, sys_arg_t d0, sys_arg_t d1,
/* if we're not in an rpc, the user messed something up. */
/** @todo choose or come up with more fitting error value. */
if (unlikely(!is_rpc(t)))
- return_args(t, SYS_RET1(ERR_MISC));
+ return_args1(t, ERR_MISC);
/* we need the current proc before leaving the rpc */
struct tcb *r = get_cproc(t);
@@ -373,20 +376,20 @@ SYSCALL_DEFINE4(ipc_resp)(struct tcb *t, sys_arg_t d0, sys_arg_t d1,
*/
SYSCALL_DEFINE1(ipc_notify)(struct tcb *t, sys_arg_t tid){
if (!has_cap(t->caps, CAP_CALL))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
struct tcb *r = get_tcb(tid);
if (r->notify_state == NOTIFY_QUEUED)
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
if (r->notify_state == NOTIFY_RUNNING) {
t->notify_state = NOTIFY_QUEUED;
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
r->notify_state = NOTIFY_QUEUED;
if (running(r))
send_ipi(r);
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
diff --git a/common/uapi/mem.c b/common/uapi/mem.c
index 01bf470..d54390a 100644
--- a/common/uapi/mem.c
+++ b/common/uapi/mem.c
@@ -27,9 +27,9 @@ SYSCALL_DEFINE2(req_mem)(struct tcb *t, sys_arg_t size, sys_arg_t flags)
vm_t start = 0;
/** @todo expose flags to users */
if (!(start = alloc_uvmem(r, size, flags)))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET2(OK, start));
+ return_args2(t, OK, start);
}
/**
@@ -46,9 +46,9 @@ SYSCALL_DEFINE2(req_page)(struct tcb *t, sys_arg_t size, sys_arg_t flags)
struct tcb *r = get_cproc(t);
vm_t start = 0; pm_t paddr = 0; size_t asize = size;
if (!(start = alloc_uvpage(r, asize, flags, &asize, &paddr)))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET4(OK, start, asize, paddr));
+ return_args4(t, OK, start, asize, paddr);
}
/**
@@ -67,9 +67,9 @@ SYSCALL_DEFINE3(req_fixmem)(struct tcb *t, sys_arg_t fixed, sys_arg_t size,
struct tcb *r = get_cproc(t);
vm_t start = 0;
if (!(start = alloc_fixed_uvmem(r, fixed, size, flags)))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET2(OK, start));
+ return_args2(t, OK, start);
}
/**
@@ -88,12 +88,12 @@ SYSCALL_DEFINE1(free_mem)(struct tcb *t, sys_arg_t start)
/* try freeing normal user memory first, if that fails, try device
* memory, otherwise just assume the address is borked. */
if (!(status = free_uvmem(r, vm_start)))
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
if (!(status = free_devmem(r, vm_start)))
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
- return_args(t, SYS_RET1(status));
+ return_args1(t, status);
}
/**
@@ -117,9 +117,9 @@ SYSCALL_DEFINE3(req_pmem)(struct tcb *t, sys_arg_t paddr, sys_arg_t size,
struct tcb *r = get_cproc(t);
vm_t start = 0;
if (!(start = alloc_devmem(r, paddr, size, flags)))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET2(OK, start));
+ return_args2(t, OK, start);
}
/**
@@ -143,16 +143,16 @@ SYSCALL_DEFINE4(req_sharedmem)(struct tcb *t, sys_arg_t tid,
/** @todo check capability for shared memory */
struct tcb *u = get_tcb(tid);
if (!u)
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
struct tcb *s = get_cproc(t);
struct tcb *c = get_rproc(u);
vm_t sstart, cstart;
if (alloc_shared_uvmem(s, c, size, sflags, cflags, &sstart, &cstart))
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET3(OK, sstart, cstart));
+ return_args3(t, OK, sstart, cstart);
}
/** \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 81e3305..0ec19fb 100644
--- a/common/uapi/proc.c
+++ b/common/uapi/proc.c
@@ -30,14 +30,14 @@ SYSCALL_DEFINE5(create)(struct tcb *t, sys_arg_t func,
{
struct tcb *c = create_thread(t);
if (!c)
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
alloc_stack(c);
- set_args(c, SYS_RET5(c->tid, d0, d1, d2, d3));
+ set_args5(c, c->tid, d0, d1, d2, d3);
set_return(c, func);
- return_args(t, SYS_RET2(OK, c->tid));
+ return_args2(t, OK, c->tid);
}
/**
@@ -60,17 +60,17 @@ SYSCALL_DEFINE0(fork)(struct tcb *t)
{
struct tcb *c = get_cproc(t);
if (!(has_cap(c->caps, CAP_PROC)))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
struct tcb *n = create_proc(get_eproc(t));
if (!n)
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
/* prepare args for when we eventually swap to the new proc, giving
* parent ID as third return value */
- set_args(n, SYS_RET3(OK, 0, n->pid));
+ set_args3(n, OK, 0, n->pid);
- return_args(t, SYS_RET2(OK, n->pid));
+ return_args2(t, OK, n->pid);
}
/**
@@ -88,7 +88,7 @@ SYSCALL_DEFINE2(exec)(struct tcb *t, sys_arg_t bin, sys_arg_t interp)
/* mark binary to be kept */
struct mem_region *b = find_used_region(&t->sp_r, bin);
if (!b)
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
set_bit(b->flags, MR_KEEP);
@@ -97,7 +97,7 @@ SYSCALL_DEFINE2(exec)(struct tcb *t, sys_arg_t bin, sys_arg_t interp)
/* mark interpreter to be kept */
i = find_used_region(&t->sp_r, interp);
if (!i)
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
set_bit(i->flags, MR_KEEP);
}
@@ -110,7 +110,7 @@ SYSCALL_DEFINE2(exec)(struct tcb *t, sys_arg_t bin, sys_arg_t interp)
if (interp)
clear_bit(b->flags, MR_KEEP);
- return_args(t, SYS_RET1(prepare_proc(t, bin, interp)));
+ return_args1(t, prepare_proc(t, bin, interp));
}
/**
@@ -126,13 +126,13 @@ SYSCALL_DEFINE2(spawn)(struct tcb *t, sys_arg_t bin, sys_arg_t interp)
{
struct tcb *c = get_proc(t);
if (!(has_cap(c->caps, CAP_PROC)))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
struct tcb *n = create_proc(NULL);
if (!n)
- return_args(t, SYS_RET1(ERR_OOMEM));
+ return_args1(t, ERR_OOMEM);
- return_args(t, SYS_RET2(prepare_proc(n, bin, interp), n->pid));
+ return_args2(t, prepare_proc(n, bin, interp), n->pid);
}
/**
@@ -148,11 +148,11 @@ SYSCALL_DEFINE1(kill)(struct tcb *t, sys_arg_t tid)
{
struct tcb *c = get_cproc(t);
if (!(has_cap(c->caps, CAP_PROC)))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
/** @todo implement */
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
/**
@@ -170,17 +170,17 @@ SYSCALL_DEFINE1(kill)(struct tcb *t, sys_arg_t tid)
SYSCALL_DEFINE1(swap)(struct tcb *t, sys_arg_t tid){
struct tcb *c = get_cproc(t);
if (!(has_cap(c->caps, CAP_PROC)))
- return_args(t, SYS_RET1(ERR_PERM));
+ return_args1(t, ERR_PERM);
struct tcb *s = get_tcb(tid);
if (!s)
- return_args(t, SYS_RET1(ERR_INVAL));
+ return_args1(t, ERR_INVAL);
/* switch over to new thread */
use_tcb(s);
/* set return value for current thread */
- set_args(t, SYS_RET1(OK));
+ set_args1(t, OK);
/* get register state for new thread */
return_args(s, get_args(s));
diff --git a/common/uapi/timers.c b/common/uapi/timers.c
index 0d0ac50..b119fcc 100644
--- a/common/uapi/timers.c
+++ b/common/uapi/timers.c
@@ -43,9 +43,9 @@ SYSCALL_DEFINE0(timebase)(struct tcb *t)
{
ticks_t tm = secs_to_ticks(1);
#if defined(_LP64)
- return_args(t, SYS_RET2(OK, tm));
+ return_args2(t, OK, tm);
#else
- return_args(t, SYS_RET3(OK, tm >> 32, tm));
+ return_args3(t, OK, tm >> 32, tm);
#endif
}
@@ -64,9 +64,9 @@ SYSCALL_DEFINE0(ticks)(struct tcb *t)
{
ticks_t tm = current_ticks();
#if defined(_LP64)
- return_args(t, SYS_RET2(OK, tm));
+ return_args2(t, OK, tm);
#else
- return_args(t, SYS_RET3(OK, tm >> 32, tm));
+ return_args3(t, OK, tm >> 32, tm);
#endif
}
@@ -84,9 +84,7 @@ SYSCALL_DEFINE0(ticks)(struct tcb *t)
*/
SYSCALL_DEFINE2(req_rel_timer)(struct tcb *t, sys_arg_t ticks, sys_arg_t mult)
{
- return_args(t,
- SYS_RET2(OK,
- new_rel_timer(t->tid, scaled_ticks(ticks, mult))));
+ return_args2(t, OK, new_rel_timer(t->tid, scaled_ticks(ticks, mult)));
}
/**
@@ -100,9 +98,7 @@ SYSCALL_DEFINE2(req_rel_timer)(struct tcb *t, sys_arg_t ticks, sys_arg_t mult)
*/
SYSCALL_DEFINE2(req_abs_timer)(struct tcb *t, sys_arg_t ticks, sys_arg_t mult)
{
- return_args(t,
- SYS_RET2(OK,
- new_abs_timer(t->tid, scaled_ticks(ticks, mult))));
+ return_args2(t, OK, new_abs_timer(t->tid, scaled_ticks(ticks, mult)));
}
/**
@@ -117,8 +113,8 @@ SYSCALL_DEFINE1(free_timer)(struct tcb *t, sys_arg_t cid)
{
struct timer *timer = find_timer(cid);
if (!timer)
- return_args(t, SYS_RET1(ERR_NF));
+ return_args1(t, ERR_NF);
remove_timer(timer);
- return_args(t, SYS_RET1(OK));
+ return_args1(t, OK);
}
diff --git a/include/arch/proc.h b/include/arch/proc.h
index c9b54db..79b099e 100644
--- a/include/arch/proc.h
+++ b/include/arch/proc.h
@@ -23,7 +23,7 @@
* @param t Thread that will run after return.
* @param a Arguments to attach.
*/
-void set_args(struct tcb *t, struct sys_ret a);
+void set_args(struct tcb *t, size_t n, struct sys_ret a);
/**
* Get argument data attached to thread.
diff --git a/include/kmi/uapi.h b/include/kmi/uapi.h
index 526738a..477e315 100644
--- a/include/kmi/uapi.h
+++ b/include/kmi/uapi.h
@@ -817,6 +817,33 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
* more readable? */
#include <arch/proc.h>
-#define return_args(t, x) {set_args((t), (x)); return;}
+
+#define set_args1(t, a) set_args(t, 1, SYS_RET1(a))
+#define set_args2(t, a, b) set_args(t, 2, SYS_RET2(a, b))
+#define set_args3(t, a, b, c) set_args(t, 3, SYS_RET3(a, b, c))
+#define set_args4(t, a, b, c, d) set_args(t, 4, SYS_RET4(a, b, c, d))
+#define set_args5(t, a, b, c, d, e) set_args(t, 5, SYS_RET5(a, b, c, d, e))
+#define set_args6(t, a, b, c, d, e, f) set_args(t, 6, \
+ SYS_RET6(a, b, c, d, e, f))
+
+#define return_args1(t, a) \
+ {set_args1(t, a); return;}
+
+#define return_args2(t, a, b) \
+ {set_args2(t, a, b); return;}
+
+#define return_args3(t, a, b, c) \
+ {set_args3(t, a, b, c); return;}
+
+#define return_args4(t, a, b, c, d) \
+ {set_args4(t, a, b, c, d); return;}
+
+#define return_args5(t, a, b, c, d, e) \
+ {set_args5(t, a, b, c, d, e); return;}
+
+#define return_args6(t, a, b, c, d, e, f) \
+ {set_args6(t, a, b, c, d, e, f); return;}
+
+#define return_args(t, x) {set_args((t), 6, (x)); return;}
#endif /* KMI_UAPI_H */