diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 9e9d9da..2d490ba 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -25,15 +25,15 @@ NewLock(UserInputLock); EHPrint("\e888888#%s\eAABBCC%03d\e4500F5: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s D:%s PS:%s G:%s Address:\e888888%#lx\n", \ depth, \ itr, \ - x.Value.Present ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.ReadWrite ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.UserSupervisor ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.WriteThrough ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.CacheDisable ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.Accessed ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.Dirty ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.PageSize ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ - x.Value.Global ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.Present ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.ReadWrite ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.UserSupervisor ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.WriteThrough ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.CacheDisable ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.Accessed ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.Dirty ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.PageSize ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ + x.Global ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \ x.GetAddress() << 12); \ Display->SetBuffer(SBIdx); @@ -310,55 +310,55 @@ namespace CrashHandler uint64_t Address = NULL; Address = strtol(arg, NULL, 16); debug("Converted %s to %#lx", arg, Address); - Memory::PageTable *BasePageTable = (Memory::PageTable *)Address; + Memory::PageTable4 *BasePageTable = (Memory::PageTable4 *)Address; if (Memory::Virtual().Check(BasePageTable)) for (int Index = 0; Index < 512; Index++) { - if (BasePageTable->Entries[Index].Value.raw == 0) + if (BasePageTable->Entries[Index].raw == 0) continue; - TRACE_PAGE_TABLE(BasePageTable->Entries[Index], Index, ""); - for (int i = 0; i < 10000; i++) - inb(0x80); + // TRACE_PAGE_TABLE(BasePageTable->Entries[Index], Index, ""); + // for (int i = 0; i < 10000; i++) + // inb(0x80); - if (BasePageTable->Entries[Index].GetFlag(Memory::PTFlag::P)) - { - Memory::PageTable *PDP = (Memory::PageTable *)((uint64_t)BasePageTable->Entries[Index].GetAddress() << 12); - for (int PDPIndex = 0; PDPIndex < 512; PDPIndex++) - { - if (PDP->Entries[PDPIndex].Value.raw == 0) - continue; - TRACE_PAGE_TABLE(PDP->Entries[PDPIndex], PDPIndex, " "); - for (int i = 0; i < 10000; i++) - inb(0x80); + // if (BasePageTable->Entries[Index].GetFlag(Memory::PTFlag::P)) + // { + // Memory::PageTable4 *PDP = (Memory::PageTable4 *)((uint64_t)BasePageTable->Entries[Index].GetAddress() << 12); + // for (int PMLIndex = 0; PMLIndex < 512; PMLIndex++) + // { + // if (PDP->Entries[PMLIndex].raw == 0) + // continue; + // TRACE_PAGE_TABLE(PDP->Entries[PMLIndex], PMLIndex, " "); + // for (int i = 0; i < 10000; i++) + // inb(0x80); - if (PDP->Entries[PDPIndex].GetFlag(Memory::PTFlag::P)) - { - Memory::PageTable *PD = (Memory::PageTable *)((uint64_t)PDP->Entries[PDPIndex].GetAddress() << 12); - for (int PDIndex = 0; PDIndex < 512; PDIndex++) - { - if (PD->Entries[PDIndex].Value.raw == 0) - continue; - TRACE_PAGE_TABLE(PD->Entries[PDIndex], PDIndex, " "); - for (int i = 0; i < 10000; i++) - inb(0x80); + // if (PDP->Entries[PMLIndex].GetFlag(Memory::PTFlag::P)) + // { + // Memory::PageTable4 *PD = (Memory::PageTable4 *)((uint64_t)PDP->Entries[PMLIndex].GetAddress() << 12); + // for (int PDPTEIndex = 0; PDPTEIndex < 512; PDPTEIndex++) + // { + // if (PD->Entries[PDPTEIndex].raw == 0) + // continue; + // TRACE_PAGE_TABLE(PD->Entries[PDPTEIndex], PDPTEIndex, " "); + // for (int i = 0; i < 10000; i++) + // inb(0x80); - if (PD->Entries[PDIndex].GetFlag(Memory::PTFlag::P)) - { - Memory::PageTable *PT = (Memory::PageTable *)((uint64_t)PD->Entries[PDIndex].GetAddress() << 12); - for (int PIndex = 0; PIndex < 512; PIndex++) - { - if (PT->Entries[PIndex].Value.raw == 0) - continue; - TRACE_PAGE_TABLE(PT->Entries[PIndex], PIndex, " "); - for (int i = 0; i < 10000; i++) - inb(0x80); - } - } - } - } - } - } + // if (PD->Entries[PDPTEIndex].GetFlag(Memory::PTFlag::P)) + // { + // Memory::PageTable4 *PT = (Memory::PageTable4 *)((uint64_t)PD->Entries[PDPTEIndex].GetAddress() << 12); + // for (int PTEIndex = 0; PTEIndex < 512; PTEIndex++) + // { + // if (PT->Entries[PTEIndex].raw == 0) + // continue; + // TRACE_PAGE_TABLE(PT->Entries[PTEIndex], PTEIndex, " "); + // for (int i = 0; i < 10000; i++) + // inb(0x80); + // } + // } + // } + // } + // } + // } } } else if (strncmp(Input, "bitmap", 6) == 0) diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index 6a7e1b7..f1d62fa 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -9,27 +9,25 @@ using namespace Memory; Physical KernelAllocator; -PageTable *KernelPageTable = nullptr; -PageTable *UserspaceKernelOnlyPageTable = nullptr; +PageTable4 *KernelPageTable = nullptr; +PageTable4 *UserspaceKernelOnlyPageTable = nullptr; static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None; Xalloc::AllocatorV1 *XallocV1Allocator = nullptr; #ifdef DEBUG -__no_instrument_function void tracepagetable(PageTable *pt) +__no_instrument_function void tracepagetable(PageTable4 *pt) { for (int i = 0; i < 512; i++) { #if defined(__amd64__) - if (pt->Entries[i].Value.Present) - debug("Entry %03d: %x %x %x %x %x %x %x %x %x %x %x %p-%#llx", i, - pt->Entries[i].Value.Present, pt->Entries[i].Value.ReadWrite, - pt->Entries[i].Value.UserSupervisor, pt->Entries[i].Value.WriteThrough, - pt->Entries[i].Value.CacheDisable, pt->Entries[i].Value.Accessed, - pt->Entries[i].Value.Dirty, pt->Entries[i].Value.PageSize, - pt->Entries[i].Value.Global, pt->Entries[i].Value.PageAttributeTable, - pt->Entries[i].Value.ExecuteDisable, pt->Entries[i].GetAddress(), - pt->Entries[i].Value); + if (pt->Entries[i].Present) + debug("Entry %03d: %x %x %x %x %x %x %x %p-%#llx", i, + pt->Entries[i].Present, pt->Entries[i].ReadWrite, + pt->Entries[i].UserSupervisor, pt->Entries[i].WriteThrough, + pt->Entries[i].CacheDisable, pt->Entries[i].Accessed, + pt->Entries[i].ExecuteDisable, pt->Entries[i].Address << 12, + pt->Entries[i]); #elif defined(__i386__) #elif defined(__aarch64__) #endif @@ -37,7 +35,7 @@ __no_instrument_function void tracepagetable(PageTable *pt) } #endif -__no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapFromZero(PageTable4 *PT, BootInfo *Info) { Virtual va = Virtual(PT); uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET; @@ -50,7 +48,7 @@ __no_instrument_function void MapFromZero(PageTable *PT, BootInfo *Info) } } -__no_instrument_function void MapFramebuffer(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapFramebuffer(PageTable4 *PT, BootInfo *Info) { Virtual va = Virtual(PT); int itrfb = 0; @@ -67,7 +65,7 @@ __no_instrument_function void MapFramebuffer(PageTable *PT, BootInfo *Info) } } -__no_instrument_function void MapKernel(PageTable *PT, BootInfo *Info) +__no_instrument_function void MapKernel(PageTable4 *PT, BootInfo *Info) { /* KernelStart KernelTextEnd KernelRoDataEnd KernelEnd Kernel Start & Text Start ------ Text End ------ Kernel Rodata End ------ Kernel Data End & Kernel End @@ -173,10 +171,10 @@ __no_instrument_function void InitializeMemoryManagement(BootInfo *Info) AllocatorType = MemoryAllocatorType::Pages; trace("Initializing Virtual Memory Manager"); - KernelPageTable = (PageTable *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); + KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); memset(KernelPageTable, 0, PAGE_SIZE); - UserspaceKernelOnlyPageTable = (PageTable *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); + UserspaceKernelOnlyPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); memset(UserspaceKernelOnlyPageTable, 0, PAGE_SIZE); debug("Mapping from 0x0 to %#llx", Info->Memory.Size); diff --git a/Core/Memory/PageDirectoryEntry.cpp b/Core/Memory/PageDirectoryEntry.cpp deleted file mode 100644 index 1fdbddf..0000000 --- a/Core/Memory/PageDirectoryEntry.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include - -namespace Memory -{ - void PageDirectoryEntry::AddFlag(uint64_t Flag) { this->Value.raw |= Flag; } - void PageDirectoryEntry::RemoveFlags(uint64_t Flag) { this->Value.raw &= ~Flag; } - void PageDirectoryEntry::ClearFlags() { this->Value.raw = 0; } - void PageDirectoryEntry::SetFlag(uint64_t Flag, bool Enabled) - { - this->Value.raw &= ~Flag; - if (Enabled) - this->Value.raw |= Flag; - } - bool PageDirectoryEntry::GetFlag(uint64_t Flag) { return (this->Value.raw & Flag) > 0 ? true : false; } - uint64_t PageDirectoryEntry::GetFlag() { return this->Value.raw; } - void PageDirectoryEntry::SetAddress(uint64_t Address) - { -#if defined(__amd64__) - Address &= 0x000000FFFFFFFFFF; - this->Value.raw &= 0xFFF0000000000FFF; - this->Value.raw |= (Address << 12); -#elif defined(__i386__) - Address &= 0x000FFFFF; - this->Value.raw &= 0xFFC00003; - this->Value.raw |= (Address << 12); -#elif defined(__aarch64__) - Address &= 0x000000FFFFFFFFFF; - this->Value.raw &= 0xFFF0000000000FFF; - this->Value.raw |= (Address << 12); -#endif - } - uint64_t PageDirectoryEntry::GetAddress() - { -#if defined(__amd64__) - return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12; -#elif defined(__i386__) - return (this->Value.raw & 0x003FFFFF000) >> 12; -#elif defined(__aarch64__) - return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12; -#endif - } -} diff --git a/Core/Memory/PageMapIndexer.cpp b/Core/Memory/PageMapIndexer.cpp index d99f3d2..3b87ad7 100644 --- a/Core/Memory/PageMapIndexer.cpp +++ b/Core/Memory/PageMapIndexer.cpp @@ -7,21 +7,21 @@ namespace Memory #if defined(__amd64__) uint64_t Address = VirtualAddress; Address >>= 12; - this->PIndex = Address & 0x1FF; + this->PTEIndex = Address & 0x1FF; Address >>= 9; - this->PTIndex = Address & 0x1FF; + this->PDEIndex = Address & 0x1FF; Address >>= 9; - this->PDIndex = Address & 0x1FF; + this->PDPTEIndex = Address & 0x1FF; Address >>= 9; - this->PDPIndex = Address & 0x1FF; + this->PMLIndex = Address & 0x1FF; #elif defined(__i386__) uint64_t Address = VirtualAddress; Address >>= 12; - this->PIndex = Address & 0x3FF; + this->PTEIndex = Address & 0x3FF; Address >>= 10; - this->PTIndex = Address & 0x3FF; + this->PDEIndex = Address & 0x3FF; Address >>= 10; - this->PDIndex = Address & 0x3FF; + this->PDPTEIndex = Address & 0x3FF; #elif defined(__aarch64__) #endif } diff --git a/Core/Memory/StackGuard.cpp b/Core/Memory/StackGuard.cpp index f9eac9f..1fdb301 100644 --- a/Core/Memory/StackGuard.cpp +++ b/Core/Memory/StackGuard.cpp @@ -4,7 +4,7 @@ namespace Memory { - StackGuard::StackGuard(bool User, PageTable *Table) + StackGuard::StackGuard(bool User, PageTable4 *Table) { this->UserMode = User; this->Table = Table; diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index 4c62976..2d6922e 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -12,33 +12,31 @@ namespace Memory Address &= 0xFFFFFFFFFFFFF000; PageMapIndexer Index = PageMapIndexer((uint64_t)Address); - PageDirectoryEntry PDE = this->Table->Entries[Index.PDPIndex]; - PageTable *PDP = nullptr; - PageTable *PD = nullptr; - PageTable *PT = nullptr; - if (PDE.GetFlag(Flag)) - PDP = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - else - return false; + PageMapLevel4 PML4 = this->Table->Entries[Index.PMLIndex]; - PDE = PDP->Entries[Index.PDIndex]; - if (PDE.GetFlag(Flag)) - PD = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - else - return false; - - PDE = PD->Entries[Index.PTIndex]; - if (PDE.GetFlag(Flag)) - PT = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - else - return false; - - PDE = PT->Entries[Index.PIndex]; - if (PDE.GetFlag(Flag)) - return true; - else - return false; + PageDirectoryPointerTableEntryPtr *PDPTE = nullptr; + PageDirectoryEntryPtr *PDE = nullptr; + PageTableEntryPtr *PTE = nullptr; + if ((PML4.raw & Flag) > 0) + { + PDPTE = (PageDirectoryPointerTableEntryPtr *)((uint64_t)PML4.GetAddress() << 12); + if (PDPTE) + if ((PDPTE->Entries[Index.PDPTEIndex].Present)) + { + PDE = (PageDirectoryEntryPtr *)((uint64_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); + if (PDE) + if ((PDE->Entries[Index.PDEIndex].Present)) + { + PTE = (PageTableEntryPtr *)((uint64_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12); + if (PTE) + if ((PTE->Entries[Index.PTEIndex].Present)) + { + return true; + } + } + } + } return false; } @@ -50,58 +48,56 @@ namespace Memory error("No page table"); return; } + PageMapIndexer Index = PageMapIndexer((uint64_t)VirtualAddress); - PageDirectoryEntry PDE = this->Table->Entries[Index.PDPIndex]; - PageTable *PDP = nullptr; - if (!PDE.GetFlag(PTFlag::P)) + PageMapLevel4 PML4 = this->Table->Entries[Index.PMLIndex]; + PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr; + + if (!PML4.Present) { - PDP = (PageTable *)KernelAllocator.RequestPage(); - memset(PDP, 0, PAGE_SIZE); - PDE.ClearFlags(); - PDE.SetFlag(PTFlag::P, true); - PDE.AddFlag(Flags); - PDE.SetAddress((uint64_t)PDP >> 12); - this->Table->Entries[Index.PDPIndex] = PDE; + PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPage(); + memset(PDPTEPtr, 0, PAGE_SIZE); + PML4.Present = true; + PML4.raw |= Flags; + PML4.SetAddress((uint64_t)PDPTEPtr >> 12); + this->Table->Entries[Index.PMLIndex] = PML4; } else - PDP = (PageTable *)((uint64_t)PDE.GetAddress() << 12); + PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uint64_t)PML4.GetAddress() << 12); - PDE = PDP->Entries[Index.PDIndex]; - PageTable *PD = nullptr; - if (!PDE.GetFlag(PTFlag::P)) + PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex]; + PageDirectoryEntryPtr *PDEPtr = nullptr; + if (!PDPTE.Present) { - PD = (PageTable *)KernelAllocator.RequestPage(); - memset(PD, 0, PAGE_SIZE); - PDE.ClearFlags(); - PDE.SetFlag(PTFlag::P, true); - PDE.AddFlag(Flags); - PDE.SetAddress((uint64_t)PD >> 12); - PDP->Entries[Index.PDIndex] = PDE; + PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator.RequestPage(); + memset(PDEPtr, 0, PAGE_SIZE); + PDPTE.Present = true; + PDPTE.raw |= Flags; + PDPTE.SetAddress((uint64_t)PDEPtr >> 12); + PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE; } else - PD = (PageTable *)((uint64_t)PDE.GetAddress() << 12); + PDEPtr = (PageDirectoryEntryPtr *)((uint64_t)PDPTE.GetAddress() << 12); - PDE = PD->Entries[Index.PTIndex]; - PageTable *PT = nullptr; - if (!PDE.GetFlag(PTFlag::P)) + PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex]; + PageTableEntryPtr *PTEPtr = nullptr; + if (!PDE.Present) { - PT = (PageTable *)KernelAllocator.RequestPage(); - memset(PT, 0, PAGE_SIZE); - PDE.ClearFlags(); - PDE.SetFlag(PTFlag::P, true); - PDE.AddFlag(Flags); - PDE.SetAddress((uint64_t)PT >> 12); - PD->Entries[Index.PTIndex] = PDE; + PTEPtr = (PageTableEntryPtr *)KernelAllocator.RequestPage(); + memset(PTEPtr, 0, PAGE_SIZE); + PDE.Present = true; + PDE.raw |= Flags; + PDE.SetAddress((uint64_t)PTEPtr >> 12); + PDEPtr->Entries[Index.PDEIndex] = PDE; } else - PT = (PageTable *)((uint64_t)PDE.GetAddress() << 12); + PTEPtr = (PageTableEntryPtr *)((uint64_t)PDE.GetAddress() << 12); - PDE = PT->Entries[Index.PIndex]; - PDE.ClearFlags(); - PDE.SetFlag(PTFlag::P, true); - PDE.AddFlag(Flags); - PDE.SetAddress((uint64_t)PhysicalAddress >> 12); - PT->Entries[Index.PIndex] = PDE; + PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; + PTE.Present = true; + PTE.raw |= Flags; + PTE.SetAddress((uint64_t)PhysicalAddress >> 12); + PTEPtr->Entries[Index.PTEIndex] = PTE; #if defined(__amd64__) CPU::x64::invlpg(VirtualAddress); @@ -131,7 +127,10 @@ namespace Memory (byte & 0x01 ? '1' : '0') if (!this->Check(VirtualAddress, (PTFlag)Flags)) // quick workaround just to see where it fails - warn("Failed to map %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, BYTE_TO_BINARY(Flags)); + { + this->Check(VirtualAddress, (PTFlag)Flags); + warn("Failed to map %#lx - %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags)); + } #endif } @@ -151,31 +150,36 @@ namespace Memory } PageMapIndexer Index = PageMapIndexer((uint64_t)VirtualAddress); - PageDirectoryEntry PDE = this->Table->Entries[Index.PDPIndex]; - - if (PDE.GetFlag(PTFlag::P)) + PageMapLevel4 PML4 = this->Table->Entries[Index.PMLIndex]; + if (!PML4.Present) { - PageTable *PDP = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - - PDE = PDP->Entries[Index.PDIndex]; - if (PDE.GetFlag(PTFlag::P)) - { - PageTable *PD = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - - PDE = PD->Entries[Index.PTIndex]; - if (PDE.GetFlag(PTFlag::P)) - { - PageTable *PT = (PageTable *)((uint64_t)PDE.GetAddress() << 12); - - PDE = PT->Entries[Index.PIndex]; - if (PDE.GetFlag(PTFlag::P)) - { - PDE.ClearFlags(); - // debug("Unmapped %#lx", VirtualAddress); - } - } - } + error("Page not present"); + return; } + PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uint64_t)PML4.Address << 12); + PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex]; + if (!PDPTE.Present) + { + error("Page not present"); + return; + } + PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uint64_t)PDPTE.Address << 12); + PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex]; + if (!PDE.Present) + { + error("Page not present"); + return; + } + PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uint64_t)PDE.Address << 12); + PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; + if (!PTE.Present) + { + error("Page not present"); + return; + } + + PTE.Present = false; + PTEPtr->Entries[Index.PTEIndex] = PTE; #if defined(__amd64__) CPU::x64::invlpg(VirtualAddress); @@ -204,12 +208,12 @@ namespace Memory this->Map(VirtualAddress, PhysicalAddress, Flags); } - Virtual::Virtual(PageTable *Table) + Virtual::Virtual(PageTable4 *Table) { if (Table) this->Table = Table; else - this->Table = (PageTable *)CPU::PageTable(); + this->Table = (PageTable4 *)CPU::PageTable(); } Virtual::~Virtual() {} diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 25065b4..9592249 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -1005,7 +1005,7 @@ namespace Tasking { SecurityManager.TrustToken(Process->Security.UniqueToken, TokenTrustLevel::TrustedByKernel); #if defined(__amd64__) - Process->PageTable = (Memory::PageTable *)CPU::x64::readcr3().raw; + Process->PageTable = (Memory::PageTable4 *)CPU::x64::readcr3().raw; #elif defined(__i386__) #elif defined(__aarch64__) #endif @@ -1015,7 +1015,7 @@ namespace Tasking { SecurityManager.TrustToken(Process->Security.UniqueToken, TokenTrustLevel::Untrusted); #if defined(__amd64__) - Process->PageTable = (Memory::PageTable *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); + Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE)); memcpy(Process->PageTable, (void *)UserspaceKernelOnlyPageTable, PAGE_SIZE); for (uint64_t i = 0; i < TO_PAGES(PAGE_SIZE); i++) Memory::Virtual(Process->PageTable).Map((void *)Process->PageTable, (void *)Process->PageTable, Memory::PTFlag::RW); // Make sure the page table is mapped. diff --git a/include/memory.hpp b/include/memory.hpp index bcbc241..cd77039 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -152,58 +152,238 @@ namespace Memory XD = (uint64_t)1 << 63 }; - typedef union __attribute__((packed)) + /* 2.2 Paging in IA-32e Mode - https://composter.com.ua/documents/TLBs_Paging-Structure_Caches_and_Their_Invalidation.pdf */ + + union __attribute__((packed)) PageTableEntry { struct { -#if defined(__amd64__) - bool Present : 1; - bool ReadWrite : 1; - bool UserSupervisor : 1; - bool WriteThrough : 1; - bool CacheDisable : 1; - bool Accessed : 1; - bool Dirty : 1; - bool PageSize : 1; - bool Global : 1; - uint8_t Available1 : 3; - bool PageAttributeTable : 1; - uint64_t Reserved : 39; - uint32_t Available2 : 7; - uint16_t ProtectionKey : 4; - bool ExecuteDisable : 1; -#elif defined(__i386__) - bool Present : 1; - bool ReadWrite : 1; - bool UserSupervisor : 1; - bool Accessed : 1; - bool Dirty : 1; - uint8_t Available : 7; - uint32_t Frame : 20; -// TODO: i386 PDEData is not tested -#elif defined(__aarch64__) -// TODO: aarch64 PDEData not implemented -#endif + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Dirty : 1; // 6 + bool PageAttributeTable : 1; // 7 + bool Global : 1; // 8 + uint8_t Available0 : 3; // 9-11 + uint64_t Address : 40; // 12-51 + uint32_t Available1 : 7; // 52-58 + bool ProtectionKey : 4; // 59-62 + bool ExecuteDisable : 1; // 63 }; uint64_t raw; - } PDEData; - struct __attribute__((packed)) PageDirectoryEntry - { - PDEData Value; - void AddFlag(uint64_t Flag); - void RemoveFlags(uint64_t Flag); - void ClearFlags(); - void SetFlag(uint64_t Flag, bool Enabled); - bool GetFlag(uint64_t Flag); - uint64_t GetFlag(); - void SetAddress(uint64_t Address); - uint64_t GetAddress(); + /** @brief Set Address */ + void SetAddress(uint64_t _Address) + { +#if defined(__amd64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(__i386__) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(__aarch64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get Address */ + uint64_t GetAddress() + { +#if defined(__amd64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(__i386__) + return (this->raw & 0x003FFFFF000) >> 12; +#elif defined(__aarch64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } }; - struct PageTable + struct __attribute__((packed)) PageTableEntryPtr { - PageDirectoryEntry Entries[512]; + PageTableEntry Entries[511]; + }; + + union __attribute__((packed)) PageDirectoryEntry + { + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool PageSize : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + /** @brief Set PageTableEntryPtr address */ + void SetAddress(uint64_t _Address) + { +#if defined(__amd64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(__i386__) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(__aarch64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageTableEntryPtr address */ + uint64_t GetAddress() + { +#if defined(__amd64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(__i386__) + return (this->raw & 0x003FFFFF000) >> 12; +#elif defined(__aarch64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __attribute__((packed)) PageDirectoryEntryPtr + { + PageDirectoryEntry Entries[511]; + }; + + union __attribute__((packed)) PageDirectoryPointerTableEntry + { + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool PageSize : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + /** @brief Set PageDirectoryEntryPtr address */ + void SetAddress(uint64_t _Address) + { +#if defined(__amd64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(__i386__) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(__aarch64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageDirectoryEntryPtr address */ + uint64_t GetAddress() + { +#if defined(__amd64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(__i386__) + return (this->raw & 0x003FFFFF000) >> 12; +#elif defined(__aarch64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr + { + PageDirectoryPointerTableEntry Entries[511]; + }; + + union __attribute__((packed)) PageMapLevel4 + { + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool Reserved0 : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + /** @brief Set PageDirectoryPointerTableEntryPtr address */ + void SetAddress(uint64_t _Address) + { +#if defined(__amd64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#elif defined(__i386__) + _Address &= 0x000FFFFF; + this->raw &= 0xFFC00003; + this->raw |= (_Address << 12); +#elif defined(__aarch64__) + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); +#endif + } + + /** @brief Get PageDirectoryPointerTableEntryPtr address */ + uint64_t GetAddress() + { +#if defined(__amd64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#elif defined(__i386__) + return (this->raw & 0x003FFFFF000) >> 12; +#elif defined(__aarch64__) + return (this->raw & 0x000FFFFFFFFFF000) >> 12; +#endif + } + }; + + struct PageTable4 + { + PageMapLevel4 Entries[511]; + } __attribute__((aligned(0x1000))); + + struct __attribute__((packed)) PageMapLevel5 + { + /* FIXME: NOT IMPLEMENTED! */ + }; + + struct PageTable5 + { + PageMapLevel5 Entries[511]; } __attribute__((aligned(0x1000))); class Physical @@ -337,16 +517,16 @@ namespace Memory { private: NewLock(MemoryLock); - PageTable *Table = nullptr; + PageTable4 *Table = nullptr; public: class PageMapIndexer { public: - uint64_t PDPIndex = 0; - uint64_t PDIndex = 0; - uint64_t PTIndex = 0; - uint64_t PIndex = 0; + uint64_t PMLIndex = 0; + uint64_t PDPTEIndex = 0; + uint64_t PDEIndex = 0; + uint64_t PTEIndex = 0; PageMapIndexer(uint64_t VirtualAddress); }; @@ -408,7 +588,7 @@ namespace Memory * * @param Table Page table. If null, it will use the current page table. */ - Virtual(PageTable *Table = nullptr); + Virtual(PageTable4 *Table = nullptr); /** * @brief Destroy the Virtual object @@ -426,7 +606,7 @@ namespace Memory void *SGT = nullptr; uint64_t Size = 0; bool UserMode = false; - PageTable *Table = nullptr; + PageTable4 *Table = nullptr; public: /** @brief For general info */ @@ -439,7 +619,7 @@ namespace Memory * @brief Construct a new Stack Guard object * @param User Stack for user mode? */ - StackGuard(bool User, PageTable *Table); + StackGuard(bool User, PageTable4 *Table); /** * @brief Destroy the Stack Guard object */ @@ -470,8 +650,8 @@ void operator delete(void *Pointer, long unsigned int Size); void operator delete[](void *Pointer, long unsigned int Size); extern Memory::Physical KernelAllocator; -extern Memory::PageTable *KernelPageTable; -extern Memory::PageTable *UserspaceKernelOnlyPageTable; +extern Memory::PageTable4 *KernelPageTable; +extern Memory::PageTable4 *UserspaceKernelOnlyPageTable; #endif // __cplusplus diff --git a/include/task.hpp b/include/task.hpp index ff717e9..670373c 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -145,7 +145,7 @@ namespace Tasking Vector Threads; Vector Children; HashMap *IPCHandles; - Memory::PageTable *PageTable; + Memory::PageTable4 *PageTable; }; enum TokenTrustLevel