Apply code from memory-test branch

This commit is contained in:
Alex
2022-12-05 23:20:06 +02:00
parent 0116fd3b38
commit 1bb97f19fd
9 changed files with 403 additions and 263 deletions

View File

@ -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)

View File

@ -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);

View File

@ -1,42 +0,0 @@
#include <memory.hpp>
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
}
}

View File

@ -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
}

View File

@ -4,7 +4,7 @@
namespace Memory
{
StackGuard::StackGuard(bool User, PageTable *Table)
StackGuard::StackGuard(bool User, PageTable4 *Table)
{
this->UserMode = User;
this->Table = Table;

View File

@ -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() {}