diff options
Diffstat (limited to 'arch')
| -rwxr-xr-x | arch/riscv64/conf/init | bin | 5312 -> 3688 bytes | |||
| -rw-r--r-- | arch/riscv64/conf/init.c | 23 | ||||
| -rw-r--r-- | arch/riscv64/conf/initrd | bin | 5632 -> 4096 bytes | |||
| -rw-r--r-- | arch/riscv64/include/uapi.h | 38 | ||||
| -rw-r--r-- | arch/riscv64/include/vmem.h | 48 | ||||
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 7 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 2 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 20 |
8 files changed, 95 insertions, 43 deletions
diff --git a/arch/riscv64/conf/init b/arch/riscv64/conf/init Binary files differindex ea63935..e1a5de7 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 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 Binary files differindex 72260ef..6c101bc 100644 --- a/arch/riscv64/conf/initrd +++ b/arch/riscv64/conf/initrd 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); } } |
