diff --git a/kernel/arch/i386/APIC.cpp b/kernel/arch/i386/APIC.cpp index 57860f4446..c426ee9d28 100644 --- a/kernel/arch/i386/APIC.cpp +++ b/kernel/arch/i386/APIC.cpp @@ -210,8 +210,8 @@ namespace APIC static void ParseMADT(RSDPDescriptor* rsdp) { - RSDT* root = (RSDT*)(rsdp->revision == 2 ? ((RSDPDescriptor20*)rsdp)->xsdt_address : rsdp->rsdt_address); - MMU::Get().AllocatePage((uint32_t)root); + RSDT* const root = (RSDT*)(rsdp->revision == 2 ? ((RSDPDescriptor20*)rsdp)->xsdt_address : rsdp->rsdt_address); + MMU::Get().AllocatePage((uintptr_t)root); uint32_t sdt_entry_count = (root->header.length - sizeof(root->header)) / (rsdp->revision == 2 ? 8 : 4); for (uint32_t i = 0; i < sdt_entry_count; i++) @@ -305,6 +305,7 @@ namespace APIC } } } + MMU::Get().UnAllocatePage((uintptr_t)root); } static uint32_t ReadLocalAPIC(uint32_t offset) diff --git a/kernel/arch/i386/MMU.cpp b/kernel/arch/i386/MMU.cpp index e5d15b9ba2..e49f2a2715 100644 --- a/kernel/arch/i386/MMU.cpp +++ b/kernel/arch/i386/MMU.cpp @@ -96,3 +96,30 @@ void MMU::AllocateRange(uintptr_t address, ptrdiff_t size) for (uintptr_t page = s_page; page <= e_page; page += PAGE_SIZE) AllocatePage(page); } + +void MMU::UnAllocatePage(uintptr_t address) +{ + uint32_t pdpte = (address & 0xC0000000) >> 30; + uint32_t pde = (address & 0x3FE00000) >> 21; + uint32_t pte = (address & 0x001FF000) >> 12; + + uint64_t* page_directory = (uint64_t*)(m_page_descriptor_pointer_table[pdpte] & PAGE_MASK); + ASSERT(page_directory[pde] & PRESENT); + + uint64_t* page_table = (uint64_t*)(page_directory[pde] & PAGE_MASK); + ASSERT(page_table[pte] & PRESENT); + + page_table[pte] = 0; + + // TODO: Unallocate the page table if this was the only allocated page + + asm volatile("invlpg (%0)" :: "r"(address & PAGE_MASK) : "memory"); +} + +void MMU::UnAllocateRange(uintptr_t address, ptrdiff_t size) +{ + uintptr_t s_page = address & PAGE_MASK; + uintptr_t e_page = (address + size - 1) & PAGE_MASK; + for (uintptr_t page = s_page; page <= e_page; page += PAGE_SIZE) + UnAllocatePage(page); +} diff --git a/kernel/include/kernel/MMU.h b/kernel/include/kernel/MMU.h index d47fee5168..9dccc8c5e4 100644 --- a/kernel/include/kernel/MMU.h +++ b/kernel/include/kernel/MMU.h @@ -11,7 +11,10 @@ public: void AllocatePage(uintptr_t); void AllocateRange(uintptr_t, ptrdiff_t); - + + void UnAllocatePage(uintptr_t); + void UnAllocateRange(uintptr_t, ptrdiff_t); + private: MMU();