From 2d173beb3392aff35c8a33f4ac001bf63bb9adc6 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sat, 25 Sep 2021 14:56:43 +0300 Subject: Used memory regions now marked + I don't fully trust my memory management system yet, so should probably check the memory regions it gives. --- arch/riscv/config.h | 2 +- arch/riscv/include/pages.h | 5 ++++ arch/riscv/init/init.c | 75 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 77 insertions(+), 5 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/config.h b/arch/riscv/config.h index 8bfe360..9db8d8f 100644 --- a/arch/riscv/config.h +++ b/arch/riscv/config.h @@ -1,6 +1,6 @@ #include #define PM_KERN 0x83800000 -#define PM_STACK_BASE 0x83900000 +#define PM_STACK_BASE (PM_KERN + SZ_2M) #define PM_STACK_TOP (PM_STACK_BASE + SZ_2M - 2) #define VM_KERN ((-1) - SZ_1G) diff --git a/arch/riscv/include/pages.h b/arch/riscv/include/pages.h index 1533f7b..82ce6c7 100644 --- a/arch/riscv/include/pages.h +++ b/arch/riscv/include/pages.h @@ -12,4 +12,9 @@ typedef uint64_t pm_t; #define MM_GPAGE MM_O2 #define MM_TPAGE MM_O3 +#define MM_KPAGE_SIZE SZ_4K +#define MM_MPAGE_SIZE SZ_2M +#define MM_GPAGE_SIZE SZ_1G +#define MM_TPAGE_SIZE SZ_512G + #endif /* APOS_RISCV_PAGES_H */ diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index 86c2563..ca04bcd 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -127,12 +127,61 @@ static pm_t get_initrdtop(void *fdt) 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 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; + while(area_left >= MM_TPAGE_SIZE){ + mark_used(MM_TPAGE, base); + area_left -= MM_TPAGE_SIZE; + base += MM_TPAGE_SIZE; + } + + while(area_left >= MM_GPAGE_SIZE){ + mark_used(MM_GPAGE, base); + area_left -= MM_GPAGE_SIZE; + base += MM_GPAGE_SIZE; + } + + while(area_left >= MM_MPAGE_SIZE){ + mark_used(MM_MPAGE, base); + area_left -= MM_MPAGE_SIZE; + base += MM_MPAGE_SIZE; + } + + + 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 setup_pmem(void *fdt) { struct pmem_layout pmem = get_memlayout(fdt); @@ -148,14 +197,32 @@ static void setup_pmem(void *fdt) /* 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 */ - populate_pmap(pmem.base, pmem.top - pmem.base, align_up(top + 1, 2)); + 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); - /* TODO: mark used pages */ + /* mark kernel, at the moment it is always mapped to a 2M partition */ + mark_used(PM_KERN, MM_MPAGE); - /* mark init stack */ - mark_used(PM_STACK_BASE, 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); } void init(void *fdt) -- cgit v1.3