mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-01 18:39:16 +00:00
Merge remote-tracking branch 'Kernel/master'
This commit is contained in:
90
Kernel/core/memory/page_table.cpp
Normal file
90
Kernel/core/memory/page_table.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user