diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-11-12 16:41:36 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-11-12 16:41:36 +0200 |
| commit | 41ead8de77963bae907375c1bb115dad3315f46b (patch) | |
| tree | 4b364db137bd3bea69853f15329292af7662897d /arch/riscv64/conf/init.c | |
| parent | 1d37792fb7a47135f0e7b7fc245e83bb1d8fc496 (diff) | |
| download | kmi-41ead8de77963bae907375c1bb115dad3315f46b.tar.gz kmi-41ead8de77963bae907375c1bb115dad3315f46b.zip | |
initial rpc implementations
Diffstat (limited to 'arch/riscv64/conf/init.c')
| -rw-r--r-- | arch/riscv64/conf/init.c | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/arch/riscv64/conf/init.c b/arch/riscv64/conf/init.c index 45274d9..01e219e 100644 --- a/arch/riscv64/conf/init.c +++ b/arch/riscv64/conf/init.c @@ -9,8 +9,13 @@ #include <stdint.h> #include "../../../include/apos/syscalls.h" -#define ecall() do { asm ("ecall" : : : "a0", "a1", "a2", "a3", "a4", "a5"); \ +#define ecall() do { asm volatile ("ecall" \ + : \ + : \ + : "a0", "a1", "a2", "a3", "a4", "a5", \ + "memory"); \ } while (0) + static void sys_noop() { long register a0 asm ("a0") = SYS_NOOP; @@ -108,6 +113,60 @@ static uint64_t sys_swap(long tid) return a0; } +static void sys_ipc_server(void *f) +{ + long register a0 asm ("a0") = SYS_IPC_SERVER; + long register a1 asm ("a1") = (long)f; + ecall(); + if (a0 != 0) + print_value("ipc_server() failed with error ", a0); +} + +static uint64_t sys_ipc_req(long tid, long *d0, long *d1, long *d2, long *d3) +{ + long register a0 asm ("a0") = SYS_IPC_REQ; + long register a1 asm ("a1") = tid; + long register a2 asm ("a2") = *d0; + long register a3 asm ("a3") = *d1; + long register a4 asm ("a4") = *d2; + long register a5 asm ("a5") = *d3; + ecall(); + if (a0) + print_value("ipc_req() failed with error ", a0); + + *d0 = a2; + *d1 = a3; + *d2 = a4; + *d3 = a5; + return a0; +} + +static void sys_ipc_resp(long d0, long d1, long d2, long d3) +{ + long register a0 asm ("a0") = SYS_IPC_RESP; + long register a1 asm ("a1") = d0; + long register a2 asm ("a2") = d1; + long register a3 asm ("a3") = d2; + long register a4 asm ("a4") = d3; + ecall(); +} + +static void sys_poweroff(long type) +{ + long register a0 asm ("a0") = SYS_POWEROFF; + long register a1 asm ("a1") = type; + ecall(); +} + +void callback(long status, long tid, long d0, long d1, long d2, long d3) +{ + sys_ipc_resp(d0, d1, d2, d3); +} + +#define CSR_TIME "0xc01" +#define csr_read(csr, \ + res) __asm__ volatile ("csrr %0, " csr : "=r" (res) :: "memory") + void _start() { sys_noop(); @@ -128,20 +187,41 @@ void _start() print_value("End ticks", i); print_value("Syscalls per second", n); + puts("Setting callback..."); + sys_ipc_server(callback); + puts("Starting fork():\n"); long pid = sys_fork(); if (pid != 0) { - print_value("Child pid: ", pid); + print_value("Child pid", pid); puts("Swapping to child...\n"); while(1) sys_swap(pid); } puts("Hello from child!\n"); - puts("Doing 1M swaps...\n"); - start = sys_ticks(); - for (long i = 0; i < 1000000; ++i) + puts("Doing swaps...\n"); + csr_read(CSR_TIME, i); + start = i; n = 0; + while (i < start + second) { sys_swap(1); - uint64_t ticks = sys_ticks() - start; - print_value("1M swaps took ", ticks / second); + csr_read(CSR_TIME, i); + n++; + } + + print_value("Swaps (both ways) per second", n); + + puts("Doing ipc requests...\n"); + long d0, d1, d2, d3; + csr_read(CSR_TIME, i); + start = i; n = 0; + while (i < start + second) { + sys_ipc_req(1, &d0, &d1, &d2, &d3); + csr_read(CSR_TIME, i); + n++; + } + + print_value("IPC requests per second", n); + + sys_poweroff(0); } |
