From efc0093ed29836382ab7adf144bd18ca20c10304 Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Thu, 12 Feb 2026 00:34:23 -0300 Subject: [PATCH] =?utf8?q?feat:=20pmm=5Falloc=5Fblocks/pmm=5Ffree=5Fblocks?= =?utf8?q?=20=E2=80=94=20contiguous=20physical=20page=20allocation=20for?= =?utf8?q?=20DMA=20buffers?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/pmm.h | 6 ++++++ src/mm/pmm.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/pmm.h b/include/pmm.h index 855e833..352dafa 100644 --- a/include/pmm.h +++ b/include/pmm.h @@ -25,6 +25,12 @@ void pmm_arch_init(void* boot_info); // Allocate a single physical page void* pmm_alloc_page(void); +// Allocate N contiguous physical pages (for DMA buffers etc.) +void* pmm_alloc_blocks(uint32_t count); + +// Free N contiguous physical pages +void pmm_free_blocks(void* ptr, uint32_t count); + // Free a physical page (decrements refcount, frees at 0) void pmm_free_page(void* ptr); diff --git a/src/mm/pmm.c b/src/mm/pmm.c index 9150354..71456bd 100644 --- a/src/mm/pmm.c +++ b/src/mm/pmm.c @@ -157,6 +157,43 @@ void* pmm_alloc_page(void) { return NULL; // OOM } +void* pmm_alloc_blocks(uint32_t count) { + if (count == 0) return NULL; + if (count == 1) return pmm_alloc_page(); + + uintptr_t flags = spin_lock_irqsave(&pmm_lock); + + for (uint64_t start = 1; start + count <= max_frames; start++) { + int found = 1; + for (uint32_t j = 0; j < count; j++) { + if (bitmap_test(start + j)) { + start += j; /* skip ahead past the used frame */ + found = 0; + break; + } + } + if (found) { + for (uint32_t j = 0; j < count; j++) { + bitmap_set(start + j); + frame_refcount[start + j] = 1; + used_memory += PAGE_SIZE; + } + spin_unlock_irqrestore(&pmm_lock, flags); + return (void*)(uintptr_t)(start * PAGE_SIZE); + } + } + + spin_unlock_irqrestore(&pmm_lock, flags); + return NULL; +} + +void pmm_free_blocks(void* ptr, uint32_t count) { + uintptr_t addr = (uintptr_t)ptr; + for (uint32_t i = 0; i < count; i++) { + pmm_free_page((void*)(addr + i * PAGE_SIZE)); + } +} + void pmm_free_page(void* ptr) { uintptr_t addr = (uintptr_t)ptr; uint64_t frame = addr / PAGE_SIZE; -- 2.43.0