aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64/kernel
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-07-05 19:38:11 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-07-05 19:38:11 +0300
commite09edb5d54e39bd9509a1dc450df5ab320759f97 (patch)
tree78e050b0db87df3a3ddfbb6570d44513ac34e02a /arch/riscv64/kernel
parent98f21e694a6b0964d6d08196cb6bfbc1c2ae2ff4 (diff)
downloadkmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.tar.gz
kmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.zip
allow booting with Qemu's -kernel flag directly
+ Took some fairly significant changes, for one the kernel is no longer relocated at the start of a boot, instead it sits wherever the user decides the kernel should sit. Similarly, the initial kernel stack and page table are stored within the binary, slightly bloating the size but making it much safer to boot since there's really no chance of us overwriting the fdt or initrd in memory.
Diffstat (limited to 'arch/riscv64/kernel')
-rw-r--r--arch/riscv64/kernel/arch.c3
-rw-r--r--arch/riscv64/kernel/proc.c2
-rw-r--r--arch/riscv64/kernel/start.S36
-rw-r--r--arch/riscv64/kernel/vmem.c20
4 files changed, 54 insertions, 7 deletions
diff --git a/arch/riscv64/kernel/arch.c b/arch/riscv64/kernel/arch.c
index ff2c04c..ec4cf43 100644
--- a/arch/riscv64/kernel/arch.c
+++ b/arch/riscv64/kernel/arch.c
@@ -19,7 +19,7 @@ id_t hartid_to_cpuid(id_t hart)
if (cpuid_to_hartid(i) == hart)
return i;
- error("failed to match hart id %ld to cpu id\n", hart);
+ error("failed to match hart id %ld to cpu id\n", (long)hart);
/* default to zero, though this should maybe be a panic? */
return 0;
}
@@ -27,7 +27,6 @@ id_t hartid_to_cpuid(id_t hart)
pm_t branch_to_satp(struct vmem *branch, enum mm_mode mode)
{
/* Sv57 && Sv64 in the future? */
- branch = (struct vmem *)__pa(branch);
pm_t pn = (pm_t)(branch) >> page_shift();
pm_t m = DEFAULT_Sv_MODE;
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c
index 4e4d7ec..55ccbb8 100644
--- a/arch/riscv64/kernel/proc.c
+++ b/arch/riscv64/kernel/proc.c
@@ -15,7 +15,7 @@
#include "regs.h"
#include "csr.h"
-void run_init(struct tcb *t, void *fdt, void *initrd)
+void run_init(struct tcb *t, vm_t fdt, vm_t initrd)
{
/** \todo actually map fdt and initrd into the target address space */
csr_write(CSR_SSCRATCH, t);
diff --git a/arch/riscv64/kernel/start.S b/arch/riscv64/kernel/start.S
new file mode 100644
index 0000000..4978cc0
--- /dev/null
+++ b/arch/riscv64/kernel/start.S
@@ -0,0 +1,36 @@
+#if GENERIC_UBOOT
+# define MAIN main_go
+#else
+# define LOAD_REG a1
+# define MAIN main
+#endif
+
+.section .kernel.start
+.global _start
+_start:
+/* get load address */
+auipc a2, 0
+
+/* load initial stack */
+lla sp, riscv_init_stack
+li t0, 4096
+add sp, sp, t0
+
+/* set thread pointer to zero so we don't accidentally try to use a tcb */
+li tp, 0
+
+/* call main, whichever one is relevant */
+call MAIN
+ret
+
+.section .text
+
+/* a0 is fdt, a1 is load_addr, a2 is d, a3 is ram_base, a4 is DMAP */
+.global to_kernelspace
+to_kernelspace:
+lla t0, kernel
+add t0, t0, a4
+sub t0, t0, a3
+add sp, sp, a4
+sub sp, sp, a3
+jr t0
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c
index cc6f3ac..835f53d 100644
--- a/arch/riscv64/kernel/vmem.c
+++ b/arch/riscv64/kernel/vmem.c
@@ -399,13 +399,26 @@ static void __populate_dmap(struct vmem *branch)
/** How many base pages we use for the rpc stack. Used fairly often so calculate
* it at the start and then reference it. */
static size_t rpc_pages;
+long riscv_init_stack[4096 / sizeof(long)];
+__attribute__((aligned(4096))) struct vmem bootvmem;
+
+struct vmem *direct_mapping()
+{
+ rpc_pages = order_size(MM_O1) / BASE_PAGE_SIZE;
+
+ __populate_dmap(&bootvmem);
+ populate_kvmem(&bootvmem);
+ __use_vmem(&bootvmem, DEFAULT_Sv_MODE);
+
+ return &bootvmem;
+}
+
struct vmem *init_vmem(void *fdt)
{
UNUSED(fdt);
struct vmem *b = create_vmem();
__populate_dmap(b);
- rpc_pages = order_size(MM_O1) / BASE_PAGE_SIZE;
/* update which memory branch to use */
use_vmem(b);
return b;
@@ -415,14 +428,13 @@ struct vmem *create_vmem()
{
struct vmem *b = (struct vmem *)alloc_page(MM_KPAGE);
memset(b, 0, MM_KPAGE_SIZE);
-
populate_kvmem(b);
return b;
}
stat_t use_vmem(struct vmem *b)
{
- __use_vmem(b, DEFAULT_Sv_MODE);
+ __use_vmem(__pa(b), DEFAULT_Sv_MODE);
return OK;
}
@@ -457,7 +469,7 @@ vm_t setup_kernel_io(struct vmem *b, vm_t paddr)
* modifying, or during the startup stage where we don't have a tcb yet.
* I don't think checking the rpc context is necessary? */
if (!cur_tcb() || cur_tcb()->proc.vmem == b)
- flush_tlb((uintptr_t)pte_addr(b->leaf[IO_PAGE]));
+ flush_tlb_full();
return -TOP_PAGE_SIZE + paddr - addr;
}