diff --git a/kernel/src/arch/x86_64/MMU.cpp b/kernel/src/arch/x86_64/MMU.cpp index de239a22..7d037bef 100644 --- a/kernel/src/arch/x86_64/MMU.cpp +++ b/kernel/src/arch/x86_64/MMU.cpp @@ -278,9 +278,9 @@ namespace MMU const u64 physical_memory_size = highest_entry.address() + highest_entry.size(); - // FIXME: Do this using 2MiB huge pages. - MemoryManager::map_frames_at(physical_memory_base, 0, physical_memory_size / ARCH_PAGE_SIZE, - MMU::ReadWrite | MMU::NoExecute); + check(physical_memory_size % ARCH_HUGE_PAGE_SIZE == 0); + MemoryManager::map_huge_frames_at(physical_memory_base, 0, physical_memory_size / ARCH_HUGE_PAGE_SIZE, + MMU::ReadWrite | MMU::NoExecute); g_physical_mapping_base = physical_memory_base; diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 35e6b80a..bfa4e497 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -213,6 +213,29 @@ namespace MemoryManager return {}; } + Result map_huge_frames_at(u64 virt, u64 phys, usize count, int flags) + { + CHECK_PAGE_ALIGNED(virt); + CHECK_PAGE_ALIGNED(phys); + + usize pages_mapped = 0; + + // Let's clean up after ourselves if we fail. + auto guard = make_scope_guard([=, &pages_mapped] { unmap_weak_huge(virt, pages_mapped); }); + + while (pages_mapped < count) + { + TRY(MMU::map(virt, phys, flags, MMU::UseHugePages::Yes)); + virt += ARCH_HUGE_PAGE_SIZE; + phys += ARCH_HUGE_PAGE_SIZE; + pages_mapped++; + } + + guard.deactivate(); + + return {}; + } + Result alloc_at(u64 virt, usize count, int flags) { CHECK_PAGE_ALIGNED(virt); @@ -322,6 +345,19 @@ namespace MemoryManager return {}; } + Result unmap_weak_huge(u64 virt, usize count) + { + CHECK_PAGE_ALIGNED(virt); + + while (count--) + { + TRY(MMU::unmap(virt)); + virt += ARCH_HUGE_PAGE_SIZE; + } + + return {}; + } + Result unmap_weak_and_free_vm(u64 virt, usize count) { CHECK_PAGE_ALIGNED(virt); diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index 8f2b9bbc..3ceecffb 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -53,6 +53,7 @@ namespace MemoryManager } Result map_frames_at(u64 virt, u64 phys, usize count, int flags); + Result map_huge_frames_at(u64 virt, u64 phys, usize count, int flags); Result alloc_at(u64 virt, usize count, int flags); Result alloc_for_kernel(usize count, int flags); @@ -64,6 +65,8 @@ namespace MemoryManager Result unmap_weak(u64 virt, usize count); Result unmap_weak_and_free_vm(u64 virt, usize count); + Result unmap_weak_huge(u64 virt, usize count); + usize free(); usize used(); usize reserved();