void *MMU::palloc(size_t numberOfPages) { size_t contiguousFoundPages = 0; size_t retpde = 0, retpte = 0; void *retval = nullptr; for (size_t pde = 0; pde < 1024 && contiguousFoundPages != numberOfPages; ++pde) { PageTable table = getOrCreateTable(pde); // look through page table for (size_t pte = 0; pte < 1024; ++pte) { PageEntry entry = table.entryAtIndex(pte); if (!entry.getFlag(kPresentBit)) { // found a page that isn't present (is available) if (contiguousFoundPages == 0) { // this is the first available page, set our return pointer to it retpde = pde; retpte = pte; } ++contiguousFoundPages; if (contiguousFoundPages == numberOfPages) { // done retval = (void *) ((retpde << 22) | (retpte << 12)); break; } } else if (contiguousFoundPages) { // current page is used, reset our contiguous page count retval = nullptr; contiguousFoundPages = 0; } } } if (retval) { // if we succeeded in finding space allocatePages(retval, numberOfPages); } return retval; }
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; }