diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 335c3d54..b3fc2f8c 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -39,6 +39,8 @@ static void page_bitmap_set(u64 index, bool value) if (value) { page_virtual_bitmap_addr[byte_index] |= mask; } } +#define CHECK_PAGE_ALIGNED(address) check(is_aligned(address, ARCH_PAGE_SIZE)) + namespace MemoryManager { Result protect_kernel_sections() @@ -158,7 +160,7 @@ namespace MemoryManager Result remap(u64 address, usize count, int flags) { - check(is_aligned(address, ARCH_PAGE_SIZE)); + CHECK_PAGE_ALIGNED(address); while (count--) { @@ -169,6 +171,62 @@ namespace MemoryManager return {}; } + Result map(u64 virt, u64 phys, usize count, int flags) + { + CHECK_PAGE_ALIGNED(virt); + CHECK_PAGE_ALIGNED(phys); + + while (count--) + { + TRY(MMU::map(virt, phys, flags)); + virt += ARCH_PAGE_SIZE; + phys += ARCH_PAGE_SIZE; + } + + return {}; + } + + Result alloc_at(u64 virt, usize count, int flags) + { + CHECK_PAGE_ALIGNED(virt); + + while (count--) + { + u64 frame = TRY(alloc_frame()); + TRY(MMU::map(virt, frame, flags)); + virt += ARCH_PAGE_SIZE; + } + + return virt; + } + + Result unmap_owned(u64 virt, usize count) + { + CHECK_PAGE_ALIGNED(virt); + + while (count--) + { + u64 frame = TRY(MMU::unmap(virt)); + TRY(free_frame(frame)); + virt += ARCH_PAGE_SIZE; + } + + return {}; + } + + Result unmap_weak(u64 virt, usize count) + { + CHECK_PAGE_ALIGNED(virt); + + while (count--) + { + TRY(MMU::unmap(virt)); + virt += ARCH_PAGE_SIZE; + } + + return {}; + } + Result remap_unaligned(u64 address, usize count, int flags) { if (!is_aligned(address, ARCH_PAGE_SIZE)) count++; diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index 21ab26f8..734aa87c 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -20,6 +20,13 @@ namespace MemoryManager bool validate_readable_page(u64 address); bool validate_writable_page(u64 address); + Result map(u64 virt, u64 phys, usize count, int flags); + + Result alloc_at(u64 virt, usize count, int flags); + + Result unmap_owned(u64 virt, usize count); + Result unmap_weak(u64 virt, usize count); + u64 free(); u64 used(); u64 reserved();