diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-01 23:34:57 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-01 23:34:57 +0300 |
| commit | 7ad9c01dad7b1b46eced8290b8b991383d648188 (patch) | |
| tree | cd528648af552974b90117efef431659ef5f0cc6 /arch/riscv64 | |
| parent | 9ff67d879b4695e0c9910b7276f3959c005c7b19 (diff) | |
| download | kmi-7ad9c01dad7b1b46eced8290b8b991383d648188.tar.gz kmi-7ad9c01dad7b1b46eced8290b8b991383d648188.zip | |
expand notifications into interrupt handlers
+ Terminology is still a bit poor, and will still have to write
documentation + implement ipis properly
Diffstat (limited to 'arch/riscv64')
| -rwxr-xr-x | arch/riscv64/conf/init | bin | 3512 -> 5312 bytes | |||
| -rw-r--r-- | arch/riscv64/conf/init.c | 85 | ||||
| -rw-r--r-- | arch/riscv64/conf/initrd | bin | 4096 -> 5632 bytes | |||
| -rw-r--r-- | arch/riscv64/kernel/csr.h | 2 | ||||
| -rw-r--r-- | arch/riscv64/kernel/irq.c | 10 |
5 files changed, 46 insertions, 51 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init Binary files differindex d04c492..ea63935 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 293d5e8..80bb68a 100644 --- a/arch/riscv64/conf/init.c +++ b/arch/riscv64/conf/init.c @@ -24,10 +24,6 @@ #include <stddef.h> #include "../../../include/kmi/syscalls.h" -struct sys_ret { - long a0, a1, a2, a3, a4, a5; -}; - char *strcpy(char * restrict dst, const char * restrict src) { const char *s1 = src; @@ -40,8 +36,8 @@ char *strcpy(char * restrict dst, const char * restrict src) } static inline struct sys_ret ecall(size_t n, - long arg0, long arg1, long arg2, long arg3, - long arg4, long arg5) + sys_arg_t arg0, sys_arg_t arg1, sys_arg_t arg2, sys_arg_t arg3, + sys_arg_t arg4, sys_arg_t arg5) { /* here a static assert of n <= 6 && n >= 1 would be ideal */ @@ -103,11 +99,11 @@ static uint64_t sys_timebase() { struct sys_ret r = ecall1(SYS_TIMEBASE); #if defined(_LP64) - return r.a1; + return r.ar0; #else - uint64_t t = r.a1; + uint64_t t = r.ar0; t <<= 32; - return t + r.a2; + return t + r.ar1; #endif } @@ -115,11 +111,11 @@ static uint64_t sys_ticks() { struct sys_ret r = ecall1(SYS_TICKS); #if defined(_LP64) - return r.a1; + return r.ar0; #else - uint64_t t = r.a1; + uint64_t t = r.ar0; t <<= 32; - return t + r.a2; + return t + r.ar1; #endif } @@ -161,21 +157,21 @@ static uint64_t sys_fork() { struct sys_ret r = ecall1(SYS_FORK); - if (r.a0 != 0) { - print_value("fork() failed with error ", r.a0); - return r.a0; + if (r.s != 0) { + print_value("fork() failed with error ", r.s); + return r.s; } - return r.a1; + return r.ar0; } static uint64_t sys_swap(long tid) { struct sys_ret r = ecall2(SYS_SWAP, tid); - if (r.a0 != 0) { - print_value("swap() failed with error ", r.a0); - return r.a0; + if (r.s != 0) { + print_value("swap() failed with error ", r.s); + return r.s; } return 0; @@ -185,29 +181,23 @@ static void sys_ipc_server(void *f) { struct sys_ret r = ecall2(SYS_IPC_SERVER, (long)f); - if (r.a0 != 0) - print_value("ipc_server() failed with error ", r.a0); + if (r.s != 0) + print_value("ipc_server() failed with error ", r.s); } -/** Helper for ipc arguments/return values. */ -struct ipc_args { - long s; long a0, a1, a2, a3; -}; - -static inline struct ipc_args sys_ipc_req(long tid, long d0, long d1, long d2, - long d3) +static inline struct sys_ret sys_ipc_req(sys_arg_t pid, + sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, + sys_arg_t d3) { - struct sys_ret r = ecall6(SYS_IPC_REQ, tid, d0, d1, d2, d3); + struct sys_ret r = ecall6(SYS_IPC_REQ, pid, d0, d1, d2, d3); - if (r.a0) { - print_value("ipc_req() failed with error ", r.a0); - return (struct ipc_args){r.a0, 0, 0, 0, 0}; - } + if (r.s) + print_value("ipc_req() failed with error ", r.s); - return (struct ipc_args){r.a0, r.a1, r.a2, r.a3, r.a4}; + return r; } -static void sys_ipc_resp(long d0, long d1, long d2, long d3) +static void sys_ipc_resp(sys_arg_t d0, sys_arg_t d1, sys_arg_t d2, sys_arg_t d3) { ecall5(SYS_IPC_RESP, d0, d1, d2, d3); } @@ -221,20 +211,20 @@ static void *sys_req_mem(size_t count) { 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); + if (r.s) { + print_value("sys_req_mem() failed with error ", r.s); return NULL; } - return (void *)r.a1; + return (void *)r.ar0; } static void sys_free_mem(void *p) { struct sys_ret r = ecall2(SYS_FREE_MEM, (long)p); - if (r.a0) - print_value("sys_free_mem() failed with error ", r.a0); + if (r.s) + print_value("sys_free_mem() failed with error ", r.s); } static void *sys_req_sharedmem(long tid, unsigned long size, void **cbuf) @@ -242,13 +232,13 @@ static void *sys_req_sharedmem(long tid, unsigned long size, void **cbuf) 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); + if (r.s) { + print_value("sys_req_sharedmem() failed with error ", r.s); return NULL; } - *cbuf = (void *)r.a2; - return (void *)r.a1; + *cbuf = (void *)r.ar1; + return (void *)r.ar0; } /* I'm guessing my elf parser doesn't handle data pages correctly yet... */ @@ -345,9 +335,10 @@ void _start() } puts("Checking shared memory\n"); - struct ipc_args r = sys_ipc_req(1, 1, 0, 0, 0); - rw_buf = (char *)r.a1; - rw_buf_size = (size_t)r.a2; + struct sys_ret r = sys_ipc_req(1, 1, 0, 0, 0); + rw_buf = (char *)r.ar1; + rw_buf_size = (size_t)r.ar2; + print_value("Response from", r.ar0); print_value("Shared memory ptr", (uintptr_t)rw_buf); print_value("Shared memory size", rw_buf_size); diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd Binary files differindex c8d7253..72260ef 100644 --- a/arch/riscv64/conf/initrd +++ b/arch/riscv64/conf/initrd diff --git a/arch/riscv64/kernel/csr.h b/arch/riscv64/kernel/csr.h index 9b7b78a..bc48464 100644 --- a/arch/riscv64/kernel/csr.h +++ b/arch/riscv64/kernel/csr.h @@ -40,6 +40,8 @@ /** Address of \c sstatus CSR. */ #define CSR_SSTATUS 0x100 +#define SR_SPIE 0b10 + /** Address of \c sie CSR. */ #define CSR_SIE 0x104 diff --git a/arch/riscv64/kernel/irq.c b/arch/riscv64/kernel/irq.c index 964401f..2ef15cc 100644 --- a/arch/riscv64/kernel/irq.c +++ b/arch/riscv64/kernel/irq.c @@ -41,12 +41,13 @@ stat_t deactivate_irq(irq_t id) /* very simple for now */ void enable_irqs() { - csr_set(CSR_SSTATUS, CSR_SIE); + /* should be supervisor external interrupt */ + csr_set(CSR_SIE, 1 << 9); } void disable_irqs() { - csr_clear(CSR_SSTATUS, CSR_SIE); + csr_clear(CSR_SIE, 1 << 9); } irq_t get_irq() @@ -71,9 +72,10 @@ static void riscv_unknown_interrupt(long id) * * @param id ID of interrupt, with interrupt bit still set. */ -void riscv_handle_interrupt(long id) +void riscv_handle_interrupt(unsigned long id) { - id = -id; + /* clear leading one */ + id = (id << 1) >> 1; switch (id) { /* I think */ |
