From d592abd8ccc4026c51e196777031eb65c4acc4de Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 7 Jul 2024 14:34:39 +0300 Subject: misc fixes + Align kernel to 2MiB boundary in u-boot + Optimize alignment functions a little bit, should still have to check on real hardware but 'feels' more clean + Add early boot debugging + Put extra cores we aren't ready to account for to sleep if/when they boot. + Make BASE_PAGE_SIZE constant on riscv64/32, helps the compiler with some alignment checks among other things. --- arch/riscv64/kernel/arch.c | 7 ++++++- arch/riscv64/kernel/proc.c | 8 ++++---- arch/riscv64/kernel/vmem.c | 13 ++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) (limited to 'arch/riscv64/kernel') diff --git a/arch/riscv64/kernel/arch.c b/arch/riscv64/kernel/arch.c index ec4cf43..4561d8b 100644 --- a/arch/riscv64/kernel/arch.c +++ b/arch/riscv64/kernel/arch.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include "csr.h" #include "arch.h" @@ -19,8 +21,11 @@ id_t hartid_to_cpuid(id_t hart) if (cpuid_to_hartid(i) == hart) return i; + /* put extra cores to sleep so they don't do anything bad */ error("failed to match hart id %ld to cpu id\n", (long)hart); - /* default to zero, though this should maybe be a panic? */ + bkl_unlock(); + sleep(); + /* should never really be reached but eh */ return 0; } diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index af4b2f3..4310378 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -33,13 +33,13 @@ void run_init(struct tcb *t, vm_t fdt, vm_t initrd) "li a0, %1\n" "li a1, %2\n" "mv a2, %3\n" - "mv a3, %4\n" - "mv a4, %5\n" + "mv a3, %4\n" + "mv a4, %5\n" "sret\n" : : "r" (stack_top), - "K"(0), "K"(SYS_USER_BOOTED), - "r" (t->tid), "r" (fdt), "r" (initrd) + "K" (0), "K" (SYS_USER_BOOTED), + "r" (t->tid), "r" (fdt), "r" (initrd) : "memory"); /* we should never reach this */ unreachable(); diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 0aa35cc..cb1eba0 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -420,11 +420,15 @@ __aligned(4096) struct vmem bootvmem; * it. */ __aligned(4096) struct vmem kvmem; +/* adding a third page entry would let us map the kernel at any 4KiB boundary + * but eh, Linux seems fine with 2MiB so I guess I shall be as well. */ + struct vmem *init_mapping() { rpc_pages = order_size(MM_O1) / BASE_PAGE_SIZE; kvmem.leaf[0] = (struct vmem *)to_pte(get_load_addr(), - VM_A | VM_G | VM_D | VM_R | VM_W | VM_X | VM_V); + VM_A | VM_G | VM_D | VM_R | VM_W | + VM_X | VM_V); __populate_dmap(&bootvmem); populate_kvmem(&bootvmem); @@ -462,6 +466,13 @@ void destroy_vmem(struct vmem *b) __destroy_branch(b); } +/** + * Helper for mapping in the kernel virtual page. + * Remember that the kernel lives on its own in a 2MiB (riscv64) region at + * VM_KERNEL, and \ref __va() and \ref __pa() won't directly work on it. + * + * @param b Branch to map kernel into. + */ static void map_kernel(struct vmem *b) { /* slightly worried about this not being guaranteed to be pc relative, -- cgit v1.3