From 6b2465318b2dc922de282deea96c1621f7f41039 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 20 Dec 2021 13:29:01 +0200 Subject: Revert "still some issues with vmem" This reverts commit 69d13626a37e33f31627a1144605a8fb93684d25. --- Makefile | 27 ++-- arch/riscv/common/vmem.c | 57 -------- arch/riscv/conf/init-link.S | 1 - arch/riscv/init/init.c | 325 +++----------------------------------------- arch/riscv/kernel/vmem.c | 57 ++++++++ arch/riscv/source.mk | 6 +- include/apos/init.h | 30 ---- include/apos/vmem.h | 5 - kernel/temp.c | 0 scripts/gen-deps | 30 +--- 10 files changed, 93 insertions(+), 445 deletions(-) delete mode 100644 arch/riscv/common/vmem.c create mode 100644 arch/riscv/kernel/vmem.c delete mode 100644 include/apos/init.h delete mode 100644 kernel/temp.c diff --git a/Makefile b/Makefile index 2a388e8..80fe0e5 100644 --- a/Makefile +++ b/Makefile @@ -20,11 +20,10 @@ OBJCOPY ?= objcopy # This makes sure .bss is loaded into the binary OBJCOPY_FLAGS ?= -Obinary --set-section-flags .bss=alloc,load,contents -COMMON_SOURCES != echo common/*.c lib/fdt*.c -KERNEL_SOURCES != echo kernel/*.c $(COMMON_SOURCES) -INIT_SOURCES := $(COMMON_SOURCES) +KERNEL_SOURCES != echo common/*.c lib/*.c CLEANUP := build deps.mk kernel.* init.* apos.bin CLEANUP_CMD := +INIT_SOURCES := include arch/$(ARCH)/source.mk @@ -45,29 +44,27 @@ KERN_INFO = sed "s//$$($(KERN_SIZE))/" KERNEL_LINK := arch/$(ARCH)/conf/kernel-link INIT_LINK := arch/$(ARCH)/conf/init-link -KERNEL_OBJECTS != ./scripts/gen-deps --kern "$(KERNEL_SOURCES)" -INIT_OBJECTS != ./scripts/gen-deps --init "$(INIT_SOURCES)" -KERNEL_LD != ./scripts/gen-deps --kern-link "$(KERNEL_LINK).S" -INIT_LD != ./scripts/gen-deps --init-link "$(INIT_LINK).S" +KERNEL_OBJECTS != ./scripts/gen-deps --compile "$(KERNEL_SOURCES)" +INIT_OBJECTS != ./scripts/gen-deps --compile "$(INIT_SOURCES)" +KERNEL_LD != ./scripts/gen-deps --link "$(KERNEL_LINK).S" +INIT_LD != ./scripts/gen-deps --link "$(INIT_LINK).S" include deps.mk -apos.bin: kernel.bin init.bin - cat init.bin kernel.bin > $@ +init.elf: $(INIT_OBJECTS) $(INIT_LD) + $(GENELF) -T $(INIT_LD) $(INIT_OBJECTS) -o $@ kernel.elf: $(KERNEL_OBJECTS) $(KERNEL_LD) $(GENELF) -T $(KERNEL_LD) $(KERNEL_OBJECTS) -o $@ -$(INIT_LD): kernel.bin - -init.elf: $(INIT_OBJECTS) $(INIT_LD) - $(GENELF) -T $(INIT_LD) $(INIT_OBJECTS) -o $@ +init.bin: init.elf + $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ kernel.bin: kernel.elf $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ -init.bin: init.elf - $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ +apos.bin: init.bin kernel.bin + cat init.bin kernel.bin > apos.bin clean: $(RM) -r $(CLEANUP) diff --git a/arch/riscv/common/vmem.c b/arch/riscv/common/vmem.c deleted file mode 100644 index 4cb84a6..0000000 --- a/arch/riscv/common/vmem.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define pte_ppn(pte) (((pm_t)(pte)) >> 10) -#define pte_flags(pte) (((pm_t)(pte)) & 0xff) -#define to_pte(p, f) ((pm_to_pnum(p) << 10) + (f)) -#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) -{ - enum mm_order_t top = __mm_max_order; - while (top != order) { - size_t idx = vm_to_index(vaddr, top); - - if (!branch->leaf[idx]) { - pm_t new_leaf = alloc_page(MM_KPAGE, 0); - branch->leaf[idx] = - (struct vm_branch_t *)to_pte(new_leaf, VM_V); - - void *leaf_ptr = (void *)new_leaf; - memset(leaf_ptr, 0, sizeof(struct vm_branch_t)); - } - - pm_t pte = (pm_t)branch->leaf[idx]; - pm_t branch_pptr = (pm_t)pte_addr(pte); - branch = (struct vm_branch_t *)branch_pptr; - top--; - } - - size_t idx = vm_to_index(vaddr, top); - branch->leaf[idx] = (struct vm_branch_t *)to_pte(paddr, flags); -} - -void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr, enum mm_order_t order) -{ - while (order) { - size_t idx = pm_to_index(vaddr, order); - branch = (struct vm_branch_t *)pte_addr(branch->leaf[idx]); - } - - size_t idx = pm_to_index(vaddr, order); - if (branch->leaf[idx]) - free_page(order, pte_addr(branch->leaf[idx])); - - branch->leaf[idx] = 0; -} diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S index 752edc2..642e831 100644 --- a/arch/riscv/conf/init-link.S +++ b/arch/riscv/conf/init-link.S @@ -27,5 +27,4 @@ SECTIONS { } __init_end = . ; - __kernel_size = ; } diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index 7606feb..d9b32a0 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -1,322 +1,29 @@ -/* TODO: cleanup :P */ - -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -struct pm_layout_t { - pm_t base; - pm_t top; -}; - -struct pm_orders_t { - size_t max_order; - size_t bits[10]; - size_t page_shift; +/* assume 64 bit for now */ +struct __packed init_vmem { + int *leaf[512]; }; -static struct pm_layout_t get_memlayout(void *fdt) -{ - struct cell_info_t ci = get_reginfo(fdt, "/memory"); - int mem_offset = fdt_path_offset(fdt, "/memory"); - uint8_t *mem_reg = - (uint8_t *) fdt_getprop(fdt, mem_offset, "reg", NULL); - - /* if riscv128 comes around we will probably see addr_cells == 4, but - * I'm not too concerned about it at the moment */ - pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, mem_reg); - - if(ci.addr_cells == 2) - mem_reg += sizeof(fdt64_t); - else - mem_reg += sizeof(fdt32_t); - - /* -1 because base is a legitimate memory address */ - pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1; - return (struct pm_layout_t){base, top}; -} - -#ifdef DEBUG - -static void init_debug(void *fdt) -{ - struct dbg_info_t dbg = dbg_from_fdt(fdt); - dbg_init(dbg.dbg_ptr, dbg.dev); -} - -#else -#define init_debug(...) -#endif - -static pm_t get_kerneltop() -{ - /* interesting, for some reason if I define these to be just char - * pointers I get some wacky values. Not sure why that would be, but - * this works. */ - extern char __init_end, __kernel_size; - return (pm_t)&__init_end + (pm_t)&__kernel_size; -} - -static pm_t get_initrdtop(void *fdt) -{ - int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); - - void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset, - "linux,initrd-end", NULL); - - return (pm_t)fdt_load_int_ptr(ci.addr_cells, initrd_end_ptr); -} - -static pm_t get_initrdbase(void *fdt) -{ - int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); - - void *initrd_base_ptr = (void *)fdt_getprop(fdt, chosen_offset, - "linux,initrd-start", NULL); - - return (pm_t)fdt_load_int_ptr(ci.addr_cells, initrd_base_ptr); -} - -static pm_t get_fdttop(void *fdt) -{ - const char *b = (const char *)fdt; - return (pm_t)(b + fdt_totalsize(fdt)); -} - -static pm_t get_fdtbase(void *fdt) -{ - /* lol */ - return (pm_t)fdt; -} - -static void mark_area_used(pm_t base, pm_t top) -{ - size_t area_left = top - base; - /* TODO: add in a method to make sure that we use as large mappings as - * possible. */ - while(area_left >= MM_KPAGE_SIZE){ - mark_used(base, MM_KPAGE); - area_left -= MM_KPAGE_SIZE; - base += MM_KPAGE_SIZE; - } - - if(area_left != 0) - mark_used(base, MM_KPAGE_SIZE); -} - -static void mark_reserved_mem(void *fdt) -{ - int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0"); - struct cell_info_t ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0"); - uint8_t *rmem_reg = (uint8_t *)fdt_getprop(fdt, rmem_offset, "reg", NULL); - - pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, rmem_reg); - - if(ci.addr_cells == 2) - rmem_reg += sizeof(fdt64_t); - else - rmem_reg += sizeof(fdt32_t); - - pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, rmem_reg) + base - 1; - mark_area_used(base, top); -} - -static struct pm_orders_t init_pmem(void *fdt) -{ - enum mm_mode_t mmode = get_mmode(fdt); - - size_t max_order = 0; - size_t order_bits = 9; - switch(mmode){ - case Sv32: - max_order = 1; - order_bits = 10; - break; - - case Sv39: - max_order = 2; - break; - - case Sv48: - max_order = 3; - break; - }; +struct init_vmem root_branch; - size_t bits[10] = {0}; - for(size_t i = 0; i <= max_order; ++i) - bits[i] = order_bits; - - init_mem(max_order, bits, 12); - - struct pm_orders_t ret = {max_order, {0}, 12}; - for(size_t i = 0; i <= __mm_max_order; ++i) - ret.bits[i] = bits[i]; - - return ret; -} - -static struct pm_layout_t setup_pmem(void *fdt) -{ - struct pm_layout_t pmem = get_memlayout(fdt); - - pm_t initrd_top = get_initrdtop(fdt); - pm_t kernel_top = get_kerneltop(); - pm_t fdt_top = get_fdttop(fdt); - - pm_t top = MAX3(kernel_top, initrd_top, fdt_top); - dbg("initrd_top:\t%#lx\n", initrd_top); - dbg("kernel_top:\t%#lx\n", kernel_top); - dbg("fdt_top:\t%#lx\n", fdt_top); - - /* TODO: check that pmap placement doesn't overwrite anything, such as - * stack or go over top address of memory */ - size_t probe_size = probe_pmap(pmem.base, pmem.top - pmem.base); - /* riscv handles two byte boundaries better than one byte, so align - * upwards */ - pm_t pmap_base = align_up(top + 1, 2); - size_t actual_size = populate_pmap(pmem.base, pmem.top - pmem.base, - pmap_base); - - /* TODO: not entirely sure what to do about this, probably give up trying to - * boot? */ - if(probe_size != actual_size){ - dbg("BUG! probe_size (%#lx) != actual_size (%#lx)\n", - probe_size, actual_size); - } - - /* mark init stack, at the moment always mapped to 2M */ - mark_used(PM_STACK_BASE, MM_MPAGE); - - /* mark kernel, at the moment it is always mapped to a 2M partition */ - mark_used(PM_KERN, MM_MPAGE); - - /* mark fdt and initrd */ - mark_area_used(get_initrdbase(fdt), initrd_top); - mark_area_used(get_fdtbase(fdt), fdt_top); - - /* mark pmap */ - mark_area_used(pmap_base, pmap_base + actual_size); - - /* mark reserved mem */ - mark_reserved_mem(fdt); - - return (struct pm_layout_t){.base = pmap_base, .top = actual_size + pmap_base}; -} - -pm_t move_kernel() +/* assume Sv48 for now */ +void init_lowmem() { - extern char __init_end, __kernel_size; - pm_t dst = alloc_page(MM_MPAGE, 0); - memmove((void *)dst, &__init_end, (size_t)&__kernel_size); + 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); - return dst; -} - -struct vm_branch_t *prepare_vmem() -{ - pm_t kernel_dst = move_kernel(); - - /* TODO: check if this actually works */ - struct vm_branch_t *branch = (struct vm_branch_t *)alloc_page(MM_KPAGE, 0); - memset(branch, 0, sizeof(struct vm_branch_t)); - - /* TODO: check mapping flags, also iron out possible bugs etc in - * map_vmem */ - /* map kernel */ - map_vmem(branch, kernel_dst, VM_KERN, VM_R | VM_W | VM_G | VM_X | VM_V, MM_MPAGE); - - /* map init */ - map_vmem(branch, PM_KERN, PM_KERN, VM_R | VM_W | VM_X | VM_V, MM_MPAGE); - - /* map stack */ - map_vmem(branch, PM_STACK_BASE, PM_STACK_BASE, VM_R | VM_W | VM_V, MM_MPAGE); - - /* map root pte */ - map_vmem(branch, (pm_t)branch, ROOT_PTE, VM_R | VM_W | VM_V, MM_KPAGE); - - /* TODO: map more stuff? */ - return branch; -} - -void start_vmem(void *fdt, struct vm_branch_t *branch) -{ - /* TODO: get ASID from CPU id */ - - /* TODO: probably unnecessary optimisations but this could be cached? */ - enum mm_mode_t m = get_mmode(fdt); - - if(m == Sv32) - csr_write(CSR_SATP, SATP_MODE_Sv32 | pm_to_pnum((pm_t)(branch))); - else if (m == Sv39) - csr_write(CSR_SATP, SATP_MODE_Sv39 | pm_to_pnum((pm_t)(branch))); - else - csr_write(CSR_SATP, SATP_MODE_Sv48 | pm_to_pnum((pm_t)(branch))); - - __asm__ ("sfence.vma" : : : "memory"); - /* Sv57 && Sv64 in the future? */ -} - -struct init_data_t populate_initdata(void *fdt, struct pm_orders_t o, - struct pm_layout_t p, - struct vm_branch_t *b) -{ - extern char __init_start, __init_end; - - struct init_data_t d = {0}; - d.init_base = (pm_t)&__init_start; - d.init_top = (pm_t)&__init_end; - - d.initrd_base = get_initrdbase(fdt); - d.initrd_top = get_initrdtop(fdt); - - d.pmap_base = p.base; - d.pmap_top = p.top; - - d.fdt_base = get_fdtbase(fdt); - d.fdt_top = get_fdttop(fdt); - - d.stack_base = PM_STACK_BASE; - d.stack_top = PM_STACK_TOP; - - d.kernel_vm_base = b; - - d.max_order = o.max_order; - for(size_t i = 0; i <= __mm_max_order; ++i) - d.bits[i] = o.bits[i]; - d.page_shift = o.page_shift; - - /* initialize pmap in vmem */ - pm_t addr = p.base; - while(addr < p.top){ - map_vmem(b, addr, addr, VM_R | VM_W | VM_V, MM_MPAGE); - addr += MM_MPAGE_SIZE; - } - - return d; + csr_write(CSR_SATP, SATP_MODE_Sv48 | ((size_t)&root_branch >> 12)); } void __section(".init.start") main(void *fdt) { - init_debug(fdt); - dbg_fdt(fdt); - - struct pm_orders_t o = init_pmem(fdt); - struct pm_layout_t p = setup_pmem(fdt); - struct vm_branch_t *b = prepare_vmem(); - struct init_data_t d = populate_initdata(fdt, o, p, b); - start_vmem(fdt, b); - - /* update_pmap(TODO: figure out where to place pmap in vmem); */ - void (*main)(struct init_data_t) = (void (*)(struct init_data_t))VM_KERN; - main(d); + 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/vmem.c b/arch/riscv/kernel/vmem.c new file mode 100644 index 0000000..4cb84a6 --- /dev/null +++ b/arch/riscv/kernel/vmem.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include + +#define pte_ppn(pte) (((pm_t)(pte)) >> 10) +#define pte_flags(pte) (((pm_t)(pte)) & 0xff) +#define to_pte(p, f) ((pm_to_pnum(p) << 10) + (f)) +#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) +{ + enum mm_order_t top = __mm_max_order; + while (top != order) { + size_t idx = vm_to_index(vaddr, top); + + if (!branch->leaf[idx]) { + pm_t new_leaf = alloc_page(MM_KPAGE, 0); + branch->leaf[idx] = + (struct vm_branch_t *)to_pte(new_leaf, VM_V); + + void *leaf_ptr = (void *)new_leaf; + memset(leaf_ptr, 0, sizeof(struct vm_branch_t)); + } + + pm_t pte = (pm_t)branch->leaf[idx]; + pm_t branch_pptr = (pm_t)pte_addr(pte); + branch = (struct vm_branch_t *)branch_pptr; + top--; + } + + size_t idx = vm_to_index(vaddr, top); + branch->leaf[idx] = (struct vm_branch_t *)to_pte(paddr, flags); +} + +void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr, enum mm_order_t order) +{ + while (order) { + size_t idx = pm_to_index(vaddr, order); + branch = (struct vm_branch_t *)pte_addr(branch->leaf[idx]); + } + + size_t idx = pm_to_index(vaddr, order); + if (branch->leaf[idx]) + free_page(order, pte_addr(branch->leaf[idx])); + + branch->leaf[idx] = 0; +} diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk index ef61611..0e9a5c3 100644 --- a/arch/riscv/source.mk +++ b/arch/riscv/source.mk @@ -1,8 +1,6 @@ -COMMON_LOCAL != echo arch/riscv/common/*.[cS] KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS] -KERNEL_SOURCES += $(KERNEL_LOCAL) $(COMMON_LOCAL) -INIT_LOCAL != echo arch/riscv/init/*.[cS] -INIT_SOURCES += $(INIT_LOCAL) $(COMMON_LOCAL) +KERNEL_SOURCES += $(KERNEL_LOCAL) +INIT_SOURCES += arch/riscv/init/init.c CLEANUP_CMD := ./arch/riscv/conf/rmimage.sh diff --git a/include/apos/init.h b/include/apos/init.h deleted file mode 100644 index 6e20439..0000000 --- a/include/apos/init.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef APOS_INIT_H -#define APOS_INIT_H - -#include -#include - -struct init_data_t { - pm_t init_base; - pm_t init_top; - - pm_t initrd_base; - pm_t initrd_top; - - pm_t pmap_base; - pm_t pmap_top; - - pm_t fdt_base; - pm_t fdt_top; - - pm_t stack_base; - pm_t stack_top; - - struct vm_branch_t *kernel_vm_base; - - size_t max_order; - size_t bits[10]; - size_t page_shift; -}; - -#endif /* APOS_INIT_H */ diff --git a/include/apos/vmem.h b/include/apos/vmem.h index ef309e2..daa9d10 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -39,11 +39,6 @@ struct sp_mem { */ /* defined by arch */ - -void map_vmem(struct vm_branch_t *branch, - pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order); -void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr, enum mm_order_t order); - int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t nums); vm_t alloc_uvmem(struct tcb *r, size_t s, uint8_t flags); diff --git a/kernel/temp.c b/kernel/temp.c deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/gen-deps b/scripts/gen-deps index 7a468d3..ee64022 100755 --- a/scripts/gen-deps +++ b/scripts/gen-deps @@ -11,43 +11,25 @@ gencommon () { echo "${obj}: ${s}" >> deps.mk } + genlink () { gencommon ".ld" - if [ "${init}" = "0" ] ; then - echo " \$(GENLINK) $< | \$(STRIPLINK) > \$@"\ - >> deps.mk; - else - echo " \$(GENLINK) $< | \$(STRIPLINK) | \$(KERN_INFO) > \$@"\ + echo " \$(GENLINK) $< | \$(STRIPLINK) | \$(KERN_INFO) > \$@"\ >> deps.mk; - fi - } genrule () { gencommon "${1}" - echo " \$(COMPILE) ${defs} -c \$< -o \$@" >> deps.mk + echo " \$(COMPILE) -c \$< -o \$@" >> deps.mk } case "${1}" in - --kern) - suffix=.k.o - defs=-DKERNEL - func=genrule - ;; - --init) - suffix=.i.o - defs=-DINIT + --compile) + suffix=.o func=genrule ;; - --init-link) - suffix=.ld - init=1 - func=genlink - ;; - - --kern-link) + --link) suffix=.ld - init=0 func=genlink esac -- cgit v1.3