From 0be35869d226aa2edc47dea07e0aca1c73f677d5 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Mon, 15 Jul 2024 12:56:25 +0200
Subject: kernel: split the page allocator and kmalloc

---
 src/kernel/malloc.c    | 101 ---------------------------------------------
 src/kernel/pagealloc.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 101 deletions(-)
 create mode 100644 src/kernel/pagealloc.c

(limited to 'src/kernel')

diff --git a/src/kernel/malloc.c b/src/kernel/malloc.c
index 0d5cba3..7385cf3 100644
--- a/src/kernel/malloc.c
+++ b/src/kernel/malloc.c
@@ -20,78 +20,12 @@ struct Allocation {
 
 static Allocation *malloc_last = NULL;
 
-extern uint8_t pbitmap[]; /* linker.ld */
-static size_t pbitmap_len; /* in bytes */
-static void *firstfreepage; /* not necessarily actually free */
-static void *memtop;
-
-static size_t
-toindex(void *p)
-{
-	assert((void*)pbitmap <= p);
-	return ((uintptr_t)p - (uintptr_t)pbitmap) / PAGE_SIZE;
-}
-
-static bool
-pbitmap_get(void *p)
-{
-	size_t i = toindex(p);
-	size_t b = i / 8;
-	uint8_t m = 1 << (i&7);
-	assert(b < pbitmap_len); // TODO the bitmap should be a tad longer
-	return (pbitmap[b]&m) != 0;
-}
-
-static bool
-pbitmap_set(void *p, bool v)
-{
-	size_t i = toindex(p);
-	size_t b = i / 8;
-	uint8_t m = 1 << (i&7);
-	assert(b < pbitmap_len);
-	bool prev = (pbitmap[b]&m) != 0;
-	if (v) {
-		pbitmap[b] |= m;
-	} else {
-		pbitmap[b] &= ~m;
-	}
-	return prev;
-}
-
 static size_t
 page_amt(size_t bytes)
 {
 	return (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
 }
 
-void
-mem_init(void *p)
-{
-	memtop = p;
-	kprintf("memory   %8x -> %8x\n", &_bss_end, memtop);
-	pbitmap_len = toindex(memtop) / 8;
-	memset(pbitmap, 0, pbitmap_len);
-	mem_reserve(pbitmap, pbitmap_len);
-	firstfreepage = pbitmap;
-}
-
-void
-mem_reserve(void *addr, size_t len)
-{
-	kprintf("reserved %8x -> %8x\n", addr, addr + len);
-
-	void *top = min(addr + len, memtop);
-	addr = (void*)((uintptr_t)addr & ~PAGE_MASK); /* round down to page */
-	for (void *p = max(addr, (void*)pbitmap); p < top; p += PAGE_SIZE) {
-		/* this doesn't allow overlapping reserved regions, but, more
-		 * importantly, it prevents reserving an already allocated page */
-		if (pbitmap_get(p)) {
-			panic_invalid_state();
-		}
-		pbitmap_set(p, true);
-	}
-}
-
 void
 mem_debugprint(void)
 {
@@ -119,41 +53,6 @@ mem_debugprint(void)
 	);
 }
 
-void *
-page_alloc(size_t pages)
-{
-	assert(pages == 1);
-	for (void *p = firstfreepage; p < memtop; p += PAGE_SIZE) {
-		if (!pbitmap_get(p)) {
-			pbitmap_set(p, true);
-			firstfreepage = p + PAGE_SIZE;
-			return p;
-		}
-	}
-	kprintf("we ran out of memory :(\ngoodbye.\n");
-	panic_unimplemented();
-}
-
-void *
-page_zalloc(size_t pages)
-{
-	void *p = page_alloc(pages);
-	memset(p, 0, pages * PAGE_SIZE);
-	return p;
-}
-
-void
-page_free(void *addr, size_t pages)
-{
-	assert((void*)pbitmap <= addr);
-	for (size_t i = 0; i < pages; i++) {
-		if (pbitmap_set(addr + i*PAGE_SIZE, false) == false) {
-			panic_invalid_state();
-		}
-	}
-	firstfreepage = min(firstfreepage, addr);
-}
-
 static void
 kmalloc_sanity(const void *addr)
 {
diff --git a/src/kernel/pagealloc.c b/src/kernel/pagealloc.c
new file mode 100644
index 0000000..f01c295
--- /dev/null
+++ b/src/kernel/pagealloc.c
@@ -0,0 +1,108 @@
+#include <kernel/arch/generic.h>
+#include <kernel/malloc.h>
+#include <kernel/panic.h>
+#include <kernel/util.h>
+#include <shared/mem.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+extern uint8_t pbitmap[]; /* linker.ld */
+static size_t pbitmap_len; /* in bytes */
+static void *memtop;
+static void *firstfreepage; /* not necessarily actually free */
+
+static size_t
+toindex(void *p)
+{
+	assert((void*)pbitmap <= p);
+	return ((uintptr_t)p - (uintptr_t)pbitmap) / PAGE_SIZE;
+}
+
+static bool
+pbitmap_get(void *p)
+{
+	size_t i = toindex(p);
+	size_t b = i / 8;
+	uint8_t m = 1 << (i&7);
+	assert(b < pbitmap_len); // TODO the bitmap should be a tad longer
+	return (pbitmap[b]&m) != 0;
+}
+
+static bool
+pbitmap_set(void *p, bool v)
+{
+	size_t i = toindex(p);
+	size_t b = i / 8;
+	uint8_t m = 1 << (i&7);
+	assert(b < pbitmap_len);
+	bool prev = (pbitmap[b]&m) != 0;
+	if (v) {
+		pbitmap[b] |= m;
+	} else {
+		pbitmap[b] &= ~m;
+	}
+	return prev;
+}
+
+void
+mem_init(void *p)
+{
+	memtop = p;
+	kprintf("memory   %8x -> %8x\n", &_bss_end, memtop);
+	pbitmap_len = toindex(memtop) / 8;
+	memset(pbitmap, 0, pbitmap_len);
+	mem_reserve(pbitmap, pbitmap_len);
+	firstfreepage = pbitmap;
+}
+
+void
+mem_reserve(void *addr, size_t len)
+{
+	kprintf("reserved %8x -> %8x\n", addr, addr + len);
+
+	void *top = min(addr + len, memtop);
+	addr = (void*)((uintptr_t)addr & ~PAGE_MASK); /* round down to page */
+	for (void *p = max(addr, (void*)pbitmap); p < top; p += PAGE_SIZE) {
+		/* this doesn't allow overlapping reserved regions, but, more
+		 * importantly, it prevents reserving an already allocated page */
+		if (pbitmap_get(p)) {
+			panic_invalid_state();
+		}
+		pbitmap_set(p, true);
+	}
+}
+
+void *
+page_zalloc(size_t pages)
+{
+	void *p = page_alloc(pages);
+	memset(p, 0, pages * PAGE_SIZE);
+	return p;
+}
+
+void *
+page_alloc(size_t pages)
+{
+	assert(pages == 1);
+	for (void *p = firstfreepage; p < memtop; p += PAGE_SIZE) {
+		if (!pbitmap_get(p)) {
+			pbitmap_set(p, true);
+			firstfreepage = p + PAGE_SIZE;
+			return p;
+		}
+	}
+	kprintf("we ran out of memory :(\ngoodbye.\n");
+	panic_unimplemented();
+}
+
+void
+page_free(void *addr, size_t pages)
+{
+	assert((void*)pbitmap <= addr);
+	for (size_t i = 0; i < pages; i++) {
+		if (pbitmap_set(addr + i*PAGE_SIZE, false) == false) {
+			panic_invalid_state();
+		}
+	}
+	firstfreepage = min(firstfreepage, addr);
+}
-- 
cgit v1.2.3