mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
91 lines
2.7 KiB
C++
91 lines
2.7 KiB
C++
#include <memory.hpp>
|
|
|
|
#include <filesystem.hpp>
|
|
#include <signal.hpp>
|
|
#include <utsname.h>
|
|
#include <time.h>
|
|
|
|
namespace Memory
|
|
{
|
|
void PageTable::Update()
|
|
{
|
|
#if defined(a86)
|
|
asmv("mov %0, %%cr3" ::"r"(this));
|
|
#elif defined(aa64)
|
|
asmv("msr ttbr0_el1, %0" ::"r"(this));
|
|
#endif
|
|
}
|
|
|
|
PageTable *PageTable::Fork()
|
|
{
|
|
PageTable *NewTable = (PageTable *)KernelAllocator.RequestPages(TO_PAGES(sizeof(PageTable)));
|
|
// memset(NewTable, 0, sizeof(PageTable));
|
|
// CreatePageTable(NewTable);
|
|
memcpy(NewTable, this, sizeof(PageTable));
|
|
|
|
debug("Forking page table %#lx to %#lx", this, NewTable);
|
|
#if defined(a64)
|
|
for (size_t i = 0; i < sizeof(Entries) / sizeof(Entries[0]); i++)
|
|
{
|
|
PageMapLevel4 *PML4 = &Entries[i];
|
|
PageMapLevel4 *NewPML4 = &NewTable->Entries[i];
|
|
if (!PML4->Present)
|
|
continue;
|
|
|
|
PageDirectoryPointerTableEntryPtr *ptrPDPT = (PageDirectoryPointerTableEntryPtr *)(PML4->GetAddress() << 12);
|
|
PageDirectoryPointerTableEntryPtr *ptrNewPDPT = (PageDirectoryPointerTableEntryPtr *)KernelAllocator.RequestPage();
|
|
NewPML4->SetAddress((uintptr_t)ptrNewPDPT >> 12);
|
|
for (size_t j = 0; j < sizeof(ptrPDPT->Entries) / sizeof(ptrPDPT->Entries[0]); j++)
|
|
{
|
|
PageDirectoryPointerTableEntry *PDPT = &ptrPDPT->Entries[j];
|
|
PageDirectoryPointerTableEntry *NewPDPT = &ptrNewPDPT->Entries[j];
|
|
*NewPDPT = *PDPT;
|
|
|
|
if (!PDPT->Present)
|
|
continue;
|
|
if (PDPT->PageSize)
|
|
continue;
|
|
|
|
PageDirectoryEntryPtr *ptrPDE = (PageDirectoryEntryPtr *)(PDPT->GetAddress() << 12);
|
|
PageDirectoryEntryPtr *ptrNewPDE = (PageDirectoryEntryPtr *)KernelAllocator.RequestPage();
|
|
NewPDPT->SetAddress((uintptr_t)ptrNewPDE >> 12);
|
|
for (size_t k = 0; k < sizeof(ptrPDE->Entries) / sizeof(ptrPDE->Entries[0]); k++)
|
|
{
|
|
PageDirectoryEntry *PDE = &ptrPDE->Entries[k];
|
|
PageDirectoryEntry *NewPDE = &ptrNewPDE->Entries[k];
|
|
*NewPDE = *PDE;
|
|
|
|
if (!PDE->Present)
|
|
continue;
|
|
if (PDE->PageSize)
|
|
continue;
|
|
|
|
PageTableEntryPtr *ptrPTE = (PageTableEntryPtr *)(PDE->GetAddress() << 12);
|
|
PageTableEntryPtr *ptrNewPTE = (PageTableEntryPtr *)KernelAllocator.RequestPage();
|
|
NewPDE->SetAddress((uintptr_t)ptrNewPTE >> 12);
|
|
for (size_t l = 0; l < sizeof(ptrPTE->Entries) / sizeof(ptrPTE->Entries[0]); l++)
|
|
{
|
|
PageTableEntry *PTE = &ptrPTE->Entries[l];
|
|
PageTableEntry *NewPTE = &ptrNewPTE->Entries[l];
|
|
*NewPTE = *PTE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
#error "PageTable::Fork() not implemented for other architectures"
|
|
#endif
|
|
|
|
debug("Forked page table %#lx to %#lx", this, NewTable);
|
|
return NewTable;
|
|
}
|
|
|
|
/* We can't have Memory::Virtual in the header */
|
|
void *PageTable::__getPhysical(void *Address)
|
|
{
|
|
Virtual vmm(this);
|
|
void *PhysAddr = vmm.GetPhysical((void *)Address);
|
|
return PhysAddr;
|
|
}
|
|
}
|