aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/conf/apos.its4
-rwxr-xr-xarch/riscv/conf/initbin0 -> 1032 bytes
-rw-r--r--arch/riscv/conf/init-link.S30
-rw-r--r--arch/riscv/conf/initrdbin0 -> 1536 bytes
-rw-r--r--arch/riscv/conf/initrd.txt1
-rw-r--r--arch/riscv/conf/kernel-link.S4
-rw-r--r--arch/riscv/conf/s.S4
-rw-r--r--arch/riscv/include/csr.h9
-rw-r--r--arch/riscv/include/vmem.h8
-rw-r--r--arch/riscv/init/init.c29
-rw-r--r--arch/riscv/kernel/main.c10
-rw-r--r--arch/riscv/kernel/vmem.c5
-rw-r--r--arch/riscv/source.mk1
13 files changed, 89 insertions, 16 deletions
diff --git a/arch/riscv/conf/apos.its b/arch/riscv/conf/apos.its
index 1581025..15db4a4 100644
--- a/arch/riscv/conf/apos.its
+++ b/arch/riscv/conf/apos.its
@@ -7,7 +7,7 @@
images {
kernel {
description = "Garbaggio";
- data = /incbin/("../../../kernel.bin");
+ data = /incbin/("../../../apos.bin");
type = "kernel";
arch = "riscv";
os = "apos";
@@ -21,7 +21,7 @@
initrd {
description = "Gargabbio initrd";
- data = /incbin/("initrd.txt");
+ data = /incbin/("initrd");
type = "ramdisk";
arch = "riscv";
os = "apos";
diff --git a/arch/riscv/conf/init b/arch/riscv/conf/init
new file mode 100755
index 0000000..06e61e0
--- /dev/null
+++ b/arch/riscv/conf/init
Binary files differ
diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S
new file mode 100644
index 0000000..642e831
--- /dev/null
+++ b/arch/riscv/conf/init-link.S
@@ -0,0 +1,30 @@
+OUTPUT_ARCH(riscv)
+ENTRY(main)
+
+SECTIONS {
+ . = ABSOLUTE(PM_KERN);
+ __init_start = .;
+
+ /* objcopy only copies these three sections (as far as I'm aware) into the
+ produces binary, so __init_end should point to the correct location in the
+ final binary
+ */
+ .text ALIGN(4K) : AT(0) {
+ *(.init.start)
+ *(.text*);
+ }
+
+ .rodata : {
+ *(.rodata*)
+ }
+
+ .data : {
+ *(.data*)
+ }
+
+ .bss : {
+ *(.bss*) *(COMMON)
+ }
+
+ __init_end = . ;
+}
diff --git a/arch/riscv/conf/initrd b/arch/riscv/conf/initrd
new file mode 100644
index 0000000..8dc931b
--- /dev/null
+++ b/arch/riscv/conf/initrd
Binary files differ
diff --git a/arch/riscv/conf/initrd.txt b/arch/riscv/conf/initrd.txt
deleted file mode 100644
index e965047..0000000
--- a/arch/riscv/conf/initrd.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello
diff --git a/arch/riscv/conf/kernel-link.S b/arch/riscv/conf/kernel-link.S
index bf0ad28..d3b1223 100644
--- a/arch/riscv/conf/kernel-link.S
+++ b/arch/riscv/conf/kernel-link.S
@@ -2,10 +2,10 @@ OUTPUT_ARCH(riscv)
ENTRY(main)
SECTIONS {
- . = ABSOLUTE(PM_KERN);
+ . = ABSOLUTE(VM_KERN);
__kernel_start = .;
- .text : AT(0) {
+ .text ALIGN(4K) : AT(0) {
*(.kernel.start);
*(.text*);
}
diff --git a/arch/riscv/conf/s.S b/arch/riscv/conf/s.S
new file mode 100644
index 0000000..7b796ce
--- /dev/null
+++ b/arch/riscv/conf/s.S
@@ -0,0 +1,4 @@
+.text
+.global _start
+_start:
+loop: j loop
diff --git a/arch/riscv/include/csr.h b/arch/riscv/include/csr.h
index 70e60bb..bd02b04 100644
--- a/arch/riscv/include/csr.h
+++ b/arch/riscv/include/csr.h
@@ -37,6 +37,9 @@
#define EXC_LOAD_PAGE_FAULT 13
#define EXC_STORE_PAGE_FAULT 15
+/* status CSR bits */
+#define SSTATUS_SUM (1 << 18)
+
/* directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13 */
#ifdef __ASSEMBLY__
#define __ASM_STR(x) x
@@ -50,4 +53,10 @@
#define csr_write(csr, val)\
__asm__ ("csrw " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+#define csr_set(csr, val)\
+ __asm__ ("csrs " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+
+#define csr_clear(csr, val)\
+ __asm__ ("csrc " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+
#endif /* APOS_CSR_H */
diff --git a/arch/riscv/include/vmem.h b/arch/riscv/include/vmem.h
index 2cd3ac7..d17aaf1 100644
--- a/arch/riscv/include/vmem.h
+++ b/arch/riscv/include/vmem.h
@@ -3,7 +3,6 @@
#include <apos/types.h>
#include <apos/attrs.h>
-#include <apos/pmem.h>
#define VM_V (1 << 0)
#define VM_R (1 << 1)
@@ -25,11 +24,4 @@ struct __packed vm_branch_t {
struct vm_branch_t *leaf[512];
};
-
-void map_vmem(struct vm_branch_t *b,
- pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order);
-
-void unmap_vmem(struct vm_branch_t *b,
- vm_t vaddr, enum mm_order_t order);
-
#endif /* APOS_RISCV_VMAP_H */
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c
new file mode 100644
index 0000000..d9b32a0
--- /dev/null
+++ b/arch/riscv/init/init.c
@@ -0,0 +1,29 @@
+#include <apos/types.h>
+#include <apos/attrs.h>
+#include <vmem.h>
+#include <csr.h>
+
+/* assume 64 bit for now */
+struct __packed init_vmem {
+ int *leaf[512];
+};
+
+struct init_vmem root_branch;
+
+/* assume Sv48 for now */
+void init_lowmem()
+{
+ size_t flags = VM_V | VM_X | VM_R | VM_W;
+ for(size_t i = 0; i < 512; ++i)
+ root_branch.leaf[i] = (int *)((1UL << 37) * i | flags);
+
+ csr_write(CSR_SATP, SATP_MODE_Sv48 | ((size_t)&root_branch >> 12));
+}
+
+void __section(".init.start") main(void *fdt)
+{
+ extern char *__init_end;
+ void (*kernel_main)(void *fdt) = (void (*)(void *))(VM_KERN + (size_t)&__init_end);
+ init_lowmem();
+ kernel_main(fdt);
+}
diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c
index 40f0eb6..6c504f8 100644
--- a/arch/riscv/kernel/main.c
+++ b/arch/riscv/kernel/main.c
@@ -259,15 +259,17 @@ static void init_proc(void *fdt, struct vm_branch_t *b)
t->pid = 0;
t->tid = 0;
threads_insert(t);
- sp_mem_init(&t->sp_r, uvmem_size());
+ sp_mem_init(&t->sp_r, -uvmem_size(), uvmem_size() - 1);
/* binary itself */
size_t sz = align_up(get_init_size(fdt), BASE_PAGE_SIZE);
- t->bin = alloc_uvmem(t, sz, VM_V | VM_X);
+ t->bin = alloc_uvmem(t, sz, VM_V | VM_X | VM_R | VM_W | VM_U);
/* stack */
- t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W);
+ t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U);
/* if it needs heap, it'll ask for it */
+ __asm__ ("sfence.vma" : : : "memory");
+
move_init(fdt, (void *)t->bin);
jump_to_userspace(t, 0, 0);
}
@@ -277,6 +279,8 @@ void __main main(void *fdt)
init_dbg(fdt);
dbg_fdt(fdt);
+ /* allow supervisor code to touch user data */
+ csr_set(CSR_SSTATUS, SSTATUS_SUM);
struct vm_branch_t *b = init_vmem(fdt);
init_mem_blocks();
init_irq(fdt);
diff --git a/arch/riscv/kernel/vmem.c b/arch/riscv/kernel/vmem.c
index ffe8731..4cb84a6 100644
--- a/arch/riscv/kernel/vmem.c
+++ b/arch/riscv/kernel/vmem.c
@@ -11,6 +11,11 @@
#define pte_addr(pte) (pnum_to_paddr(pte_ppn(pte)))
#define vm_to_index(a, o) (pm_to_index(a, o))
+void mod_vmem(struct vm_branch_t *branch, vm_t vaddr, uint8_t flags, enum mm_order_t order)
+{
+ /* todo */
+}
+
void map_vmem(struct vm_branch_t *branch,
pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order)
{
diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk
index ecc22bd..0e9a5c3 100644
--- a/arch/riscv/source.mk
+++ b/arch/riscv/source.mk
@@ -1,5 +1,6 @@
KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS]
KERNEL_SOURCES += $(KERNEL_LOCAL)
+INIT_SOURCES += arch/riscv/init/init.c
CLEANUP_CMD := ./arch/riscv/conf/rmimage.sh