#include "../mmap.hpp" #include "pagetableentry.hpp" int kernel::mmap(PageAllocator& allocator, void* start, size_t length, int flags) { if((size_t) start % 4096 != 0) return -1; PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; size_t tableIndex = (size_t) start / 4096; for(int i = (int) length; i > 0; i -= 4096) { size_t directoryIndex = tableIndex / 1024; if(!pageDirectory[directoryIndex].getPresent()) { physaddr_t newPT = allocator.allocate(4096); if(newPT == 0) return -1; pageDirectory[directoryIndex] = newPT; pageDirectory[directoryIndex].setPresent(true); pageDirectory[directoryIndex].setUsermode(false); pageDirectory[directoryIndex].setRw(true); } if(!pageTables[tableIndex].getPresent()) { physaddr_t page = allocator.allocate(4096); pageTables[tableIndex] = page; pageTables[tableIndex].setPresent(true); pageTables[tableIndex].setUsermode(false); if(flags & MMAP_RW) pageTables[tableIndex].setRw(true); } tableIndex++; } return 0; } int kernel::munmap(PageAllocator& allocator, void* start, size_t length) { if((size_t) start % 4096 != 0) return -1; PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; size_t tableIndex = (size_t) start / 4096; for(int i = (int) length; i > 0; i -= 4096) { size_t directoryIndex = tableIndex / 1024; if(pageDirectory[directoryIndex].getPresent()) { pageTables[tableIndex] = 0; pageTables[tableIndex].setPresent(false); pageTables[tableIndex].setUsermode(false); pageTables[tableIndex].setRw(false); } tableIndex++; } return 0; } bool kernel::isMapped(void* addr) { PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; size_t tableIndex = (size_t) addr / 4096; size_t directoryIndex = tableIndex / 1024; if(pageDirectory[directoryIndex].getPresent()) { PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; return pageTables[tableIndex].getPresent(); } return false; } physaddr_t kernel::getPhysicalAddress(void* addr) { PageTableEntry* pageTables = (PageTableEntry*) 0xFFC00000; size_t tableIndex = (size_t) addr / 4096; return pageTables[tableIndex].getPhysicalAddress() + ((size_t) addr & 0xFFF); } int kernel::createAddressSpace(void* table) { if(((size_t) table & 0xFFF) != 0) return -1; PageTableEntry* pageDirectory = (PageTableEntry*) 0xFFFFF000; PageTableEntry* newDirectory = (PageTableEntry*) table; newDirectory[1022] = pageDirectory[1022]; newDirectory[1023] = pageDirectory[1023]; return 0; } int kernel::loadAddressSpace(physaddr_t table) { if((table & 0xFFF) != 0) return -1; asm("mov %0, %%cr3" : : "r" (table)); return 0; }