From 2ff21cc5011f0359715d4ac557ea7a1e64d1b5d5 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 16 Nov 2025 13:45:37 -0500 Subject: kern: vm: Add frame allocation and deallocation Signed-off-by: Ian Moffett --- sys/vm/vm_phys.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'sys/vm/vm_phys.c') diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index ecbc857..717b1f4 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,9 @@ typedef struct limine_memmap_entry mementry_t; /* Bitmap */ +static volatile size_t bitmap_lock = 0; static uint8_t *bitmap = NULL; +static size_t last_index = 0; /* Memory statistics */ static size_t total_mem = 0; @@ -210,6 +213,69 @@ vm_probe(void) vm_alloc_bitmap(); } +/* + * Lockless frame allocation routine + */ +static uintptr_t +__vm_phys_alloc(size_t count) +{ + size_t frames_found = 0; + size_t max_index; + ssize_t index_start = -1; + uintptr_t start, end; + + max_index = highest_usable / PAGESIZE; + for (size_t i = last_index; i < max_index; ++i) { + if (!testbit(bitmap, i)) { + if (index_start < 0) + index_start = i; + if ((++frames_found) >= count) + break; + + continue; + } + + index_start = -1; + } + + if (index_start < 0) { + return 0; + } + + start = index_start * PAGESIZE; + end = start + (count * PAGESIZE); + bitmap_set_range(start, end, true); + return start; +} + +void +vm_phys_free(uintptr_t base, size_t count) +{ + uintptr_t end; + + base = ALIGN_DOWN(base, PAGESIZE); + end = base + (count * PAGESIZE); + + mu_spinlock_acq(&bitmap_lock, 0); + bitmap_set_range(base, end, false); + mu_spinlock_rel(&bitmap_lock, 0); +} + +uintptr_t +vm_phys_alloc(size_t count) +{ + uintptr_t base; + + mu_spinlock_acq(&bitmap_lock, 0); + base = __vm_phys_alloc(count); + if (base == 0) { + last_index = 0; + base = __vm_phys_alloc(count); + } + mu_spinlock_rel(&bitmap_lock, 0); + return base; +} + void vm_phys_init(void) { -- cgit v1.2.3