From 3fedbb6e1f849c5e0a4033d68201d60c2fc48121 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 6 Jul 2024 23:37:11 +0300 Subject: core bringup + various warnings + dbg_fdt() is apparently broken, possibly due to UB or something, but it causes some issues with optimizations enabled. Remove it temporarily --- arch/riscv64/kernel/core_bringup.S | 4 ++-- arch/riscv64/kernel/smp.c | 5 +++-- arch/riscv64/kernel/vmem.c | 2 +- arch/riscv64/source.mk | 2 +- include/kmi/lock.h | 2 +- include/kmi/mem.h | 4 ++++ include/kmi/orphanage.h | 2 +- include/libfdt.h | 2 +- src/elf.c | 3 +++ src/main.c | 8 +++++--- src/mem.c | 17 +++++++++++++++-- src/pmem.c | 1 + src/tcb.c | 2 +- 13 files changed, 39 insertions(+), 15 deletions(-) diff --git a/arch/riscv64/kernel/core_bringup.S b/arch/riscv64/kernel/core_bringup.S index aff9b0b..83b017c 100644 --- a/arch/riscv64/kernel/core_bringup.S +++ b/arch/riscv64/kernel/core_bringup.S @@ -12,12 +12,12 @@ riscv_bringup: sfence.vma /* fetch the stack allocated to us at our hart index in smp_init_stacks */ - la t0, smp_init_stacks + lla t0, smp_init_stacks slli t1, a0, RW_SHIFT add t0, t0, t1 lr sp, 0(t0) mv tp, sp /* jump to C to handle rest of bringup */ - la t0, core_bringup + lla t0, core_bringup jr t0 diff --git a/arch/riscv64/kernel/smp.c b/arch/riscv64/kernel/smp.c index 8d04491..74cc930 100644 --- a/arch/riscv64/kernel/smp.c +++ b/arch/riscv64/kernel/smp.c @@ -93,8 +93,9 @@ void smp_bringup(struct vmem *b, void *fdt) /** @todo try to remember to free these as well */ smp_init_stacks[hartid] = (void *)alloc_page(BASE_PAGE) + BASE_PAGE_SIZE; - r = sbi_hart_start(hartid, - (unsigned long)__pa(riscv_bringup), satp); + + pm_t bringup = (pm_t)__pa(riscv_bringup); + r = sbi_hart_start(hartid, bringup, satp); if (r.error) { warn("failed bringing up hart %ld: %ld\n", diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 00752c1..97b9cce 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -536,7 +536,7 @@ void setup_rpc_stack(struct tcb *t) * which means that it must also be the leaf */ t->arch.rpc_leaf = (struct vmem *)__find_vmem(t->rpc.vmem, RPC_STACK_BASE, - BASE_PAGE); + NULL); /* we count downward in base pages */ t->arch.rpc_idx = rpc_pages; } diff --git a/arch/riscv64/source.mk b/arch/riscv64/source.mk index e4c1f10..6e72c85 100644 --- a/arch/riscv64/source.mk +++ b/arch/riscv64/source.mk @@ -3,7 +3,7 @@ KERNEL_SOURCES += $(KERNEL_LOCAL) INIT_SOURCES += $(ARCH_SOURCE)/init/*.[cS] # this doesn't work for rv32, but fine for now */ -ARCH_CFLAGS += -mcmodel=medany +ARCH_CFLAGS := $(ARCH_CFLAGS) -mcmodel=medany # oof, LLVM's riscv support has become better since I last looked into # it, but for some reason LTO still causes a crash. Meaning it has to be diff --git a/include/kmi/lock.h b/include/kmi/lock.h index f24413c..192eb34 100644 --- a/include/kmi/lock.h +++ b/include/kmi/lock.h @@ -22,7 +22,7 @@ * * \todo irq contexts? */ -typedef atomic_int spinlock_t; +typedef int spinlock_t; #include diff --git a/include/kmi/mem.h b/include/kmi/mem.h index f2b7b74..d3c4da2 100644 --- a/include/kmi/mem.h +++ b/include/kmi/mem.h @@ -224,6 +224,8 @@ void set_ram_base(pm_t base); /** @param size Set RAM size. */ void set_ram_size(size_t size); +void set_load_addr(pm_t addr); + /** * Get RAM base address. * Very much assumes set_ram_base() has been called beforehand. @@ -241,6 +243,8 @@ pm_t get_ram_base(); */ size_t get_ram_size(); +pm_t get_load_addr(); + /** Base page size. */ #define BASE_PAGE_SIZE (order_size(BASE_PAGE)) diff --git a/include/kmi/orphanage.h b/include/kmi/orphanage.h index db5a617..98756c2 100644 --- a/include/kmi/orphanage.h +++ b/include/kmi/orphanage.h @@ -2,7 +2,7 @@ /* Copyright 2024, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ #ifndef KMI_ORPHANAGE_H -#define KMI_OPRHANAGE_H +#define KMI_ORPHANAGE_H /** * @file orphanage.h diff --git a/include/libfdt.h b/include/libfdt.h index c603840..c1d6a4e 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -99,7 +99,7 @@ void __dbg_fdt(const void *fdt, int node_offset, int depth); static inline fdt64_t fdt_load_reg_addr(struct cell_info ci, const void *p, size_t i) { - hard_assert(ci.addr_cells == 2 || ci.addr_cells == 1, 0); + catastrophic_assert(ci.addr_cells == 2 || ci.addr_cells == 1); size_t offset = i * (ci.addr_cells + ci.size_cells) * sizeof(fdt32_t); char *addr = ((char *)p) + 0; return fdt_load_int_ptr(ci.addr_cells, addr + offset); diff --git a/src/elf.c b/src/elf.c index a38f3c2..9add641 100644 --- a/src/elf.c +++ b/src/elf.c @@ -69,6 +69,8 @@ static void __map_exec(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart, if (!start) return; /* out of memory or something */ + info("mapped ELF section to %x\n", start); + uint8_t elf_flags = program_header_prop(ei_c, runner, p_flags); uint8_t uvflags = __elf_to_uvflags(elf_flags); @@ -108,6 +110,7 @@ static vm_t __map_dyn(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart, /** \todo this path should only be taken when no PT_INTERP is defined, as * making sure ld is loaded should be done in userspace. Maybe a bit * hacky, I know.*/ + return 0; } /** diff --git a/src/main.c b/src/main.c index 1f4c250..169efc3 100644 --- a/src/main.c +++ b/src/main.c @@ -61,14 +61,12 @@ __noreturn void kernel(void *fdt, uintptr_t load_addr, struct vmem *d) /* we should be in kernelspace, so use the virtual address of our FDT. */ fdt = __va(fdt); - bkl_lock(); - /* dbg uses direct mapping at this point */ init_dbg(fdt); /* start up debugging in kernel IO */ setup_io_dbg(d); - dbg_fdt(fdt); + //dbg_fdt(fdt); setup_arch(fdt); @@ -80,11 +78,14 @@ __noreturn void kernel(void *fdt, uintptr_t load_addr, struct vmem *d) vm_t proc_fdt = 0, proc_initrd = 0; init_proc(fdt, &proc_fdt, &proc_initrd); + /* lock kernel since we're about to start other threads as well */ + bkl_lock(); /* try to bring up other cores on system */ smp_bringup(d, fdt); /* start running init program */ run_init(cur_tcb(), proc_fdt, proc_initrd); + unreachable(); } /** @@ -110,6 +111,7 @@ __noreturn void main(unsigned long hart, void *fdt, uintptr_t load_addr) pm_t ram_size = __fdt_ram_size(fdt); set_ram_base(ram_base); set_ram_size(ram_size); + set_load_addr(load_addr); init_mem(fdt); diff --git a/src/mem.c b/src/mem.c index 4fb9d5a..89657e8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -26,6 +26,9 @@ pm_t ram_base; /** RAM size. */ size_t ram_size; +/** Load address. */ +pm_t load_addr; + enum mm_order nearest_order(size_t size) { for (enum mm_order order = max_order(); order >= MM_MIN; --order) @@ -56,7 +59,7 @@ void init_mem(void *fdt) } } -void set_ram_base(uintptr_t base) +void set_ram_base(pm_t base) { ram_base = base; } @@ -66,7 +69,12 @@ void set_ram_size(size_t size) ram_size = size; } -uintptr_t get_ram_base() +void set_load_addr(pm_t addr) +{ + load_addr = addr; +} + +pm_t get_ram_base() { return ram_base; } @@ -75,3 +83,8 @@ size_t get_ram_size() { return ram_size; } + +uintptr_t get_load_addr() +{ + return load_addr; +} diff --git a/src/pmem.c b/src/pmem.c index cf70c3f..fac7731 100644 --- a/src/pmem.c +++ b/src/pmem.c @@ -604,6 +604,7 @@ static pm_t select_base(pm_t ram_base, pm_t ram_size, pm_t size, return base; retry: + continue; } return 0; diff --git a/src/tcb.c b/src/tcb.c index 45c31ce..27256e9 100644 --- a/src/tcb.c +++ b/src/tcb.c @@ -303,7 +303,7 @@ void unreference_proc(struct tcb *p) hard_assert(is_proc(p), RETURN_VOID); p->refcount--; if (zombie(p) && p->refcount == 0) { - dbg("thread %d is completely destroyed\n", p->tid); + dbg("thread %ld is completely destroyed\n", (long)p->tid); __destroy_thread_data(p); } } -- cgit v1.3