diff options
| -rwxr-xr-x | arch/riscv64/conf/init | bin | 3832 -> 3512 bytes | |||
| -rw-r--r-- | arch/riscv64/conf/init.c | 157 | ||||
| -rw-r--r-- | arch/riscv64/conf/initrd | bin | 4096 -> 4096 bytes | |||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 14 | ||||
| -rw-r--r-- | common/uapi/cap.c | 16 | ||||
| -rw-r--r-- | common/uapi/conf.c | 18 | ||||
| -rw-r--r-- | common/uapi/dispatch.c | 6 | ||||
| -rw-r--r-- | common/uapi/ipc.c | 21 | ||||
| -rw-r--r-- | common/uapi/mem.c | 28 | ||||
| -rw-r--r-- | common/uapi/proc.c | 36 | ||||
| -rw-r--r-- | common/uapi/timers.c | 20 | ||||
| -rw-r--r-- | include/arch/proc.h | 2 | ||||
| -rw-r--r-- | include/kmi/uapi.h | 29 |
13 files changed, 198 insertions, 149 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init Binary files differindex 6e28b9b..d04c492 100755 --- a/arch/riscv64/conf/init +++ b/arch/riscv64/conf/init 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 Binary files differindex eaefce2..c8d7253 100644 --- a/arch/riscv64/conf/initrd +++ b/arch/riscv64/conf/initrd 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 */ |
