aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64/init
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv64/init')
-rw-r--r--arch/riscv64/init/init.c72
-rw-r--r--arch/riscv64/init/start.S12
2 files changed, 84 insertions, 0 deletions
diff --git a/arch/riscv64/init/init.c b/arch/riscv64/init/init.c
new file mode 100644
index 0000000..7aecfb5
--- /dev/null
+++ b/arch/riscv64/init/init.c
@@ -0,0 +1,72 @@
+#include <apos/types.h>
+#include <apos/attrs.h>
+#include <apos/utils.h>
+#include <apos/vmem.h>
+#include <vmem.h>
+#include <csr.h>
+
+/* assume 64 bit for now */
+struct __packed init_vmem {
+ int *leaf[512];
+};
+
+struct init_vmem *root_branch;
+
+#define to_pte(a, f) (((a) >> 12) << 10 | (f))
+
+/* assume Sv39 for now */
+void init_bootmem()
+{
+ size_t flags = VM_V | VM_X | VM_R | VM_W;
+
+ extern char *__init_start;
+ root_branch = (struct init_vmem *)align_down((size_t)&__init_start - SZ_4K, SZ_4K);
+
+ /* direct mapping (temp) */
+ for(size_t i = 0; i < CSTACK_PAGE; ++i)
+ root_branch->leaf[i] = (int*)to_pte(SZ_1G * i, flags);
+
+ /* kernel (also sort of direct mapping) */
+ flags |= VM_G;
+ for(size_t i = KSTART_PAGE; i < IO_PAGE; ++i)
+ root_branch->leaf[i] = (int *)to_pte(RAM_BASE + SZ_1G * (i - 256), flags);
+
+ /* kernel IO, map to 0 for now, will be updated in the future */
+ root_branch->leaf[IO_PAGE] = (int *)to_pte(0, flags);
+
+ csr_write(CSR_SATP, SATP_MODE_Sv39 | ((size_t)root_branch >> 12));
+}
+
+void move_kernel()
+{
+ extern char *__init_end;
+ extern char *__kernel_size;
+
+ size_t sz = (size_t)&__kernel_size;
+ char *src = (char *)&__init_end;
+ char *dst = (char *)VM_KERN;
+ for(size_t i = 0; i < sz; ++i)
+ dst[i] = src[i];
+}
+
+#define __va_reg(reg)\
+{\
+ vm_t reg = 0;\
+ __asm__("mv %0, " QUOTE(reg) : "=r" (reg) :: );\
+ reg = (vm_t)__va(reg);\
+ __asm__("mv " QUOTE(reg) ", %0" :: "rK" (reg) : );\
+}
+
+void init(void *fdt)
+{
+ extern char *__init_end;
+ extern void jump_to_kernel(void *k, void *fdt);
+ void (*kernel_main)(void *fdt) = (void (*)(void *))(VM_KERN);
+ init_bootmem();
+ move_kernel();
+ __va_reg(sp);
+ __va_reg(fp);
+ __va_reg(gp);
+ jump_to_kernel((void *)VM_KERN, __va(fdt));
+ //kernel_main(__va(fdt));
+}
diff --git a/arch/riscv64/init/start.S b/arch/riscv64/init/start.S
new file mode 100644
index 0000000..7842946
--- /dev/null
+++ b/arch/riscv64/init/start.S
@@ -0,0 +1,12 @@
+.section .init.start
+.global _start
+_start:
+li sp, PM_STACK_TOP
+call init
+
+.section .text
+.global jump_to_kernel
+jump_to_kernel:
+mv a2, a0 // store kernel addr
+mv a0, a1 // move fdt pointer to first argument
+jr a2 // jump to kernel