aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rwxr-xr-xarch/riscv64/conf/initbin5312 -> 3688 bytes
-rw-r--r--arch/riscv64/conf/init.c23
-rw-r--r--arch/riscv64/conf/initrdbin5632 -> 4096 bytes
-rw-r--r--arch/riscv64/include/uapi.h38
-rw-r--r--arch/riscv64/include/vmem.h48
-rw-r--r--arch/riscv64/kernel/entry.S7
-rw-r--r--arch/riscv64/kernel/proc.c2
-rw-r--r--arch/riscv64/kernel/vmem.c20
8 files changed, 95 insertions, 43 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init
index ea63935..e1a5de7 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 010267e..7029dbd 100644
--- a/arch/riscv64/conf/init.c
+++ b/arch/riscv64/conf/init.c
@@ -14,7 +14,7 @@
* things easier for myself. For now though, this is good enough.
*
* Compile with
- * riscv64-unknown-elf-gcc -ffreestanding -nostdlib
+ * riscv64-unknown-elf-gcc -Driscv64 -ffreestanding -nostdlib
*
* Create initrd with
* echo init | cpio -H newc -o > initrd
@@ -211,8 +211,7 @@ static void sys_poweroff(long type)
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));
+ struct sys_ret r = ecall3(SYS_REQ_MEM, count, VM_R | VM_W);
if (r.s) {
print_value("sys_req_mem() failed with error ", r.s);
return NULL;
@@ -231,16 +230,22 @@ static void sys_free_mem(void *p)
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));
+ struct sys_ret r = ecall3(SYS_REQ_SHAREDMEM, size, VM_R | VM_W);
if (r.s) {
print_value("sys_req_sharedmem() failed with error ", r.s);
return NULL;
}
- *cbuf = (void *)r.ar1;
- return (void *)r.ar0;
+ void *rw_buf = (void *)r.ar0;
+
+ r = ecall4(SYS_REF_SHAREDMEM, tid, (sys_arg_t)rw_buf, VM_R | VM_W);
+ if (r.s) {
+ print_value("sys_ref_sharedmem() failed with error ", r.s);
+ return NULL;
+ }
+
+ *cbuf = (void *)r.ar0;
+ return rw_buf;
}
/* I'm guessing my elf parser doesn't handle data pages correctly yet... */
@@ -257,6 +262,7 @@ void callback(long pid, long tid, long d0, long d1, long d2, long d3)
__builtin_unreachable();
} else if (d0 == 2) {
+ puts("Received string: ");
puts(rw_buf);
sys_ipc_resp(0, 0, 0, 0);
__builtin_unreachable();
@@ -345,6 +351,7 @@ void _start()
print_value("Shared memory size", rw_buf_size);
rw_buf[0] = 0;
+ puts("Sending string...\n");
strcpy(rw_buf, "Hello from the other side!\n");
sys_ipc_req(1, 2, 0, 0, 0);
diff --git a/arch/riscv64/conf/initrd b/arch/riscv64/conf/initrd
index 72260ef..6c101bc 100644
--- a/arch/riscv64/conf/initrd
+++ b/arch/riscv64/conf/initrd
Binary files differ
diff --git a/arch/riscv64/include/uapi.h b/arch/riscv64/include/uapi.h
new file mode 100644
index 0000000..a8c236b
--- /dev/null
+++ b/arch/riscv64/include/uapi.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: copyleft-next-0.3.1 */
+/* Copyright 2024, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
+
+#ifndef KMI_RISCV_UAPI_H
+#define KMI_RISCV_UAPI_H
+
+/**
+ * @file uapi.h
+ *
+ * RISCV-specific stuff that should be visible to userspace, currently mainly
+ * VM_R/VM_W/VM_X flags.
+ */
+
+/** Page is active. */
+#define VM_V (1 << 0)
+
+/** Page is readable. */
+#define VM_R (1 << 1)
+
+/** Page is writable. */
+#define VM_W (1 << 2)
+
+/** Page is executable. */
+#define VM_X (1 << 3)
+
+/** Page is user-accessible. */
+#define VM_U (1 << 4)
+
+/** Page is global. */
+#define VM_G (1 << 5)
+
+/** Page has been accessed. */
+#define VM_A (1 << 6)
+
+/** Page is dirty. */
+#define VM_D (1 << 7)
+
+#endif /* KMI_RISCV_UAPI_H */
diff --git a/arch/riscv64/include/vmem.h b/arch/riscv64/include/vmem.h
index ed99843..704858b 100644
--- a/arch/riscv64/include/vmem.h
+++ b/arch/riscv64/include/vmem.h
@@ -4,6 +4,8 @@
#ifndef KMI_RISCV_VMAP_H
#define KMI_RISCV_VMAP_H
+#include "uapi.h"
+
/**
* @file vmem.h
* riscv64 definitions of arch-specific virtual memory data types and macros.
@@ -11,9 +13,6 @@
* architecture-nonspecific, but works for now.
*/
-#include <kmi/types.h>
-#include <kmi/attrs.h>
-
/**
* Number of entries in one page table, depends on if we're running riscv32 or
* riscv64.
@@ -26,30 +25,6 @@
#define RISCV_NUM_LEAVES 1024
#endif
-/** Page is active. */
-#define VM_V (1 << 0)
-
-/** Page is readable. */
-#define VM_R (1 << 1)
-
-/** Page is writable. */
-#define VM_W (1 << 2)
-
-/** Page is executable. */
-#define VM_X (1 << 3)
-
-/** Page is user-accessible. */
-#define VM_U (1 << 4)
-
-/** Page is global. */
-#define VM_G (1 << 5)
-
-/** Page has been accessed. */
-#define VM_A (1 << 6)
-
-/** Page is dirty. */
-#define VM_D (1 << 7)
-
/** Memory mode of cpu. Currently only Sv39 is supported. */
enum mm_mode {
/** 48bit effective addresses on 64bit systems. */
@@ -71,4 +46,23 @@ struct vmem {
struct vmem *leaf[RISCV_NUM_LEAVES];
};
+/**
+ * Extract virtual memory flags (MR_XXX).
+ *
+ * @param x Flags to extract virtual memory region flags from.
+ * @return Virtual memory region flags.
+ */
+#define vm_flags(x) ((x) & ~0xff)
+
+/**
+ * Extract physical memory page flags (VM_XXX).
+ *
+ * @param x Flags to extract physical memory page flags from.
+ * @return Physical memory page flags.
+ */
+#define vp_flags(x) ((x) & 0xff)
+
+/** How many VM_XXX flags architecture has. MR_XXX are applied after them. */
+#define ARCH_VP_FLAGS 8
+
#endif /* KMI_RISCV_VMAP_H */
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index 1680a35..e37d5cc 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -104,6 +104,13 @@ handle_exception:
save_regs
save_args
+ csrr a0, CSR_SEPC
+ csrr a1, CSR_STVAL
+ /* not really a kernel panic but used for now to signify that something
+ * happened in userspace that we can't deal with */
+ csrr a2, CSR_SCAUSE
+ call kernel_panic
+
j _load_context
handle_dispatch:
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c
index 0c43b3d..f1a62c4 100644
--- a/arch/riscv64/kernel/proc.c
+++ b/arch/riscv64/kernel/proc.c
@@ -83,7 +83,7 @@ vm_t get_stack(struct tcb *t)
return r->sp;
}
-void clone_regs(struct tcb *d, struct tcb *s)
+void copy_regs(struct tcb *d, struct tcb *s)
{
struct riscv_regs *rd = (struct riscv_regs *)(d->regs) - 1;
struct riscv_regs *rs = (struct riscv_regs *)(s->regs) - 1;
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c
index 3f29446..f717771 100644
--- a/arch/riscv64/kernel/vmem.c
+++ b/arch/riscv64/kernel/vmem.c
@@ -236,6 +236,9 @@ stat_t stat_vpage(struct vmem *branch, vm_t vaddr, pm_t *paddr,
static struct vmem *__create_leaf()
{
pm_t new_leaf = alloc_page(MM_KPAGE);
+ if (!new_leaf)
+ return NULL;
+
memset((void *)new_leaf, 0, sizeof(struct vmem));
return (struct vmem *)to_pte((pm_t)__pa(new_leaf), VM_V);
}
@@ -293,8 +296,13 @@ stat_t map_vpage(struct vmem *branch, pm_t paddr, vm_t vaddr, vmflags_t flags,
while (top != order) {
size_t idx = vm_to_index(vaddr, top);
- if (__unused((pm_t)branch->leaf[idx]))
- branch->leaf[idx] = __create_leaf();
+ if (__unused((pm_t)branch->leaf[idx])) {
+ struct vmem *leaf = __create_leaf();
+ if (!leaf)
+ return ERR_OOMEM;
+
+ branch->leaf[idx] = leaf;
+ }
branch = (struct vmem *)pte_addr(branch->leaf[idx]);
top--;
@@ -438,16 +446,14 @@ struct vmem *create_vmem()
return b;
}
-stat_t use_vmem(struct vmem *b)
+void use_vmem(struct vmem *b)
{
__use_vmem(__pa(b), DEFAULT_Sv_MODE);
- return OK;
}
-stat_t destroy_vmem(struct vmem *b)
+void destroy_vmem(struct vmem *b)
{
__destroy_branch(b);
- return OK;
}
stat_t populate_kvmem(struct vmem *b)
@@ -541,7 +547,7 @@ void destroy_rpc_stack(struct tcb *t)
pm_t page = 0; enum mm_order order = BASE_PAGE;
stat_vpage(t->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i,
&page, &order, NULL);
- free_page(page, order);
+ free_page(order, page);
}
}