#define MODULE "vmm" #include "memory/AddressSpace.h" #include "log/Log.h" #include "memory/PMM.h" #include "memory/VMM.h" AddressSpace AddressSpace::create() { AddressSpace result; result.m_pml4 = (PageTable*)PMM::request_page(); VMM::install_kernel_page_directory_into_address_space(result); return result; } void AddressSpace::destroy() { uint64_t pages_freed = 0; for (int i = 0; i < 512; i++) { PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; if (!pdp_pde.present) continue; if (pdp_pde.larger_pages) { pages_freed++; PMM::free_page((void*)pdp_pde.get_address()); continue; } PageTable* pdp = (PageTable*)pdp_pde.get_address(); for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one { PageDirectoryEntry& pd_pde = pdp->entries[j]; if (!pd_pde.present) continue; if (pd_pde.larger_pages) { pages_freed++; PMM::free_page((void*)pd_pde.get_address()); continue; } PageTable* pd = (PageTable*)pd_pde.get_address(); for (int k = 0; k < 512; k++) { PageDirectoryEntry& pt_pde = pd->entries[k]; if (!pt_pde.present) continue; if (pt_pde.larger_pages) { pages_freed++; PMM::free_page((void*)pt_pde.get_address()); continue; } PageTable* pt = (PageTable*)pt_pde.get_address(); for (int l = 0; l < 512; l++) { PageDirectoryEntry& pde = pt->entries[l]; if (pde.present) continue; pages_freed++; PMM::free_page((void*)pde.get_address()); } pages_freed++; PMM::free_page(pt); } pages_freed++; PMM::free_page(pd); } pages_freed++; PMM::free_page(pdp); } pages_freed++; PMM::free_page(m_pml4); kdbgln("Reclaimed %ld pages from address space!", pages_freed); }