diff --git a/common/inc/s3k/syscall.h b/common/inc/s3k/syscall.h index 127a675b..8541dcdb 100644 --- a/common/inc/s3k/syscall.h +++ b/common/inc/s3k/syscall.h @@ -9,6 +9,7 @@ uint64_t s3k_reg_read(s3k_reg_t reg); uint64_t s3k_reg_write(s3k_reg_t reg, uint64_t val); void s3k_sync(); void s3k_sync_mem(); +void s3k_sleep(uint64_t time); s3k_err_t s3k_cap_read(s3k_cidx_t idx, s3k_cap_t *cap); s3k_err_t s3k_cap_move(s3k_cidx_t src, s3k_cidx_t dst); s3k_err_t s3k_cap_delete(s3k_cidx_t idx); diff --git a/common/src/s3k/syscall.c b/common/src/s3k/syscall.c index 9fd30907..9788415a 100644 --- a/common/src/s3k/syscall.c +++ b/common/src/s3k/syscall.c @@ -6,6 +6,7 @@ typedef enum { S3K_SYS_REG_READ, // Read from a register S3K_SYS_REG_WRITE, // Write to a register S3K_SYS_SYNC, // Synchronize memory and time. + S3K_SYS_SLEEP, // Capability Management S3K_SYS_CAP_READ, // Read the properties of a capability. @@ -37,77 +38,112 @@ typedef enum { } s3k_syscall_t; typedef union { - s3k_syscall_t call; - struct { uint64_t a0, a1, a2, a3, a4, a5, a6, a7; }; struct { - s3k_syscall_t call; - int info; + uint64_t info; } get_info; struct { - s3k_syscall_t call; - s3k_reg_t reg; + uint64_t reg; + } reg_read; + + struct { + uint64_t reg; uint64_t val; - } reg; + } reg_write; struct { - s3k_syscall_t call; - bool full; + uint64_t full; } sync; struct { - s3k_syscall_t call; - s3k_cidx_t idx; - s3k_cidx_t dst_idx; - s3k_cap_t cap; - } cap; + uint64_t time; + } sleep; + + struct { + uint64_t idx; + } cap_read; struct { - s3k_syscall_t call; - s3k_cidx_t pmp_idx; - s3k_pmp_slot_t pmp_slot; - } pmp; + uint64_t src_idx; + uint64_t dst_idx; + } cap_move; struct { - s3k_syscall_t call; - s3k_cidx_t mon_idx; - s3k_pid_t pid; + uint64_t idx; + } cap_delete; + + struct { + uint64_t idx; + } cap_revoke; + + struct { + uint64_t src_idx; + uint64_t dst_idx; + uint64_t cap_raw; + } cap_derive; + + struct { + uint64_t idx; + uint64_t slot; + } pmp_load; + + struct { + uint64_t idx; + } pmp_unload; + + struct { + uint64_t mon_idx; + uint64_t pid; } mon_state; struct { - s3k_syscall_t call; - s3k_cidx_t mon_idx; - s3k_pid_t pid; - s3k_reg_t reg; + uint64_t mon_idx; + uint64_t pid; + uint64_t reg; + } mon_reg_read; + + struct { + uint64_t mon_idx; + uint64_t pid; + uint64_t reg; uint64_t val; - } mon_reg; + } mon_reg_write; + + struct { + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + } mon_cap_read; struct { - s3k_syscall_t call; - s3k_cidx_t mon_idx; - s3k_pid_t src_pid; - s3k_cidx_t src_idx; - s3k_pid_t dst_pid; - s3k_cidx_t dst_idx; - } mon_cap; + uint64_t mon_idx; + uint64_t src_pid; + uint64_t src_idx; + uint64_t dst_pid; + uint64_t dst_idx; + } mon_cap_move; struct { - s3k_syscall_t call; - s3k_cidx_t mon_idx; - s3k_pid_t pid; - s3k_cidx_t pmp_idx; - s3k_pmp_slot_t pmp_slot; - } mon_pmp; + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + uint64_t slot; + } mon_pmp_load; struct { - s3k_syscall_t call; - s3k_cidx_t sock_idx; - s3k_cidx_t cap_idx; - bool send_cap; + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + } mon_pmp_unload; + + struct { + uint64_t sock_idx; + uint64_t cap_idx; + uint64_t send_cap; uint64_t data[4]; } sock; } sys_args_t; @@ -119,135 +155,128 @@ typedef struct { _Static_assert(sizeof(sys_args_t) == 64, "sys_args_t has the wrong size"); -static inline s3k_ret_t do_ecall(sys_args_t args, int width) -{ - register uint64_t t0 __asm__("t0"); - register uint64_t a0 __asm__("a0") = args.a0; - register uint64_t a1 __asm__("a1") = args.a1; - register uint64_t a2 __asm__("a2") = args.a2; - register uint64_t a3 __asm__("a3") = args.a3; - register uint64_t a4 __asm__("a4") = args.a4; - register uint64_t a5 __asm__("a5") = args.a5; - register uint64_t a6 __asm__("a6") = args.a6; - register uint64_t a7 __asm__("a7") = args.a7; - switch ((width + 7) / 8) { - case 0: - __asm__ volatile("ecall" : "=r"(t0)); - break; - case 1: - __asm__ volatile("ecall" : "=r"(t0), "+r"(a0)); - break; - case 2: - __asm__ volatile("ecall" : "=r"(t0), "+r"(a0) : "r"(a1)); - break; - case 3: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2)); - break; - case 4: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2), "r"(a3)); - break; - case 5: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2), "r"(a3), "r"(a4)); - break; - case 6: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)); - break; - case 7: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), - "r"(a6)); - break; - case 8: - __asm__ volatile("ecall" - : "=r"(t0), "+r"(a0) - : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), - "r"(a6), "r"(a7)); - break; - } - return (s3k_ret_t){.err = t0, .val = a0}; -} +#define DO_ECALL(call, args, width) \ + ({ \ + register uint64_t t0 __asm__("t0") = call; \ + register uint64_t a0 __asm__("a0") = args.a0; \ + register uint64_t a1 __asm__("a1") = args.a1; \ + register uint64_t a2 __asm__("a2") = args.a2; \ + register uint64_t a3 __asm__("a3") = args.a3; \ + register uint64_t a4 __asm__("a4") = args.a4; \ + register uint64_t a5 __asm__("a5") = args.a5; \ + register uint64_t a6 __asm__("a6") = args.a6; \ + register uint64_t a7 __asm__("a7") = args.a7; \ + switch ((width + 7) / 8) { \ + case 0: \ + __asm__ volatile("ecall" : "+r"(t0)); \ + break; \ + case 1: \ + __asm__ volatile("ecall" : "+r"(t0), "+r"(a0)); \ + break; \ + case 2: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1)); \ + break; \ + case 3: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2)); \ + break; \ + case 4: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a3)); \ + break; \ + case 5: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a3), \ + "r"(a4)); \ + break; \ + case 6: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a3), "r"(a4), \ + "r"(a5)); \ + break; \ + case 7: \ + __asm__ volatile("ecall" \ + : "+r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a3), "r"(a4), \ + "r"(a5), "r"(a6)); \ + break; \ + case 8: \ + __asm__ volatile("ecall" \ + : "=r"(t0), "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a3), "r"(a4), \ + "r"(a5), "r"(a6), "r"(a7)); \ + break; \ + } \ + (s3k_ret_t){.err = t0, .val = a0}; \ + }) uint64_t s3k_get_pid(void) { - sys_args_t args = { - .get_info = {S3K_SYS_GET_INFO, 0} - }; - return do_ecall(args, sizeof(args.get_info)).val; + sys_args_t args = {.get_info = {0}}; + return DO_ECALL(S3K_SYS_GET_INFO, args, sizeof(args.get_info)).val; } uint64_t s3k_get_time(void) { - sys_args_t args = { - .get_info = {S3K_SYS_GET_INFO, 1} - }; - return do_ecall(args, sizeof(args.get_info)).val; + sys_args_t args = {.get_info = {1}}; + return DO_ECALL(S3K_SYS_GET_INFO, args, sizeof(args.get_info)).val; } uint64_t s3k_get_timeout(void) { - sys_args_t args = { - .get_info = {S3K_SYS_GET_INFO, 2} - }; - return do_ecall(args, sizeof(args.get_info)).val; + sys_args_t args = {.get_info = {2}}; + return DO_ECALL(S3K_SYS_GET_INFO, args, sizeof(args.get_info)).val; } uint64_t s3k_get_wcet(bool reset) { - sys_args_t args = { - .get_info = {S3K_SYS_GET_INFO, reset ? 4 : 3} - }; - return do_ecall(args, sizeof(args.get_info)).val; + sys_args_t args = {.get_info = {reset ? 4 : 3}}; + return DO_ECALL(S3K_SYS_GET_INFO, args, sizeof(args.get_info)).val; } uint64_t s3k_reg_read(s3k_reg_t reg) { - sys_args_t args = { - .reg = {S3K_SYS_REG_READ, reg} - }; - return do_ecall(args, sizeof(args.reg)).val; + sys_args_t args = {.reg_read = {reg}}; + return DO_ECALL(S3K_SYS_REG_READ, args, sizeof(args.reg_read)).val; } uint64_t s3k_reg_write(s3k_reg_t reg, uint64_t val) { sys_args_t args = { - .reg = {S3K_SYS_REG_WRITE, reg, val} - }; - return do_ecall(args, sizeof(args.reg)).val; + .reg_write = {reg, val} + }; + return DO_ECALL(S3K_SYS_REG_WRITE, args, sizeof(args.reg_write)).val; } void s3k_sync(void) { - sys_args_t args = { - .sync = {S3K_SYS_SYNC, true} - }; - do_ecall(args, sizeof(args.sync)); + sys_args_t args = {.sync = {true}}; + DO_ECALL(S3K_SYS_SYNC, args, sizeof(args.sync)); } void s3k_sync_mem(void) { - sys_args_t args = { - .sync = {S3K_SYS_SYNC, false} - }; - do_ecall(args, sizeof(args.sync)); + sys_args_t args = {.sync = {false}}; + DO_ECALL(S3K_SYS_SYNC, args, sizeof(args.sync)); +} + +void s3k_sleep(uint64_t time) +{ + sys_args_t args = {.sleep = {time}}; + DO_ECALL(S3K_SYS_SLEEP, args, sizeof(args.sleep)); } s3k_err_t s3k_cap_read(s3k_cidx_t idx, s3k_cap_t *cap) { - sys_args_t args = { - .cap = {S3K_SYS_CAP_READ, idx} - }; - s3k_ret_t ret = do_ecall(args, sizeof(args.cap)); - if (!ret.err) - cap->raw = ret.val; + sys_args_t args = {.cap_read = {idx}}; + s3k_ret_t ret = DO_ECALL(S3K_SYS_CAP_READ, args, sizeof(args.cap_read)); + cap->raw = ret.val; return ret.err; } @@ -434,74 +463,69 @@ s3k_reply_t s3k_sock_sendrecv(s3k_cidx_t sock_idx, const s3k_msg_t *msg) s3k_err_t s3k_try_cap_move(s3k_cidx_t src, s3k_cidx_t dst) { sys_args_t args = { - .cap = {S3K_SYS_CAP_MOVE, src, dst} - }; - return do_ecall(args, sizeof(args.cap)).err; + .cap_move = {src, dst} + }; + return DO_ECALL(S3K_SYS_CAP_MOVE, args, sizeof(args.cap_move)).err; } s3k_err_t s3k_try_cap_delete(s3k_cidx_t idx) { - sys_args_t args = { - .cap = {S3K_SYS_CAP_DELETE, idx} - }; - return do_ecall(args, sizeof(args.cap)).err; + const sys_args_t args = {.cap_delete = {idx}}; + return DO_ECALL(S3K_SYS_CAP_DELETE, args, sizeof(args.cap_delete)).err; } s3k_err_t s3k_try_cap_revoke(s3k_cidx_t idx) { - sys_args_t args = { - .cap = {S3K_SYS_CAP_REVOKE, idx} - }; - return do_ecall(args, sizeof(args.cap)).err; + sys_args_t args = {.cap_revoke = {idx}}; + return DO_ECALL(S3K_SYS_CAP_REVOKE, args, sizeof(args.cap_revoke)).err; } s3k_err_t s3k_try_cap_derive(s3k_cidx_t src, s3k_cidx_t dst, s3k_cap_t ncap) { sys_args_t args = { - .cap = {S3K_SYS_CAP_DERIVE, src, dst, ncap} - }; - return do_ecall(args, sizeof(args.cap)).err; + .cap_derive = {src, dst, ncap.raw} + }; + return DO_ECALL(S3K_SYS_CAP_DERIVE, args, sizeof(args.cap_derive)).err; } s3k_err_t s3k_try_pmp_load(s3k_cidx_t idx, s3k_pmp_slot_t slot) { sys_args_t args = { - .pmp = {S3K_SYS_PMP_LOAD, idx, slot} - }; - return do_ecall(args, sizeof(args.pmp)).err; + .pmp_load = {idx, slot} + }; + return DO_ECALL(S3K_SYS_PMP_LOAD, args, sizeof(args.pmp_load)).err; } s3k_err_t s3k_try_pmp_unload(s3k_cidx_t idx) { - sys_args_t args = { - .pmp = {S3K_SYS_PMP_UNLOAD, idx} - }; - return do_ecall(args, sizeof(args.pmp)).err; + sys_args_t args = {.pmp_unload = {idx}}; + return DO_ECALL(S3K_SYS_PMP_UNLOAD, args, sizeof(args.pmp_unload)).err; } s3k_err_t s3k_try_mon_suspend(s3k_cidx_t mon, s3k_pid_t pid) { sys_args_t args = { - .mon_state = {S3K_SYS_MON_SUSPEND, mon, pid} - }; - return do_ecall(args, sizeof(args.mon_state)).err; + .mon_state = {mon, pid} + }; + return DO_ECALL(S3K_SYS_MON_SUSPEND, args, sizeof(args.mon_state)).err; } s3k_err_t s3k_try_mon_resume(s3k_cidx_t mon, s3k_pid_t pid) { sys_args_t args = { - .mon_state = {S3K_SYS_MON_RESUME, mon, pid} - }; - return do_ecall(args, sizeof(args.mon_state)).err; + .mon_state = {mon, pid} + }; + return DO_ECALL(S3K_SYS_MON_RESUME, args, sizeof(args.mon_state)).err; } s3k_err_t s3k_try_mon_state_get(s3k_cidx_t mon, s3k_pid_t pid, s3k_state_t *state) { sys_args_t args = { - .mon_state = {S3K_SYS_MON_STATE_GET, mon, pid} - }; - s3k_ret_t ret = do_ecall(args, sizeof(args.mon_state)); + .mon_state = {mon, pid} + }; + s3k_ret_t ret + = DO_ECALL(S3K_SYS_MON_STATE_GET, args, sizeof(args.mon_state)); *state = ret.val; return ret.err; } @@ -509,18 +533,19 @@ s3k_err_t s3k_try_mon_state_get(s3k_cidx_t mon, s3k_pid_t pid, s3k_err_t s3k_try_mon_yield(s3k_cidx_t mon, s3k_pid_t pid) { sys_args_t args = { - .mon_state = {S3K_SYS_MON_YIELD, mon, pid} - }; - return do_ecall(args, sizeof(args.mon_state)).err; + .mon_state = {mon, pid} + }; + return DO_ECALL(S3K_SYS_MON_YIELD, args, sizeof(args.mon_state)).err; } s3k_err_t s3k_try_mon_reg_read(s3k_cidx_t mon, s3k_pid_t pid, s3k_reg_t reg, uint64_t *val) { sys_args_t args = { - .mon_reg = {S3K_SYS_MON_REG_READ, mon, pid, reg} - }; - s3k_ret_t ret = do_ecall(args, sizeof(args.mon_reg)); + .mon_reg_read = {mon, pid, reg} + }; + s3k_ret_t ret + = DO_ECALL(S3K_SYS_MON_REG_READ, args, sizeof(args.mon_reg_read)); *val = ret.val; return ret.err; } @@ -529,9 +554,10 @@ s3k_err_t s3k_try_mon_reg_write(s3k_cidx_t mon, s3k_pid_t pid, s3k_reg_t reg, uint64_t val) { sys_args_t args = { - .mon_reg = {S3K_SYS_MON_REG_WRITE, mon, pid, reg, val} - }; - s3k_ret_t ret = do_ecall(args, sizeof(args.mon_reg)); + .mon_reg_write = {mon, pid, reg, val} + }; + s3k_ret_t ret + = DO_ECALL(S3K_SYS_MON_REG_WRITE, args, sizeof(args.mon_reg_write)); return ret.err; } @@ -539,9 +565,10 @@ s3k_err_t s3k_try_mon_cap_read(s3k_cidx_t mon_idx, s3k_pid_t pid, s3k_cidx_t idx, s3k_cap_t *cap) { sys_args_t args = { - .mon_cap = {S3K_SYS_MON_CAP_READ, mon_idx, pid, idx} - }; - s3k_ret_t ret = do_ecall(args, sizeof(args.mon_cap)); + .mon_cap_read = {mon_idx, pid, idx} + }; + s3k_ret_t ret + = DO_ECALL(S3K_SYS_MON_CAP_READ, args, sizeof(args.mon_cap_read)); if (!ret.err) cap->raw = ret.val; return ret.err; @@ -552,49 +579,50 @@ s3k_err_t s3k_try_mon_cap_move(s3k_cidx_t mon_idx, s3k_pid_t src_pid, s3k_cidx_t dst_idx) { sys_args_t args = { - .mon_cap = {S3K_SYS_MON_CAP_MOVE, mon_idx, src_pid, src_idx, - dst_pid, dst_idx} + .mon_cap_move = {mon_idx, src_pid, src_idx, dst_pid, dst_idx} }; - return do_ecall(args, sizeof(args.mon_cap)).err; + return DO_ECALL(S3K_SYS_MON_CAP_MOVE, args, sizeof(args.mon_cap_move)) + .err; } s3k_err_t s3k_try_mon_pmp_load(s3k_cidx_t mon_idx, s3k_pid_t pid, - s3k_cidx_t pmp_idx, s3k_pmp_slot_t pmp_slot) + s3k_cidx_t idx, s3k_pmp_slot_t slot) { sys_args_t args = { - .mon_pmp = {S3K_SYS_MON_PMP_LOAD, mon_idx, pid, pmp_idx, pmp_slot} - }; - return do_ecall(args, sizeof(args.mon_pmp)).err; + .mon_pmp_load = {mon_idx, pid, idx, slot} + }; + return DO_ECALL(S3K_SYS_MON_PMP_LOAD, args, sizeof(args.mon_pmp_load)) + .err; } s3k_err_t s3k_try_mon_pmp_unload(s3k_cidx_t mon_idx, s3k_pid_t pid, - s3k_cidx_t pmp_idx) + s3k_cidx_t idx) { sys_args_t args = { - .mon_pmp = {S3K_SYS_MON_PMP_UNLOAD, mon_idx, pid, pmp_idx} - }; - return do_ecall(args, sizeof(args.mon_pmp)).err; + .mon_pmp_unload = {mon_idx, pid, idx} + }; + return DO_ECALL(S3K_SYS_MON_PMP_UNLOAD, args, + sizeof(args.mon_pmp_unload)) + .err; } s3k_err_t s3k_try_sock_send(s3k_cidx_t sock_idx, const s3k_msg_t *msg) { sys_args_t args = { - .sock = {S3K_SYS_SOCK_SEND, - .sock_idx = sock_idx, + .sock = {.sock_idx = sock_idx, .cap_idx = msg->cap_idx, .send_cap = msg->send_cap, {msg->data[0], msg->data[1], msg->data[2], msg->data[3]}} }; - return do_ecall(args, sizeof(args.sock)).err; + return DO_ECALL(S3K_SYS_SOCK_SEND, args, sizeof(args.sock)).err; } s3k_reply_t s3k_try_sock_recv(s3k_cidx_t sock_idx, s3k_cidx_t cap_idx) { sys_args_t args = { - .sock = {S3K_SYS_SOCK_SENDRECV, .sock_idx = sock_idx, - .cap_idx = cap_idx} - }; - register uint64_t t0 __asm__("t0"); + .sock = {.sock_idx = sock_idx, .cap_idx = cap_idx} + }; + register uint64_t t0 __asm__("t0") = S3K_SYS_SOCK_SENDRECV; register uint64_t a0 __asm__("a0") = args.a0; register uint64_t a1 __asm__("a1") = args.a1; register uint64_t a2 __asm__("a2") = args.a2; @@ -621,13 +649,12 @@ s3k_reply_t s3k_try_sock_recv(s3k_cidx_t sock_idx, s3k_cidx_t cap_idx) s3k_reply_t s3k_try_sock_sendrecv(s3k_cidx_t sock_idx, const s3k_msg_t *msg) { sys_args_t args = { - .sock = {S3K_SYS_SOCK_SENDRECV, - .sock_idx = sock_idx, + .sock = {.sock_idx = sock_idx, .cap_idx = msg->cap_idx, .send_cap = msg->send_cap, {msg->data[0], msg->data[1], msg->data[2], msg->data[3]}} }; - register uint64_t t0 __asm__("t0"); + register uint64_t t0 __asm__("t0") = S3K_SYS_SOCK_SENDRECV; register uint64_t a0 __asm__("a0") = args.a0; register uint64_t a1 __asm__("a1") = args.a1; register uint64_t a2 __asm__("a2") = args.a2; diff --git a/kernel/inc/kassert.h b/kernel/inc/kassert.h index cbdefd33..369bbb2f 100644 --- a/kernel/inc/kassert.h +++ b/kernel/inc/kassert.h @@ -18,26 +18,23 @@ #ifndef NDEBUG #define KASSERT_FAILURE(FILE, LINE) \ - kprintf("Kernel assertion failed at %s:%d.\n", FILE, LINE); + kprintf(0, "Kernel assertion failed at %s:%d.\n", FILE, LINE); -#define KASSERT(EXPR) \ - do { \ - if (!(EXPR)) { \ - KASSERT_FAILURE(__FILE__, __LINE__); \ - while (1) \ - ; \ - } \ +#define KASSERT(expr) \ + do { \ + if (expr) \ + break; \ + KASSERT_FAILURE(__FILE__, __LINE__); \ + while (1) \ + ; \ } while (false) #else /* NDEBUG */ #define KASSERT(expr) \ do { \ - if (!(expr)) { \ + if (!(expr)) \ __builtin_unreachable(); \ - while (1) \ - ; \ - } \ } while (false) #endif /* NDEBUG */ diff --git a/kernel/inc/kprintf.h b/kernel/inc/kprintf.h index 93404244..a54137ca 100644 --- a/kernel/inc/kprintf.h +++ b/kernel/inc/kprintf.h @@ -1,3 +1,4 @@ #pragma once -void kputstr(char *s); -void kprintf(char *restrict fmt, ...); +#include + +void kprintf(int verbosity, char *const restrict fmt, ...); diff --git a/kernel/inc/syscall.h b/kernel/inc/syscall.h index f34c340e..7cd88e78 100644 --- a/kernel/inc/syscall.h +++ b/kernel/inc/syscall.h @@ -12,6 +12,7 @@ typedef enum { SYS_REG_READ, // Set the value of a specific register SYS_REG_WRITE, // Get the value of a specific register SYS_SYNC, // Synchronize with capabilities/scheduling + SYS_SLEEP, // Capability Management SYS_CAP_READ, // Read the properties of a capability @@ -43,77 +44,112 @@ typedef enum { } syscall_t; typedef union { - syscall_t call; - struct { uint64_t a0, a1, a2, a3, a4, a5, a6, a7; }; struct { - syscall_t call; - int info; + uint64_t info; } get_info; struct { - syscall_t call; - regnr_t reg; + uint64_t reg; + } reg_read; + + struct { + uint64_t reg; uint64_t val; - } reg; + } reg_write; struct { - syscall_t call; - bool full; + uint64_t full; } sync; struct { - syscall_t call; - cidx_t idx; - cidx_t dst_idx; - cap_t cap; - } cap; + uint64_t time; + } sleep; + + struct { + uint64_t idx; + } cap_read; + + struct { + uint64_t src_idx; + uint64_t dst_idx; + } cap_move; + + struct { + uint64_t idx; + } cap_delete; + + struct { + uint64_t idx; + } cap_revoke; struct { - syscall_t call; - cidx_t idx; - pmp_slot_t slot; - } pmp; + uint64_t src_idx; + uint64_t dst_idx; + uint64_t cap_raw; + } cap_derive; struct { - syscall_t call; - cidx_t mon_idx; - pid_t pid; + uint64_t idx; + uint64_t slot; + } pmp_load; + + struct { + uint64_t idx; + } pmp_unload; + + struct { + uint64_t mon_idx; + uint64_t pid; } mon_state; struct { - syscall_t call; - cidx_t mon_idx; - pid_t pid; - regnr_t reg; + uint64_t mon_idx; + uint64_t pid; + uint64_t reg; + } mon_reg_read; + + struct { + uint64_t mon_idx; + uint64_t pid; + uint64_t reg; uint64_t val; - } mon_reg; + } mon_reg_write; + + struct { + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + } mon_cap_read; + + struct { + uint64_t mon_idx; + uint64_t src_pid; + uint64_t src_idx; + uint64_t dst_pid; + uint64_t dst_idx; + } mon_cap_move; struct { - syscall_t call; - cidx_t mon_idx; - pid_t pid; - cidx_t idx; - pid_t dst_pid; - cidx_t dst_idx; - } mon_cap; + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + uint64_t slot; + } mon_pmp_load; struct { - syscall_t call; - cidx_t mon_idx; - pid_t pid; - cidx_t pmp_idx; - pmp_slot_t pmp_slot; - } mon_pmp; + uint64_t mon_idx; + uint64_t pid; + uint64_t idx; + } mon_pmp_unload; struct { - syscall_t call; - cidx_t sock_idx; - cidx_t cap_idx; - bool send_cap; + uint64_t sock_idx; + uint64_t cap_idx; + uint64_t send_cap; uint64_t data[4]; } sock; } sys_args_t; diff --git a/kernel/src/cap_ipc.c b/kernel/src/cap_ipc.c index 09eefac1..ae83eb6c 100644 --- a/kernel/src/cap_ipc.c +++ b/kernel/src/cap_ipc.c @@ -61,8 +61,10 @@ static err_t do_send(cap_t cap, const ipc_msg_t *msg, proc_t **next) cap_move(msg->cap_buf, cap_buf); if (cap.sock.mode == IPC_YIELD) { + recv->timeout = (*next)->timeout; *next = recv; } else { + recv->timeout = 0; proc_release(recv); } return SUCCESS; diff --git a/kernel/src/cap_table.c b/kernel/src/cap_table.c index ee49f46a..0c7423e5 100644 --- a/kernel/src/cap_table.c +++ b/kernel/src/cap_table.c @@ -21,15 +21,11 @@ void ctable_init(void) { const cap_t init_caps[] = INIT_CAPS; cte_t prev = ctable; -#if !defined(NDEBUG) && VERBOSE > 0 - kputstr("> Initial capabilities:\n"); -#endif + kprintf(0, "> Initial capabilities:\n"); for (unsigned int i = 0; i < ARRAY_SIZE(init_caps); ++i) { -#if !defined(NDEBUG) && VERBOSE > 0 char buf[128]; cap_snprint(buf, 128, init_caps[i]); - kprintf(" %d: %s\n", i, buf); -#endif + kprintf(0, " %d: %s\n", i, buf); cte_insert(&ctable[i], init_caps[i], prev); } } diff --git a/kernel/src/exception.c b/kernel/src/exception.c index 8a0a9ca4..f9db571b 100644 --- a/kernel/src/exception.c +++ b/kernel/src/exception.c @@ -14,10 +14,8 @@ proc_t *handle_exception(proc_t *p) { -#if !defined(NDEBUG) && VERBOSE > 1 - kprintf("handle_exception(pid=%X,mcause=%X,mtval=%X,mepc=%X)", p->pid, - csrr(mcause), csrr(mtval), csrr(mepc)); -#endif + kprintf(1, "> handle_exception(pid=%X,mcause=%X,mtval=%X,mepc=%X)\n", + p->pid, csrr(mcause), csrr(mtval), csrr(mepc)); /* Check if it is a return from exception */ p->regs[REG_ECAUSE] = csrr(mcause); p->regs[REG_EVAL] = csrr(mtval); @@ -34,6 +32,8 @@ proc_t *handle_exception(proc_t *p) static proc_t *handle_trap_return(proc_t *p) { + kprintf(1, "> handle_trap_return(pid=%X)\n", + p->pid); p->regs[REG_PC] = p->regs[REG_EPC]; p->regs[REG_SP] = p->regs[REG_ESP]; p->regs[REG_ECAUSE] = 0; diff --git a/kernel/src/head.S b/kernel/src/head.S index 6270899b..f411dd6d 100644 --- a/kernel/src/head.S +++ b/kernel/src/head.S @@ -15,37 +15,6 @@ .type _start, @function _start: head_entry: - li x1,0 - li x2,0 - li x3,0 - li x4,0 - li x5,0 - li x6,0 - li x7,0 - li x8,0 - li x9,0 - li x10,0 - li x11,0 - li x12,0 - li x13,0 - li x14,0 - li x15,0 - li x16,0 - li x17,0 - li x18,0 - li x19,0 - li x20,0 - li x21,0 - li x22,0 - li x23,0 - li x24,0 - li x25,0 - li x26,0 - li x27,0 - li x28,0 - li x29,0 - li x30,0 - li x31,0 /* Load global pointer */ ld_gp ld_sp t1 @@ -96,6 +65,7 @@ head_exit: # Enable timer interrupts li t0,MIE_MTIE csrw mie,t0 + #ifdef INSTRUMENT csrw mcounteren,0xF csrw scounteren,0xF diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index 67b74987..b9cf5069 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -16,17 +16,17 @@ static uint64_t wcet; void kernel_init(void) { alt_init(); - alt_puts("> uart initialized"); + kprintf(0, "> uart initialized\n"); mcslock_init(&lock); - alt_puts("> mcslock initialized"); + kprintf(0, "> mcslock initialized\n"); ctable_init(); - alt_puts("> ctable initialized"); + kprintf(0, "> ctable initialized\n"); sched_init(); - alt_puts("> scheduler initialized"); + kprintf(0, "> scheduler initialized\n"); proc_init(); - alt_puts("> processes initialized"); - alt_puts("> kernel initialization complete"); - alt_puts("> starting boot process"); + kprintf(0, "> processes initialized\n"); + kprintf(0, "> kernel initialization complete\n"); + kprintf(0, "> starting boot process\n"); } uint64_t kernel_wcet(void) @@ -54,7 +54,7 @@ void kernel_lock_release(void) bool kernel_preempt(void) { #ifndef NPREEMPT - return csrr(mip) & csrr(mie); + return csrr(mip) & 0x80; #else return false; #endif diff --git a/kernel/src/kprintf.c b/kernel/src/kprintf.c index b79f25c2..35242e83 100644 --- a/kernel/src/kprintf.c +++ b/kernel/src/kprintf.c @@ -5,21 +5,26 @@ #define BUF_SIZE 128 -void kputstr(char *buf) +#if defined(NDEBUG) || !defined(VERBOSITY) +#undef VERBOSITY +#define VERBOSITY 0 +#endif + +void kprintf(int verbosity, char *restrict fmt, ...) { static int lock = 0; - while (__atomic_fetch_or(&lock, 1, __ATOMIC_ACQUIRE)) - ; - alt_putstr(buf); - __atomic_store_n(&lock, 0, __ATOMIC_RELEASE); -} -void kprintf(char *restrict fmt, ...) -{ + if (verbosity > VERBOSITY) + return; + char buf[BUF_SIZE]; va_list ap; va_start(ap, fmt); alt_vsnprintf(buf, BUF_SIZE, fmt, ap); va_end(ap); - kputstr(buf); + + while (__atomic_fetch_or(&lock, 1, __ATOMIC_ACQUIRE)) + ; + alt_putstr(buf); + __atomic_store_n(&lock, 0, __ATOMIC_RELEASE); } diff --git a/kernel/src/proc.c b/kernel/src/proc.c index 34d8966f..98eb97cd 100644 --- a/kernel/src/proc.c +++ b/kernel/src/proc.c @@ -17,7 +17,7 @@ void proc_init(void) } _processes[0].state = 0; _processes[0].regs[REG_PC] = (uint64_t)_payload; - kprintf("> boot process pc=0x%X\n", _payload); + kprintf(0, "> boot process pc=0x%X\n", _payload); KASSERT(cap_pmp_load(ctable_get(0, 0), 0) == SUCCESS); } @@ -44,7 +44,7 @@ bool proc_acquire(proc_t *proc) if (expected & (PSF_BUSY | PSF_SUSPENDED)) return false; - if ((expected == PSF_BLOCKED) && time_get() < proc->timeout) + if (time_get() < proc->timeout) return false; return __atomic_compare_exchange(&proc->state, &expected, &desired, @@ -70,6 +70,8 @@ void proc_suspend(proc_t *proc) void proc_resume(proc_t *proc) { + if (proc->state == PSF_SUSPENDED) + proc->timeout = 0; __atomic_fetch_and(&proc->state, ~PSF_SUSPENDED, __ATOMIC_RELAXED); } diff --git a/kernel/src/sched.c b/kernel/src/sched.c index 735cd27d..7598836d 100644 --- a/kernel/src/sched.c +++ b/kernel/src/sched.c @@ -14,9 +14,9 @@ typedef struct slot_info { // Owner of time slot. - uint32_t pid; + uint8_t pid; // Remaining length of corresponding slice. - uint32_t length; + uint8_t length; } slot_info_t; struct sched_decision { @@ -24,7 +24,7 @@ struct sched_decision { uint64_t end_time; }; -static slot_info_t slots[S3K_HART_CNT][S3K_SLOT_CNT]; +static uint64_t slots[S3K_SLOT_CNT]; static semaphore_t sched_semaphore; void sched_init(void) @@ -45,13 +45,14 @@ void sched_update(uint64_t pid, uint64_t end, uint64_t hart, uint64_t from, { // Acquire all resources, blocking everyone else. semaphore_acquire_n(&sched_semaphore, S3K_HART_CNT); -#if !defined(NDEBUG) && VERBOSE > 0 - kprintf("> sched_update(pid=%D,end=%D,hart=%D,from=%D,to=%D)\n", pid, + kprintf(1, "> sched_update(pid=%D,end=%D,hart=%D,from=%D,to=%D)\n", pid, end, hart, from, to); -#endif + hart -= S3K_MIN_HART; + int offset = hart * 16; + uint64_t mask = 0xFFFFull << offset; for (uint64_t i = from; i < to; i++) { - slots[hart - S3K_MIN_HART][i].pid = pid & 0xFF; - slots[hart - S3K_MIN_HART][i].length = (end - i) & 0xFF; + slots[i] &= ~mask; + slots[i] |= ((pid << 8) | (end - from)) << offset; } // Release the resources. semaphore_release_n(&sched_semaphore, S3K_HART_CNT); @@ -60,20 +61,22 @@ void sched_update(uint64_t pid, uint64_t end, uint64_t hart, uint64_t from, void sched_delete(uint64_t hart, uint64_t from, uint64_t to) { semaphore_acquire_n(&sched_semaphore, S3K_HART_CNT); -#if !defined(NDEBUG) && VERBOSE > 0 - kprintf("> sched_delete(hart=%D,from=%D,to=%D)\n", hart, from, to); -#endif - for (uint64_t i = from; i < to; ++i) { - slots[hart - S3K_MIN_HART][i].pid = 0; - slots[hart - S3K_MIN_HART][i].length = 0; - } + kprintf(1, "> sched_delete(hart=%D,from=%D,to=%D)\n", hart, from, to); + hart -= S3K_MIN_HART; + int offset = hart * 16; + uint64_t mask = 0xFFFFull << offset; + for (uint64_t i = from; i < to; ++i) + slots[i] &= ~mask; // Release the resources. semaphore_release_n(&sched_semaphore, S3K_HART_CNT); } slot_info_t slot_info_get(uint64_t hartid, uint64_t slot) { - return slots[hartid - S3K_MIN_HART][slot % S3K_SLOT_CNT]; + uint64_t x = slots[slot % S3K_SLOT_CNT]; + x >>= (hartid - S3K_MIN_HART) * 16; + x &= 0xFFFF; + return (slot_info_t){.pid = (x >> 8) & 0xFF, .length = x & 0xFF}; } static proc_t *sched_fetch(uint64_t hart, uint64_t slot) @@ -107,32 +110,32 @@ static proc_t *sched_fetch(uint64_t hart, uint64_t slot) // Try to acquire the process. if (!proc_acquire(p)) return NULL; -#if !defined(NDEBUG) && VERBOSE > 1 - kprintf("> sched(hart=%d,pid=%d,slot=%D)\n", hart, si.pid, + kprintf(2, "> sched(hart=%d,pid=%d,slot=%D)\n", hart, si.pid, slot % S3K_SLOT_CNT); -#endif p->timeout = (slot + si.length) * S3K_SLOT_LEN; return p; } proc_t *sched(void) { - // Get hart ID + // Hart ID uint64_t hart = csrr(mhartid); - // Get next time slot + // Time slot uint64_t slot = (time_get() + S3K_SCHED_TIME) / S3K_SLOT_LEN; // Process to run - proc_t *next = NULL; - while (!next) { + proc_t *next; + + do { while (time_get() < slot * S3K_SLOT_LEN) ; // Try schedule process semaphore_acquire(&sched_semaphore); next = sched_fetch(hart, slot); semaphore_release(&sched_semaphore); - // Increment time slot if necessary. slot++; - } + } while (!next); + timeout_set(hart, next->timeout - S3K_SCHED_TIME); + return next; } diff --git a/kernel/src/syscall.c b/kernel/src/syscall.c index 82715d94..c84c025f 100644 --- a/kernel/src/syscall.c +++ b/kernel/src/syscall.c @@ -19,11 +19,11 @@ #define ARGS 8 -static err_t validate_arguments(const sys_args_t *); static inline err_t validate_get_info(const sys_args_t *); static inline err_t validate_reg_read(const sys_args_t *); static inline err_t validate_reg_write(const sys_args_t *); static inline err_t validate_sync(const sys_args_t *); +static inline err_t validate_sleep(const sys_args_t *); static inline err_t validate_cap_read(const sys_args_t *); static inline err_t validate_cap_move(const sys_args_t *); static inline err_t validate_cap_delete(const sys_args_t *); @@ -49,6 +49,7 @@ static proc_t *handle_get_info(proc_t *const, const sys_args_t *); static proc_t *handle_reg_read(proc_t *const, const sys_args_t *); static proc_t *handle_reg_write(proc_t *const, const sys_args_t *); static proc_t *handle_sync(proc_t *const, const sys_args_t *); +static proc_t *handle_sleep(proc_t *const, const sys_args_t *); static proc_t *handle_cap_read(proc_t *const, const sys_args_t *); static proc_t *handle_cap_move(proc_t *const, const sys_args_t *); static proc_t *handle_cap_delete(proc_t *const, const sys_args_t *); @@ -74,40 +75,48 @@ typedef proc_t *(*handler_t)(proc_t *const, const sys_args_t *); typedef err_t (*validator_t)(const sys_args_t *); handler_t handlers[] = { - handle_get_info, handle_reg_read, handle_reg_write, - handle_sync, handle_cap_read, handle_cap_move, - handle_cap_delete, handle_cap_revoke, handle_cap_derive, - handle_pmp_load, handle_pmp_unload, handle_mon_suspend, - handle_mon_resume, handle_mon_state_get, handle_mon_yield, - handle_mon_reg_read, handle_mon_reg_write, handle_mon_cap_read, - handle_mon_cap_move, handle_mon_pmp_load, handle_mon_pmp_unload, - handle_sock_send, handle_sock_recv, handle_sock_sendrecv, + handle_get_info, handle_reg_read, handle_reg_write, + handle_sync, handle_sleep, handle_cap_read, + handle_cap_move, handle_cap_delete, handle_cap_revoke, + handle_cap_derive, handle_pmp_load, handle_pmp_unload, + handle_mon_suspend, handle_mon_resume, handle_mon_state_get, + handle_mon_yield, handle_mon_reg_read, handle_mon_reg_write, + handle_mon_cap_read, handle_mon_cap_move, handle_mon_pmp_load, + handle_mon_pmp_unload, handle_sock_send, handle_sock_recv, + handle_sock_sendrecv, }; validator_t validators[] = { - validate_get_info, validate_reg_read, validate_reg_write, - validate_sync, validate_cap_read, validate_cap_move, - validate_cap_delete, validate_cap_revoke, validate_cap_derive, - validate_pmp_load, validate_pmp_unload, validate_mon_suspend, - validate_mon_resume, validate_mon_state_get, validate_mon_yield, - validate_mon_reg_read, validate_mon_reg_write, validate_mon_cap_read, - validate_mon_cap_move, validate_mon_pmp_load, validate_mon_pmp_unload, - validate_sock_send, validate_sock_recv, validate_sock_sendrecv, + validate_get_info, validate_reg_read, validate_reg_write, + validate_sync, validate_sleep, validate_cap_read, + validate_cap_move, validate_cap_delete, validate_cap_revoke, + validate_cap_derive, validate_pmp_load, validate_pmp_unload, + validate_mon_suspend, validate_mon_resume, validate_mon_state_get, + validate_mon_yield, validate_mon_reg_read, validate_mon_reg_write, + validate_mon_cap_read, validate_mon_cap_move, validate_mon_pmp_load, + validate_mon_pmp_unload, validate_sock_send, validate_sock_recv, + validate_sock_sendrecv, }; proc_t *handle_syscall(proc_t *proc) { // System call arguments. const sys_args_t *args = (sys_args_t *)&proc->regs[REG_A0]; + uint64_t call = proc->regs[REG_T0]; // Validate system call arguments. - err_t err = validate_arguments(args); + err_t err = ERR_INVALID_SYSCALL; + if (call < ARRAY_SIZE(validators)) + err = validators[call](args); + + if (kernel_preempt()) + return NULL; // Increment PC proc->regs[REG_PC] += 4; proc->regs[REG_T0] = err; if (!err) // If arguments valid, perform system call. - proc = handlers[args->call](proc, args); + proc = handlers[call](proc, args); return proc; } @@ -131,13 +140,6 @@ static bool valid_reg(reg_t reg) return reg < REG_CNT; } -static err_t validate_arguments(const sys_args_t *args) -{ - if (args->call < ARRAY_SIZE(validators)) - return validators[args->call](args); - return ERR_INVALID_SYSCALL; -} - err_t validate_get_info(const sys_args_t *args) { return SUCCESS; @@ -170,27 +172,27 @@ proc_t *handle_get_info(proc_t *const p, const sys_args_t *args) err_t validate_reg_read(const sys_args_t *args) { - if (!valid_reg(args->reg.reg)) + if (!valid_reg(args->reg_read.reg)) return ERR_INVALID_REGISTER; return SUCCESS; } proc_t *handle_reg_read(proc_t *const p, const sys_args_t *args) { - p->regs[REG_A0] = p->regs[args->reg.reg]; + p->regs[REG_A0] = p->regs[args->reg_read.reg]; return p; } err_t validate_reg_write(const sys_args_t *args) { - if (!valid_reg(args->reg.reg)) + if (!valid_reg(args->reg_write.reg)) return ERR_INVALID_REGISTER; return SUCCESS; } proc_t *handle_reg_write(proc_t *const p, const sys_args_t *args) { - p->regs[args->reg.reg] = args->reg.val; + p->regs[args->reg_write.reg] = args->reg_write.val; return p; } @@ -211,33 +213,45 @@ proc_t *handle_sync(proc_t *const p, const sys_args_t *args) return p; } +err_t validate_sleep(const sys_args_t *args) +{ + return SUCCESS; +} + +proc_t *handle_sleep(proc_t *const p, const sys_args_t *args) +{ + if (args->sleep.time) + p->timeout = args->sleep.time; + return NULL; +} + err_t validate_cap_read(const sys_args_t *args) { - if (!valid_idx(args->cap.idx)) + if (!valid_idx(args->cap_read.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_cap_read(proc_t *const p, const sys_args_t *args) { - cte_t c = ctable_get(p->pid, args->cap.idx); + cte_t c = ctable_get(p->pid, args->cap_read.idx); p->regs[REG_T0] = cap_read(c, (cap_t *)&p->regs[REG_A0]); return p; } err_t validate_cap_move(const sys_args_t *args) { - if (!valid_idx(args->cap.idx)) + if (!valid_idx(args->cap_move.src_idx)) return ERR_INVALID_INDEX; - if (!valid_idx(args->cap.dst_idx)) + if (!valid_idx(args->cap_move.dst_idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_cap_move(proc_t *const p, const sys_args_t *args) { - cte_t src = ctable_get(p->pid, args->cap.idx); - cte_t dst = ctable_get(p->pid, args->cap.dst_idx); + cte_t src = ctable_get(p->pid, args->cap_move.src_idx); + cte_t dst = ctable_get(p->pid, args->cap_move.dst_idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; @@ -248,14 +262,14 @@ proc_t *handle_cap_move(proc_t *const p, const sys_args_t *args) err_t validate_cap_delete(const sys_args_t *args) { - if (!valid_idx(args->cap.idx)) + if (!valid_idx(args->cap_delete.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_cap_delete(proc_t *const p, const sys_args_t *args) { - cte_t c = ctable_get(p->pid, args->cap.idx); + cte_t c = ctable_get(p->pid, args->cap_delete.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; @@ -266,14 +280,14 @@ proc_t *handle_cap_delete(proc_t *const p, const sys_args_t *args) err_t validate_cap_revoke(const sys_args_t *args) { - if (!valid_idx(args->cap.idx)) + if (!valid_idx(args->cap_revoke.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_cap_revoke(proc_t *const p, const sys_args_t *args) { - cte_t c = ctable_get(p->pid, args->cap.idx); + cte_t c = ctable_get(p->pid, args->cap_revoke.idx); p->regs[REG_T0] = ERR_PREEMPTED; err_t err; do { @@ -288,57 +302,59 @@ proc_t *handle_cap_revoke(proc_t *const p, const sys_args_t *args) err_t validate_cap_derive(const sys_args_t *args) { - if (!valid_idx(args->cap.idx)) + if (!valid_idx(args->cap_derive.src_idx)) return ERR_INVALID_INDEX; - if (!valid_idx(args->cap.dst_idx)) + if (!valid_idx(args->cap_derive.dst_idx)) return ERR_INVALID_INDEX; - if (!cap_is_valid(args->cap.cap)) + cap_t cap = { .raw = args->cap_derive.cap_raw }; + if (!cap_is_valid(cap)) return ERR_INVALID_DERIVATION; return SUCCESS; } proc_t *handle_cap_derive(proc_t *const p, const sys_args_t *args) { - cte_t src = ctable_get(p->pid, args->cap.idx); - cte_t dst = ctable_get(p->pid, args->cap.dst_idx); + cte_t src = ctable_get(p->pid, args->cap_derive.src_idx); + cte_t dst = ctable_get(p->pid, args->cap_derive.dst_idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; - p->regs[REG_T0] = cap_derive(src, dst, args->cap.cap); + cap_t cap = { .raw = args->cap_derive.cap_raw }; + p->regs[REG_T0] = cap_derive(src, dst, cap); kernel_lock_release(); return p; } err_t validate_pmp_load(const sys_args_t *args) { - if (!valid_idx(args->pmp.idx)) + if (!valid_idx(args->pmp_load.idx)) return ERR_INVALID_INDEX; - if (!valid_slot(args->pmp.slot)) + if (!valid_slot(args->pmp_load.slot)) return ERR_INVALID_SLOT; return SUCCESS; } proc_t *handle_pmp_load(proc_t *const p, const sys_args_t *args) { - cte_t pmp = ctable_get(p->pid, args->pmp.idx); + cte_t pmp = ctable_get(p->pid, args->pmp_load.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; - p->regs[REG_T0] = cap_pmp_load(pmp, args->pmp.slot); + p->regs[REG_T0] = cap_pmp_load(pmp, args->pmp_load.slot); kernel_lock_release(); return p; } err_t validate_pmp_unload(const sys_args_t *args) { - if (!valid_idx(args->pmp.idx)) + if (!valid_idx(args->pmp_unload.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_pmp_unload(proc_t *const p, const sys_args_t *args) { - cte_t pmp = ctable_get(p->pid, args->pmp.idx); + cte_t pmp = ctable_get(p->pid, args->pmp_unload.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; @@ -431,65 +447,67 @@ proc_t *handle_mon_yield(proc_t *const p, const sys_args_t *args) err_t validate_mon_reg_read(const sys_args_t *args) { - if (!valid_idx(args->mon_reg.mon_idx)) + if (!valid_idx(args->mon_reg_read.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_reg.pid)) + if (!valid_pid(args->mon_reg_read.pid)) return ERR_INVALID_PID; - if (!valid_reg(args->mon_reg.reg)) + if (!valid_reg(args->mon_reg_read.reg)) return ERR_INVALID_REGISTER; return SUCCESS; } proc_t *handle_mon_reg_read(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_reg.mon_idx); + cte_t mon = ctable_get(p->pid, args->mon_reg_read.mon_idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; - p->regs[REG_T0] = cap_monitor_reg_read( - mon, args->mon_reg.pid, args->mon_reg.reg, &p->regs[REG_A0]); + p->regs[REG_T0] = cap_monitor_reg_read(mon, args->mon_reg_read.pid, + args->mon_reg_read.reg, + &p->regs[REG_A0]); kernel_lock_release(); return p; } err_t validate_mon_reg_write(const sys_args_t *args) { - if (!valid_idx(args->mon_reg.mon_idx)) + if (!valid_idx(args->mon_reg_write.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_reg.pid)) + if (!valid_pid(args->mon_reg_write.pid)) return ERR_INVALID_PID; - if (!valid_reg(args->mon_reg.reg)) + if (!valid_reg(args->mon_reg_write.reg)) return ERR_INVALID_REGISTER; return SUCCESS; } proc_t *handle_mon_reg_write(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_reg.mon_idx); + cte_t mon = ctable_get(p->pid, args->mon_reg_write.mon_idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; - p->regs[REG_T0] = cap_monitor_reg_write( - mon, args->mon_reg.pid, args->mon_reg.reg, args->mon_reg.val); + p->regs[REG_T0] = cap_monitor_reg_write(mon, args->mon_reg_write.pid, + args->mon_reg_write.reg, + args->mon_reg_write.val); kernel_lock_release(); return p; } err_t validate_mon_cap_read(const sys_args_t *args) { - if (!valid_idx(args->mon_cap.mon_idx)) + if (!valid_idx(args->mon_cap_read.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_cap.pid)) + if (!valid_pid(args->mon_cap_read.pid)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_cap.idx)) + if (!valid_idx(args->mon_cap_read.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_mon_cap_read(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_cap.mon_idx); - cte_t src = ctable_get(args->mon_cap.pid, args->mon_cap.idx); + cte_t mon = ctable_get(p->pid, args->mon_cap_read.mon_idx); + cte_t src = ctable_get(args->mon_cap_read.pid, args->mon_cap_read.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; @@ -501,24 +519,26 @@ proc_t *handle_mon_cap_read(proc_t *const p, const sys_args_t *args) err_t validate_mon_cap_move(const sys_args_t *args) { - if (!valid_idx(args->mon_cap.mon_idx)) + if (!valid_idx(args->mon_cap_move.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_cap.pid)) + if (!valid_pid(args->mon_cap_move.src_pid)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_cap.idx)) + if (!valid_idx(args->mon_cap_move.src_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_cap.dst_pid)) + if (!valid_pid(args->mon_cap_move.dst_pid)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_cap.dst_idx)) + if (!valid_idx(args->mon_cap_move.dst_idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_mon_cap_move(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_cap.mon_idx); - cte_t src = ctable_get(args->mon_cap.pid, args->mon_cap.idx); - cte_t dst = ctable_get(args->mon_cap.dst_pid, args->mon_cap.dst_idx); + cte_t mon = ctable_get(p->pid, args->mon_cap_move.mon_idx); + cte_t src = ctable_get(args->mon_cap_move.src_pid, + args->mon_cap_move.src_idx); + cte_t dst = ctable_get(args->mon_cap_move.dst_pid, + args->mon_cap_move.dst_idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; @@ -529,51 +549,46 @@ proc_t *handle_mon_cap_move(proc_t *const p, const sys_args_t *args) err_t validate_mon_pmp_load(const sys_args_t *args) { - if (!valid_idx(args->mon_pmp.mon_idx)) + if (!valid_idx(args->mon_pmp_load.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_pmp.pid)) + if (!valid_pid(args->mon_pmp_load.pid)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_pmp.pmp_idx)) + if (!valid_idx(args->mon_pmp_load.idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_pmp.pmp_slot)) + if (!valid_pid(args->mon_pmp_load.slot)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_cap.dst_idx)) - return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_mon_pmp_load(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_pmp.mon_idx); - cte_t pmp = ctable_get(args->mon_pmp.pid, args->mon_pmp.pmp_idx); + cte_t mon = ctable_get(p->pid, args->mon_pmp_load.mon_idx); + cte_t pmp = ctable_get(args->mon_pmp_load.pid, args->mon_pmp_load.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; p->regs[REG_T0] - = cap_monitor_pmp_load(mon, pmp, args->mon_pmp.pmp_slot); + = cap_monitor_pmp_load(mon, pmp, args->mon_pmp_load.slot); kernel_lock_release(); return p; } err_t validate_mon_pmp_unload(const sys_args_t *args) { - if (!valid_idx(args->mon_pmp.mon_idx)) - return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_pmp.pid)) - return ERR_INVALID_PID; - if (!valid_idx(args->mon_pmp.pmp_idx)) + if (!valid_idx(args->mon_pmp_unload.mon_idx)) return ERR_INVALID_INDEX; - if (!valid_pid(args->mon_pmp.pmp_slot)) + if (!valid_pid(args->mon_pmp_unload.pid)) return ERR_INVALID_PID; - if (!valid_idx(args->mon_cap.dst_idx)) + if (!valid_idx(args->mon_pmp_unload.idx)) return ERR_INVALID_INDEX; return SUCCESS; } proc_t *handle_mon_pmp_unload(proc_t *const p, const sys_args_t *args) { - cte_t mon = ctable_get(p->pid, args->mon_pmp.mon_idx); - cte_t pmp = ctable_get(args->mon_pmp.pid, args->mon_pmp.pmp_idx); + cte_t mon = ctable_get(p->pid, args->mon_pmp_unload.mon_idx); + cte_t pmp + = ctable_get(args->mon_pmp_unload.pid, args->mon_pmp_unload.idx); p->regs[REG_T0] = ERR_PREEMPTED; if (!kernel_lock_acquire()) return NULL; diff --git a/kernel/src/trap.S b/kernel/src/trap.S index dbe08081..f5beb7ec 100644 --- a/kernel/src/trap.S +++ b/kernel/src/trap.S @@ -114,8 +114,9 @@ _exception_table: _machine_yield: csrrw a0,mscratch,a0 -_user_yield: + csrw mstatus,0 +_user_yield: #ifdef NDEBUG csrr t0,mcause li t1,0x8000000000000007 @@ -131,8 +132,8 @@ _sched: call sched trap_exit_pmp: -#ifndef NPREEMPT - csrw mstatus,MSTATUS_MIE +#ifndef PREEMPT + csrs mstatus,MSTATUS_MIE #endif ld s0,PROC_PMPADDR0(a0) ld s1,PROC_PMPADDR1(a0) @@ -154,15 +155,15 @@ trap_exit_pmp: csrw pmpcfg0,s8 trap_exit: -#ifndef NPREEMPT - csrw mstatus,MSTATUS_MIE +#ifndef PREEMPT + csrs mstatus,MSTATUS_MIE #endif ld t0,PROC_PC(a0) csrw mepc,t0 ld ra,PROC_RA(a0) - #ld sp,PROC_A0(a0) - #ld gp,PROC_A0(a0) + #ld sp,PROC_SP(a0) + #ld gp,PROC_GP(a0) ld tp,PROC_TP(a0) ld t0,PROC_T0(a0) ld t1,PROC_T1(a0) @@ -192,6 +193,8 @@ trap_exit: ld t5,PROC_T5(a0) ld t6,PROC_T6(a0) + csrc mstatus,MSTATUS_MIE + # Save PCB pointer csrw mscratch,a0 diff --git a/projects/hello/s3k_conf.h b/projects/hello/s3k_conf.h index fcc88bfc..f9893f28 100644 --- a/projects/hello/s3k_conf.h +++ b/projects/hello/s3k_conf.h @@ -22,5 +22,5 @@ #define S3K_SCHED_TIME (S3K_SLOT_LEN / 10) // If debugging, comment -// #define NDEBUG -#define VERBOSE 2 +//#define NDEBUG +#define VERBOSITY 0 diff --git a/projects/trapped/s3k_conf.h b/projects/trapped/s3k_conf.h index 8c2d613d..407317df 100644 --- a/projects/trapped/s3k_conf.h +++ b/projects/trapped/s3k_conf.h @@ -22,5 +22,5 @@ #define S3K_SCHED_TIME (S3K_SLOT_LEN / 10) // If debugging, comment -#define NDEBUG -#define INSTRUMENT +//#define NDEBUG +#define VERBOSITY 1