aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-09-25 14:56:43 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2021-09-25 14:56:43 +0300
commit2d173beb3392aff35c8a33f4ac001bf63bb9adc6 (patch)
tree3b9dc8dc03276f5ead11f2e3613536c7f11c6b18 /arch/riscv
parent13fe461374c0716404e2ee7726781b9cd12dbaa7 (diff)
downloadkmi-2d173beb3392aff35c8a33f4ac001bf63bb9adc6.tar.gz
kmi-2d173beb3392aff35c8a33f4ac001bf63bb9adc6.zip
Used memory regions now marked
+ I don't fully trust my memory management system yet, so should probably check the memory regions it gives.
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/config.h2
-rw-r--r--arch/riscv/include/pages.h5
-rw-r--r--arch/riscv/init/init.c73
3 files changed, 76 insertions, 4 deletions
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 <apos/sizes.h>
#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: mark used pages */
+ /* 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 */
+ /* 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);
}
void init(void *fdt)