From: Tulio A M Mendes Date: Thu, 12 Feb 2026 03:34:23 +0000 (-0300) Subject: feat: pmm_alloc_blocks/pmm_free_blocks — contiguous physical page allocation for... X-Git-Url: https://projects.tadryanom.me/sitemap.xml?a=commitdiff_plain;h=efc0093ed29836382ab7adf144bd18ca20c10304;p=AdrOS.git feat: pmm_alloc_blocks/pmm_free_blocks — contiguous physical page allocation for DMA buffers --- 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;