PageEntry SectionMethodList::GetPageListEntry(UInt32 idx) { ASSERT(idx < m_uPageListCountDEBUG); if (m_uFlags & SmallPageListEntriesFlag) return PageEntry(dac_cast<ArrayDPTR(UInt16)>(m_pbPageList)[idx]); return PageEntry((dac_cast<PTR_UInt32>(m_pbPageList))[idx]); }
PageTable MMU::getOrCreateTable(uint16_t directoryIndex) { if (directoryIndex > 1023) { kernel->panic("MMU::getOrCreateTable: invalid directoryIndex"); } PageEntry pde = _pageDirectory.entryAtIndex(directoryIndex); PageTable table{PageTableForDirectoryIndex(directoryIndex)}; if (!pde.getFlag(kPresentBit)) { // no page table here, create one pde = PageEntry(_pageFrameAllocator.alloc()); pde.setFlags(kPresentBit | kReadWriteBit); _pageDirectory.setEntry(directoryIndex, pde); table.clear(); _flush(); } return table; }
int MMU::pfree(void *startOfMemoryRange, size_t numberOfPages) { uint32_t virtualAddress = (uint32_t) startOfMemoryRange; if (!numberOfPages) return -1; while (numberOfPages--) { uint32_t pdeIndex = virtualAddress >> 22; uint32_t pteIndex = virtualAddress >> 12 & 0x03FF; PageTable table = PageTableForDirectoryIndex(pdeIndex); PageEntry pte = table.entryAtIndex(pteIndex); _pageFrameAllocator.free(pte.address()); table.setEntry(pteIndex, PageEntry(0)); virtualAddress += 0x1000; } _flush(); return 0; }
void MMU::allocatePages(void *address, size_t numberOfPages) { uintptr_t virtualAddress = reinterpret_cast<uintptr_t>(address); uint32_t currpde = virtualAddress >> 22; uint32_t currpte = virtualAddress >> 12 & 0x03FF; size_t pagesLeft = numberOfPages; while (pagesLeft > 0) { // map the pages PageTable table = PageTableForDirectoryIndex(currpde); PageEntry entry = PageEntry(_pageFrameAllocator.alloc()); entry.setFlags(kPresentBit | kReadWriteBit); table.setEntry(currpte, entry); ++currpte; --pagesLeft; // move to next PDE if needed if (currpte > 1023) { ++currpde; currpte = 0; } } _flush(); }