aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-09-15 19:21:14 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-09-15 19:46:07 +0300
commita717296a2036cede5fccfff544513043a984d614 (patch)
tree68f75a23adc298628fb9cab41fd47402a99dd19d /arch/riscv64
parent619725a5f2f5272f9cbb547ed95c87312c2765a9 (diff)
downloadkmi-a717296a2036cede5fccfff544513043a984d614.tar.gz
kmi-a717296a2036cede5fccfff544513043a984d614.zip
change syscalls to take 5 params and return 6
+ In total, a syscall is built up of 6 values, with the first being the syscall number. Symmetrically, the first value is now a status and the following five values return "values". This allows us to cram in more info into the ipc_* functions. The performance difference is absolutely minimal, at least from my testing in qemu.
Diffstat (limited to 'arch/riscv64')
-rw-r--r--arch/riscv64/asm/asm-offsets.c9
-rw-r--r--arch/riscv64/asm/source.mk2
-rwxr-xr-xarch/riscv64/conf/initbin2136 -> 2144 bytes
-rw-r--r--arch/riscv64/conf/init.c20
-rw-r--r--arch/riscv64/conf/initrdbin2560 -> 2560 bytes
-rw-r--r--arch/riscv64/init/init.c3
-rw-r--r--arch/riscv64/kernel/entry.S35
-rw-r--r--arch/riscv64/kernel/vmem.c2
8 files changed, 49 insertions, 22 deletions
diff --git a/arch/riscv64/asm/asm-offsets.c b/arch/riscv64/asm/asm-offsets.c
index 8852d8f..3619765 100644
--- a/arch/riscv64/asm/asm-offsets.c
+++ b/arch/riscv64/asm/asm-offsets.c
@@ -8,6 +8,7 @@
*/
#include <apos/utils.h>
+#include <apos/uapi.h>
#include "../kernel/regs.h"
/**
@@ -74,4 +75,12 @@ void asm_offsets()
OFFSETOF(t5, struct riscv_regs);
OFFSETOF(t6, struct riscv_regs);
SIZEOF(registers, struct riscv_regs);
+
+ OFFSETOF(s, struct sys_ret);
+ OFFSETOF(ar0, struct sys_ret);
+ OFFSETOF(ar1, struct sys_ret);
+ OFFSETOF(ar2, struct sys_ret);
+ OFFSETOF(ar3, struct sys_ret);
+ OFFSETOF(ar4, struct sys_ret);
+ SIZEOF(sys_ret, struct sys_ret);
}
diff --git a/arch/riscv64/asm/source.mk b/arch/riscv64/asm/source.mk
index 9b463b7..87bcf24 100644
--- a/arch/riscv64/asm/source.mk
+++ b/arch/riscv64/asm/source.mk
@@ -9,7 +9,7 @@ $(OFFSET_HEADER): $(OFFSET_SOURCE)
echo " * @file asm-offsets.h" >> $(OFFSET_HEADER)
echo " * This comment is to shut up warnings." >> $(OFFSET_HEADER)
echo " */" >> $(OFFSET_HEADER)
- $(COMPILER) $(INCLUDE_FLAGS) -S $(OFFSET_SOURCE) -o - |\
+ $(COMPILER) $(CFLAGS) $(INCLUDE_FLAGS) -S $(OFFSET_SOURCE) -o - |\
awk '($$1 == "#->") { print "#define " $$2 " " $$3 }' >> $(OFFSET_HEADER)
echo "#endif /* APOS_ASM_OFFSETS_H */" >> $(OFFSET_HEADER)
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init
index d9a585d..b75076f 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 4bd6a4e..feb5177 100644
--- a/arch/riscv64/conf/init.c
+++ b/arch/riscv64/conf/init.c
@@ -9,30 +9,33 @@
#include <stdint.h>
#include "../../../include/apos/syscalls.h"
+#define ecall() do { asm ("ecall" : : : "a0", "a1", "a2", "a3", "a4", "a5"); \
+} while (0)
static void sys_noop()
{
long register a0 asm ("a0") = SYS_NOOP;
- asm ("ecall" : : : "a0", "a1");
+ ecall();
}
static void sys_putch(char c)
{
long register a0 asm ("a0") = SYS_PUTCH;
long register a1 asm ("a1") = c;
- asm ("ecall" : : : "a0", "a1");
+ ecall();
}
static uint64_t sys_timebase()
{
long register a0 asm ("a0") = SYS_TIMEBASE;
long register a1 asm ("a1") = 0;
- asm ("ecall" : : : "a0", "a1");
+ long register a2 asm ("a2") = 0;
+ ecall();
#if defined(_LP64)
return a1;
#else
- uint64_t t = a0;
+ uint64_t t = a1;
t <<= 32;
- return t + a1;
+ return t + a2;
#endif
}
@@ -40,13 +43,14 @@ static uint64_t sys_ticks()
{
long register a0 asm ("a0") = SYS_TICKS;
long register a1 asm ("a1") = 0;
- asm ("ecall" : : : "a0", "a1");
+ long register a2 asm ("a2") = 0;
+ ecall();
#if defined(_LP64)
return a1;
#else
- uint64_t t = a0;
+ uint64_t t = a1;
t <<= 32;
- return t + a1;
+ return t + a2;
#endif
}
diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd
index f05e035..3af4d2e 100644
--- a/arch/riscv64/conf/initrd
+++ b/arch/riscv64/conf/initrd
Binary files differ
diff --git a/arch/riscv64/init/init.c b/arch/riscv64/init/init.c
index 0680296..498023a 100644
--- a/arch/riscv64/init/init.c
+++ b/arch/riscv64/init/init.c
@@ -44,7 +44,8 @@ static void init_bootmem()
/* direct mapping (temp) */
for (size_t i = 0; i < CSTACK_PAGE; ++i)
- root_branch->leaf[i] = (struct vmem *)to_pte(TOP_PAGE_SIZE * i, flags);
+ root_branch->leaf[i] = (struct vmem *)to_pte(TOP_PAGE_SIZE * i,
+ flags);
/* kernel (also sort of direct mapping) */
flags |= VM_G;
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index 1bd6046..8ff642a 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -86,25 +86,42 @@ handle_syscall:
/* add 4 (size of ecall) to EPC to avoid running the same instruction
* twice */
csrr s0, CSR_SEPC
- addi s0, s0, 4
+ addi s0, s0, 4
csrw CSR_SEPC, s0
+ /* allocate space for sys_ret structure on stack and shift argument
+ * registers down one to make room for the pointer to this structure */
+ addi sp, sp, -sizeof_sys_ret
+ mv a6, a5
+ mv a5, a4
+ mv a4, a3
+ mv a3, a2
+ mv a2, a1
+ mv a1, a0
+ mv a0, sp
jal syscall_dispatch
+ /* move structure from stack into registers. */
+ lr a0, offsetof_s(sp)
+ lr a1, offsetof_ar0(sp)
+ lr a2, offsetof_ar1(sp)
+ lr a3, offsetof_ar2(sp)
+ lr a4, offsetof_ar3(sp)
+ lr a5, offsetof_ar4(sp)
+ addi sp, sp, sizeof_sys_ret
/* if we had a thread switch, load kernel stack of current thread and
* restore its context */
- /* TODO: is a whole function call necessary? */
- mv s0, a0
- mv s1, a1
/* get associated kernel stack */
mv sp, tp
addi sp, sp, -sizeof_registers
/* restore system call result */
- mv a0, s0
- mv a1, s1
j restore_noreturn
restore_all:
lr a0, offsetof_a0(sp)
lr a1, offsetof_a1(sp)
+ lr a2, offsetof_a2(sp)
+ lr a3, offsetof_a3(sp)
+ lr a4, offsetof_a4(sp)
+ lr a5, offsetof_a5(sp)
restore_noreturn:
/* restore registers besides possible return value, assume instruction
@@ -117,11 +134,7 @@ restore_noreturn:
lr t0, offsetof_t0(sp)
lr t1, offsetof_t1(sp)
lr t2, offsetof_t2(sp)
- /* a0 and a1 should not be restored when coming from a syscall */
- lr a2, offsetof_a2(sp)
- lr a3, offsetof_a3(sp)
- lr a4, offsetof_a4(sp)
- lr a5, offsetof_a5(sp)
+ /* a0 - a5 should not be restored when coming from a syscall */
lr a6, offsetof_a6(sp)
lr s0, offsetof_s0(sp)
lr s1, offsetof_s1(sp)
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c
index 1abc58d..a029f6a 100644
--- a/arch/riscv64/kernel/vmem.c
+++ b/arch/riscv64/kernel/vmem.c
@@ -306,7 +306,7 @@ vm_t setup_kernel_io(struct vmem *b, vm_t paddr)
{
pm_t top_page = paddr / TOP_PAGE_SIZE;
b->leaf[IO_PAGE] = (struct vmem *)to_pte(top_page * TOP_PAGE_SIZE,
- VM_V | VM_R | VM_W);
+ VM_V | VM_R | VM_W);
return -TOP_PAGE_SIZE + paddr - (top_page * TOP_PAGE_SIZE);
}
#endif