mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Add support for 2MB and 1GB map
This commit is contained in:
parent
5becc15ed7
commit
540152a339
@ -103,13 +103,10 @@ namespace SMP
|
|||||||
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24));
|
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRHI, (((ACPI::MADT *)madt)->lapic[i]->APICId << 24));
|
||||||
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500);
|
((APIC::APIC *)Interrupts::apic[0])->Write(APIC::APIC_ICRLO, 0x500);
|
||||||
|
|
||||||
Memory::Virtual vma = Memory::Virtual(KernelPageTable);
|
Memory::Virtual(KernelPageTable).Map(0x0, 0x0, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
|
|
||||||
vma.Map(0x0, 0x0, Memory::PTFlag::RW | Memory::PTFlag::US);
|
|
||||||
|
|
||||||
uint64_t TrampolineLength = (uintptr_t)&_trampoline_end - (uintptr_t)&_trampoline_start;
|
uint64_t TrampolineLength = (uintptr_t)&_trampoline_end - (uintptr_t)&_trampoline_start;
|
||||||
for (uint64_t i = 0; i < (TrampolineLength / PAGE_SIZE) + 2; i++)
|
Memory::Virtual(KernelPageTable).Map((void *)TRAMPOLINE_START, (void *)TRAMPOLINE_START, TrampolineLength, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
vma.Map((void *)(TRAMPOLINE_START + (i * PAGE_SIZE)), (void *)(TRAMPOLINE_START + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US);
|
|
||||||
|
|
||||||
memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength);
|
memcpy((void *)TRAMPOLINE_START, &_trampoline_start, TrampolineLength);
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ namespace Driver
|
|||||||
{
|
{
|
||||||
void Driver::MapPCIAddresses(PCI::PCIDeviceHeader *PCIDevice)
|
void Driver::MapPCIAddresses(PCI::PCIDeviceHeader *PCIDevice)
|
||||||
{
|
{
|
||||||
Memory::Virtual vma = Memory::Virtual(nullptr);
|
|
||||||
|
|
||||||
debug("Header Type: %d", PCIDevice->HeaderType);
|
debug("Header Type: %d", PCIDevice->HeaderType);
|
||||||
switch (PCIDevice->HeaderType)
|
switch (PCIDevice->HeaderType)
|
||||||
{
|
{
|
||||||
@ -103,12 +101,7 @@ namespace Driver
|
|||||||
size_t BARSize = BARsSize[i];
|
size_t BARSize = BARsSize[i];
|
||||||
|
|
||||||
debug("Mapping BAR%d from %#lx to %#lx", i, BARBase, BARBase + BARSize);
|
debug("Mapping BAR%d from %#lx to %#lx", i, BARBase, BARBase + BARSize);
|
||||||
for (uintptr_t j = BARBase;
|
Memory::Virtual().Map((void *)BARBase, (void *)BARBase, BARSize, Memory::PTFlag::RW | Memory::PTFlag::PWT);
|
||||||
j < (BARBase + BARSize);
|
|
||||||
j += PAGE_SIZE)
|
|
||||||
{
|
|
||||||
vma.Map((void *)j, (void *)j, Memory::PTFlag::RW | Memory::PTFlag::PWT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ((BAR[i] & 1) == 1) // I/O Base
|
else if ((BAR[i] & 1) == 1) // I/O Base
|
||||||
{
|
{
|
||||||
@ -116,12 +109,7 @@ namespace Driver
|
|||||||
uintptr_t BARSize = BARsSize[i];
|
uintptr_t BARSize = BARsSize[i];
|
||||||
|
|
||||||
debug("Mapping BAR%d from %#x to %#x", i, BARBase, BARBase + BARSize);
|
debug("Mapping BAR%d from %#x to %#x", i, BARBase, BARBase + BARSize);
|
||||||
for (uintptr_t j = BARBase;
|
Memory::Virtual().Map((void *)BARBase, (void *)BARBase, BARSize, Memory::PTFlag::RW | Memory::PTFlag::PWT);
|
||||||
j < (BARBase + BARSize);
|
|
||||||
j += PAGE_SIZE)
|
|
||||||
{
|
|
||||||
vma.Map((void *)j, (void *)j, Memory::PTFlag::RW | Memory::PTFlag::PWT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -75,22 +75,47 @@ NIF void tracepagetable(PageTable4 *pt)
|
|||||||
|
|
||||||
NIF void MapFromZero(PageTable4 *PT, BootInfo *Info)
|
NIF void MapFromZero(PageTable4 *PT, BootInfo *Info)
|
||||||
{
|
{
|
||||||
static int once = 0;
|
bool Page1GBSupport = false;
|
||||||
if (!once++)
|
bool PSESupport = false;
|
||||||
|
|
||||||
|
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||||
{
|
{
|
||||||
Virtual va = Virtual(PT);
|
CPU::x86::AMD::CPUID0x80000001 cpuid;
|
||||||
void *NullAddress = KernelAllocator.RequestPage();
|
cpuid.Get();
|
||||||
memset(NullAddress, 0, PAGE_SIZE); // TODO: If the CPU instruction pointer hits this page, there should be function to handle it. (memcpy assembly code?)
|
Page1GBSupport = cpuid.EDX.Page1GB;
|
||||||
va.Map((void *)0, (void *)NullAddress, PTFlag::RW | PTFlag::US);
|
PSESupport = cpuid.EDX.PSE;
|
||||||
size_t MemSize = Info->Memory.Size;
|
}
|
||||||
for (size_t t = 0; t < MemSize; t += PAGE_SIZE)
|
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
|
||||||
va.Map((void *)t, (void *)t, PTFlag::RW);
|
{
|
||||||
|
CPU::x86::Intel::CPUID0x80000001 cpuid;
|
||||||
|
cpuid.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Virtual va = Virtual(PT);
|
||||||
|
size_t MemSize = Info->Memory.Size;
|
||||||
|
|
||||||
|
if (Page1GBSupport && PSESupport)
|
||||||
|
{
|
||||||
|
debug("1GB Page Support Enabled");
|
||||||
|
#if defined(a64)
|
||||||
|
CPU::x64::CR4 cr4 = CPU::x64::readcr4();
|
||||||
|
cr4.PSE = 1;
|
||||||
|
CPU::x64::writecr4(cr4);
|
||||||
|
#elif defined(a32)
|
||||||
|
CPU::x32::CR4 cr4 = CPU::x32::readcr4();
|
||||||
|
cr4.PSE = 1;
|
||||||
|
CPU::x32::writecr4(cr4);
|
||||||
|
#elif defined(aa64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
va.Map((void *)0, (void *)0, MemSize, PTFlag::RW | PTFlag::PS /* , Virtual::MapType::OneGB */);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
va.Map((void *)0, (void *)0, MemSize, PTFlag::RW);
|
||||||
error("MapFromZero() called more than once!");
|
|
||||||
CPU::Stop();
|
void *NullAddress = KernelAllocator.RequestPage();
|
||||||
}
|
memset(NullAddress, 0, PAGE_SIZE); // TODO: If the CPU instruction pointer hits this page, there should be function to handle it. (memcpy assembly code?)
|
||||||
|
va.Remap((void *)0, (void *)NullAddress, PTFlag::RW | PTFlag::US);
|
||||||
}
|
}
|
||||||
|
|
||||||
NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info)
|
NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info)
|
||||||
@ -151,7 +176,7 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
|
|||||||
/* Text section */
|
/* Text section */
|
||||||
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
|
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW);
|
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
|
||||||
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
KernelAllocator.LockPage((void *)BaseKernelMapAddress);
|
||||||
BaseKernelMapAddress += PAGE_SIZE;
|
BaseKernelMapAddress += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace Memory
|
namespace Memory
|
||||||
{
|
{
|
||||||
bool Virtual::Check(void *VirtualAddress, PTFlag Flag)
|
bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type)
|
||||||
{
|
{
|
||||||
// 0x1000 aligned
|
// 0x1000 aligned
|
||||||
uintptr_t Address = (uintptr_t)VirtualAddress;
|
uintptr_t Address = (uintptr_t)VirtualAddress;
|
||||||
@ -39,20 +39,30 @@ namespace Memory
|
|||||||
{
|
{
|
||||||
PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
||||||
if (PDPTE)
|
if (PDPTE)
|
||||||
|
{
|
||||||
if ((PDPTE->Entries[Index.PDPTEIndex].Present))
|
if ((PDPTE->Entries[Index.PDPTEIndex].Present))
|
||||||
{
|
{
|
||||||
|
if (Type == MapType::OneGB && PDPTE->Entries[Index.PDPTEIndex].PageSize)
|
||||||
|
return true;
|
||||||
|
|
||||||
PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12);
|
PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12);
|
||||||
if (PDE)
|
if (PDE)
|
||||||
|
{
|
||||||
|
if (Type == MapType::TwoMB && PDE->Entries[Index.PDEIndex].PageSize)
|
||||||
|
return true;
|
||||||
|
|
||||||
if ((PDE->Entries[Index.PDEIndex].Present))
|
if ((PDE->Entries[Index.PDEIndex].Present))
|
||||||
{
|
{
|
||||||
PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12);
|
PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12);
|
||||||
if (PTE)
|
if (PTE)
|
||||||
|
{
|
||||||
if ((PTE->Entries[Index.PTEIndex].Present))
|
if ((PTE->Entries[Index.PTEIndex].Present))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -74,25 +84,35 @@ namespace Memory
|
|||||||
{
|
{
|
||||||
PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
||||||
if (PDPTE)
|
if (PDPTE)
|
||||||
|
{
|
||||||
if (PDPTE->Entries[Index.PDPTEIndex].Present)
|
if (PDPTE->Entries[Index.PDPTEIndex].Present)
|
||||||
{
|
{
|
||||||
|
if (PDPTE->Entries[Index.PDPTEIndex].PageSize)
|
||||||
|
return (void *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12);
|
||||||
|
|
||||||
PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12);
|
PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12);
|
||||||
if (PDE)
|
if (PDE)
|
||||||
|
{
|
||||||
if (PDE->Entries[Index.PDEIndex].Present)
|
if (PDE->Entries[Index.PDEIndex].Present)
|
||||||
{
|
{
|
||||||
|
if (PDE->Entries[Index.PDEIndex].PageSize)
|
||||||
|
return (void *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12);
|
||||||
|
|
||||||
PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12);
|
PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12);
|
||||||
if (PTE)
|
if (PTE)
|
||||||
|
{
|
||||||
if (PTE->Entries[Index.PTEIndex].Present)
|
if (PTE->Entries[Index.PTEIndex].Present)
|
||||||
{
|
|
||||||
return (void *)((uintptr_t)PTE->Entries[Index.PTEIndex].GetAddress() << 12);
|
return (void *)((uintptr_t)PTE->Entries[Index.PTEIndex].GetAddress() << 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
|
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
|
||||||
{
|
{
|
||||||
SmartLock(this->MemoryLock);
|
SmartLock(this->MemoryLock);
|
||||||
if (unlikely(!this->Table))
|
if (unlikely(!this->Table))
|
||||||
@ -118,6 +138,17 @@ namespace Memory
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12);
|
||||||
|
|
||||||
|
if (Type == MapType::OneGB)
|
||||||
|
{
|
||||||
|
PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex];
|
||||||
|
PDPTE.raw |= Flags;
|
||||||
|
PDPTE.PageSize = true;
|
||||||
|
PDPTE.SetAddress((uintptr_t)PhysicalAddress >> 12);
|
||||||
|
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PML4.raw |= DirectoryFlags;
|
PML4.raw |= DirectoryFlags;
|
||||||
this->Table->Entries[Index.PMLIndex] = PML4;
|
this->Table->Entries[Index.PMLIndex] = PML4;
|
||||||
|
|
||||||
@ -132,6 +163,17 @@ namespace Memory
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12);
|
PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12);
|
||||||
|
|
||||||
|
if (Type == MapType::TwoMB)
|
||||||
|
{
|
||||||
|
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
|
||||||
|
PDE.raw |= Flags;
|
||||||
|
PDE.PageSize = true;
|
||||||
|
PDE.SetAddress((uintptr_t)PhysicalAddress >> 12);
|
||||||
|
PDEPtr->Entries[Index.PDEIndex] = PDE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PDPTE.raw |= DirectoryFlags;
|
PDPTE.raw |= DirectoryFlags;
|
||||||
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
|
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
|
||||||
|
|
||||||
@ -182,18 +224,25 @@ namespace Memory
|
|||||||
(byte & 0x02 ? '1' : '0'), \
|
(byte & 0x02 ? '1' : '0'), \
|
||||||
(byte & 0x01 ? '1' : '0')
|
(byte & 0x01 ? '1' : '0')
|
||||||
|
|
||||||
if (!this->Check(VirtualAddress, (PTFlag)Flags)) // quick workaround just to see where it fails
|
if (!this->Check(VirtualAddress, (PTFlag)Flags, Type)) // quick workaround just to see where it fails
|
||||||
warn("Failed to map %#lx - %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags));
|
warn("Failed to map %#lx - %#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, size_t PageCount, uint64_t Flags)
|
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, MapType Type)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < PageCount; i++)
|
int PageSize = PAGE_SIZE_4K;
|
||||||
this->Map((void *)((uintptr_t)VirtualAddress + (i * PAGE_SIZE)), (void *)((uintptr_t)PhysicalAddress + (i * PAGE_SIZE)), Flags);
|
|
||||||
|
if (Type == MapType::TwoMB)
|
||||||
|
PageSize = PAGE_SIZE_2M;
|
||||||
|
else if (Type == MapType::OneGB)
|
||||||
|
PageSize = PAGE_SIZE_1G;
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < Length; i += PageSize)
|
||||||
|
this->Map((void *)((uintptr_t)VirtualAddress + i), (void *)((uintptr_t)PhysicalAddress + i), Flags, Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Virtual::Unmap(void *VirtualAddress)
|
void Virtual::Unmap(void *VirtualAddress, MapType Type)
|
||||||
{
|
{
|
||||||
SmartLock(this->MemoryLock);
|
SmartLock(this->MemoryLock);
|
||||||
if (!this->Table)
|
if (!this->Table)
|
||||||
@ -218,6 +267,13 @@ namespace Memory
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Type == MapType::OneGB && PDPTE.PageSize)
|
||||||
|
{
|
||||||
|
PDPTE.Present = false;
|
||||||
|
PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12);
|
PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.Address << 12);
|
||||||
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
|
PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex];
|
||||||
if (!PDE.Present)
|
if (!PDE.Present)
|
||||||
@ -226,6 +282,13 @@ namespace Memory
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Type == MapType::TwoMB && PDE.PageSize)
|
||||||
|
{
|
||||||
|
PDE.Present = false;
|
||||||
|
PDEPtr->Entries[Index.PDEIndex] = PDE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12);
|
PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.Address << 12);
|
||||||
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
|
PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex];
|
||||||
if (!PTE.Present)
|
if (!PTE.Present)
|
||||||
@ -252,16 +315,23 @@ namespace Memory
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Virtual::Unmap(void *VirtualAddress, size_t PageCount)
|
void Virtual::Unmap(void *VirtualAddress, size_t Length, MapType Type)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < PageCount; i++)
|
int PageSize = PAGE_SIZE_4K;
|
||||||
this->Unmap((void *)((uintptr_t)VirtualAddress + (i * PAGE_SIZE)));
|
|
||||||
|
if (Type == MapType::TwoMB)
|
||||||
|
PageSize = PAGE_SIZE_2M;
|
||||||
|
else if (Type == MapType::OneGB)
|
||||||
|
PageSize = PAGE_SIZE_1G;
|
||||||
|
|
||||||
|
for (uintptr_t i = 0; i < Length; i += PageSize)
|
||||||
|
this->Unmap((void *)((uintptr_t)VirtualAddress + i), Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Virtual::Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags)
|
void Virtual::Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
|
||||||
{
|
{
|
||||||
this->Unmap(VirtualAddress);
|
this->Unmap(VirtualAddress, Type);
|
||||||
this->Map(VirtualAddress, PhysicalAddress, Flags);
|
this->Map(VirtualAddress, PhysicalAddress, Flags, Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Virtual::Virtual(PageTable4 *Table)
|
Virtual::Virtual(PageTable4 *Table)
|
||||||
|
@ -36,8 +36,7 @@ namespace Video
|
|||||||
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1);
|
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1);
|
||||||
memcpy((void *)font2, Start, FontDataLength);
|
memcpy((void *)font2, Start, FontDataLength);
|
||||||
|
|
||||||
for (uintptr_t i = 0; i < FontDataLength / PAGE_SIZE + 1; i++)
|
Memory::Virtual().Map((void *)font2, (void *)font2, FontDataLength, Memory::PTFlag::RW);
|
||||||
Memory::Virtual().Map((void *)(font2 + (i * PAGE_SIZE)), (void *)(font2 + (i * PAGE_SIZE)), Memory::PTFlag::RW);
|
|
||||||
|
|
||||||
if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3)
|
if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3)
|
||||||
{
|
{
|
||||||
|
@ -51,9 +51,7 @@ namespace Execute
|
|||||||
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size));
|
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size));
|
||||||
memset(Buffer, 0, Section->sh_size);
|
memset(Buffer, 0, Section->sh_size);
|
||||||
|
|
||||||
Memory::Virtual pva = Memory::Virtual(Process->PageTable);
|
Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
for (size_t i = 0; i < TO_PAGES(Section->sh_size); i++)
|
|
||||||
pva.Map((void *)((uintptr_t)Buffer + (i * PAGE_SIZE)), (void *)((uintptr_t)Buffer + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US);
|
|
||||||
|
|
||||||
Section->sh_offset = (uintptr_t)Buffer - (uintptr_t)BaseImage;
|
Section->sh_offset = (uintptr_t)Buffer - (uintptr_t)BaseImage;
|
||||||
debug("Section %ld", Section->sh_size);
|
debug("Section %ld", Section->sh_size);
|
||||||
|
@ -92,7 +92,7 @@ namespace Execute
|
|||||||
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
|
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
|
||||||
debug("LibFile: %#lx", LibFile);
|
debug("LibFile: %#lx", LibFile);
|
||||||
memcpy(LibFile, (void *)ElfImage, Length);
|
memcpy(LibFile, (void *)ElfImage, Length);
|
||||||
Memory::Virtual().Map(LibFile, LibFile, TO_PAGES(Length), Memory::RW | Memory::US | Memory::G);
|
Memory::Virtual().Map(LibFile, LibFile, Length, Memory::RW | Memory::US | Memory::G);
|
||||||
|
|
||||||
Memory::Virtual ncpV = pV;
|
Memory::Virtual ncpV = pV;
|
||||||
sl.MemoryImage = r_cst(uint64_t, ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal);
|
sl.MemoryImage = r_cst(uint64_t, ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal);
|
||||||
|
@ -61,9 +61,7 @@ namespace Execute
|
|||||||
void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length));
|
void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length));
|
||||||
memcpy(BaseImage, (void *)ExFile->node->Address, ExFile->node->Length);
|
memcpy(BaseImage, (void *)ExFile->node->Address, ExFile->node->Length);
|
||||||
|
|
||||||
Memory::Virtual pva = Memory::Virtual(Process->PageTable);
|
Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile->node->Length, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
for (size_t i = 0; i < TO_PAGES(ExFile->node->Length); i++)
|
|
||||||
pva.Map((void *)((uintptr_t)BaseImage + (i * PAGE_SIZE)), (void *)((uintptr_t)BaseImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US);
|
|
||||||
|
|
||||||
std::vector<AuxiliaryVector> auxv; // TODO!
|
std::vector<AuxiliaryVector> auxv; // TODO!
|
||||||
|
|
||||||
|
@ -723,8 +723,7 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE));
|
Process->PageTable = (Memory::PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE));
|
||||||
memcpy(Process->PageTable, (void *)UserspaceKernelOnlyPageTable, PAGE_SIZE);
|
memcpy(Process->PageTable, (void *)UserspaceKernelOnlyPageTable, PAGE_SIZE);
|
||||||
for (size_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.
|
||||||
Memory::Virtual(Process->PageTable).Map((void *)Process->PageTable, (void *)Process->PageTable, Memory::PTFlag::RW); // Make sure the page table is mapped.
|
|
||||||
}
|
}
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
#elif defined(aa64)
|
#elif defined(aa64)
|
||||||
|
@ -174,7 +174,7 @@ namespace Memory
|
|||||||
|
|
||||||
/* 2.2 Paging in IA-32e Mode - https://composter.com.ua/documents/TLBs_Paging-Structure_Caches_and_Their_Invalidation.pdf */
|
/* 2.2 Paging in IA-32e Mode - https://composter.com.ua/documents/TLBs_Paging-Structure_Caches_and_Their_Invalidation.pdf */
|
||||||
|
|
||||||
union __attribute__((packed)) PageTableEntry
|
union __packed PageTableEntry
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -187,10 +187,10 @@ namespace Memory
|
|||||||
bool Dirty : 1; // 6
|
bool Dirty : 1; // 6
|
||||||
bool PageAttributeTable : 1; // 7
|
bool PageAttributeTable : 1; // 7
|
||||||
bool Global : 1; // 8
|
bool Global : 1; // 8
|
||||||
uint8_t Available0 : 3; // 9-11
|
char Available0 : 3; // 9-11
|
||||||
uint64_t Address : 40; // 12-51
|
long Address : 40; // 12-51
|
||||||
uint32_t Available1 : 7; // 52-58
|
char Available1 : 7; // 52-58
|
||||||
uint8_t ProtectionKey : 4; // 59-62
|
char ProtectionKey : 4; // 59-62
|
||||||
bool ExecuteDisable : 1; // 63
|
bool ExecuteDisable : 1; // 63
|
||||||
};
|
};
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
@ -226,28 +226,49 @@ namespace Memory
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) PageTableEntryPtr
|
struct __packed PageTableEntryPtr
|
||||||
{
|
{
|
||||||
PageTableEntry Entries[511];
|
PageTableEntry Entries[511];
|
||||||
};
|
};
|
||||||
|
|
||||||
union __attribute__((packed)) PageDirectoryEntry
|
union __packed PageDirectoryEntry
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool Present : 1; // 0
|
bool Present : 1; // 0
|
||||||
bool ReadWrite : 1; // 1
|
bool ReadWrite : 1; // 1
|
||||||
bool UserSupervisor : 1; // 2
|
bool UserSupervisor : 1; // 2
|
||||||
bool WriteThrough : 1; // 3
|
bool WriteThrough : 1; // 3
|
||||||
bool CacheDisable : 1; // 4
|
bool CacheDisable : 1; // 4
|
||||||
bool Accessed : 1; // 5
|
bool Accessed : 1; // 5
|
||||||
bool Available0 : 1; // 6
|
bool Available0 : 1; // 6
|
||||||
bool PageSize : 1; // 7
|
bool PageSize : 1; // 7
|
||||||
uint8_t Available1 : 4; // 8-11
|
char Available1 : 4; // 8-11
|
||||||
uint64_t Address : 40; // 12-51
|
long Address : 40; // 12-51
|
||||||
uint32_t Available2 : 11; // 52-62
|
short Available2 : 11; // 52-62
|
||||||
bool ExecuteDisable : 1; // 63
|
bool ExecuteDisable : 1; // 63
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 Dirty : 1; // 6
|
||||||
|
bool PageSize : 1; // 7
|
||||||
|
bool Global : 1; // 8
|
||||||
|
char Available0 : 3; // 9-11
|
||||||
|
bool PageAttributeTable : 1; // 12
|
||||||
|
char Reserved0 : 8; // 13-20
|
||||||
|
long Address : 31; // 21-51
|
||||||
|
char Available1 : 7; // 52-58
|
||||||
|
char ProtectionKey : 4; // 59-62
|
||||||
|
bool ExecuteDisable : 1; // 63
|
||||||
|
} TwoMB;
|
||||||
|
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
/** @brief Set PageTableEntryPtr address */
|
/** @brief Set PageTableEntryPtr address */
|
||||||
@ -281,28 +302,49 @@ namespace Memory
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) PageDirectoryEntryPtr
|
struct __packed PageDirectoryEntryPtr
|
||||||
{
|
{
|
||||||
PageDirectoryEntry Entries[511];
|
PageDirectoryEntry Entries[511];
|
||||||
};
|
};
|
||||||
|
|
||||||
union __attribute__((packed)) PageDirectoryPointerTableEntry
|
union __packed PageDirectoryPointerTableEntry
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool Present : 1; // 0
|
bool Present : 1; // 0
|
||||||
bool ReadWrite : 1; // 1
|
bool ReadWrite : 1; // 1
|
||||||
bool UserSupervisor : 1; // 2
|
bool UserSupervisor : 1; // 2
|
||||||
bool WriteThrough : 1; // 3
|
bool WriteThrough : 1; // 3
|
||||||
bool CacheDisable : 1; // 4
|
bool CacheDisable : 1; // 4
|
||||||
bool Accessed : 1; // 5
|
bool Accessed : 1; // 5
|
||||||
bool Available0 : 1; // 6
|
bool Available0 : 1; // 6
|
||||||
bool PageSize : 1; // 7
|
bool PageSize : 1; // 7
|
||||||
uint8_t Available1 : 4; // 8-11
|
char Available1 : 4; // 8-11
|
||||||
uint64_t Address : 40; // 12-51
|
long Address : 40; // 12-51
|
||||||
uint32_t Available2 : 11; // 52-62
|
short Available2 : 11; // 52-62
|
||||||
bool ExecuteDisable : 1; // 63
|
bool ExecuteDisable : 1; // 63
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 Dirty : 1; // 6
|
||||||
|
bool PageSize : 1; // 7
|
||||||
|
bool Global : 1; // 8
|
||||||
|
char Available0 : 3; // 9-11
|
||||||
|
bool PageAttributeTable : 1; // 12
|
||||||
|
int Reserved0 : 17; // 13-29
|
||||||
|
long Address : 22; // 30-51
|
||||||
|
char Available1 : 7; // 52-58
|
||||||
|
char ProtectionKey : 4; // 59-62
|
||||||
|
bool ExecuteDisable : 1; // 63
|
||||||
|
} OneGB;
|
||||||
|
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
/** @brief Set PageDirectoryEntryPtr address */
|
/** @brief Set PageDirectoryEntryPtr address */
|
||||||
@ -336,27 +378,27 @@ namespace Memory
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr
|
struct __packed PageDirectoryPointerTableEntryPtr
|
||||||
{
|
{
|
||||||
PageDirectoryPointerTableEntry Entries[511];
|
PageDirectoryPointerTableEntry Entries[511];
|
||||||
};
|
};
|
||||||
|
|
||||||
union __attribute__((packed)) PageMapLevel4
|
union __packed PageMapLevel4
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool Present : 1; // 0
|
bool Present : 1; // 0
|
||||||
bool ReadWrite : 1; // 1
|
bool ReadWrite : 1; // 1
|
||||||
bool UserSupervisor : 1; // 2
|
bool UserSupervisor : 1; // 2
|
||||||
bool WriteThrough : 1; // 3
|
bool WriteThrough : 1; // 3
|
||||||
bool CacheDisable : 1; // 4
|
bool CacheDisable : 1; // 4
|
||||||
bool Accessed : 1; // 5
|
bool Accessed : 1; // 5
|
||||||
bool Available0 : 1; // 6
|
bool Available0 : 1; // 6
|
||||||
bool Reserved0 : 1; // 7
|
bool Reserved0 : 1; // 7
|
||||||
uint8_t Available1 : 4; // 8-11
|
char Available1 : 4; // 8-11
|
||||||
uint64_t Address : 40; // 12-51
|
long Address : 40; // 12-51
|
||||||
uint32_t Available2 : 11; // 52-62
|
short Available2 : 11; // 52-62
|
||||||
bool ExecuteDisable : 1; // 63
|
bool ExecuteDisable : 1; // 63
|
||||||
};
|
};
|
||||||
uint64_t raw;
|
uint64_t raw;
|
||||||
|
|
||||||
@ -396,7 +438,7 @@ namespace Memory
|
|||||||
PageMapLevel4 Entries[511];
|
PageMapLevel4 Entries[511];
|
||||||
} __attribute__((aligned(0x1000)));
|
} __attribute__((aligned(0x1000)));
|
||||||
|
|
||||||
struct __attribute__((packed)) PageMapLevel5
|
struct __packed PageMapLevel5
|
||||||
{
|
{
|
||||||
/* FIXME: NOT IMPLEMENTED! */
|
/* FIXME: NOT IMPLEMENTED! */
|
||||||
};
|
};
|
||||||
@ -554,6 +596,13 @@ namespace Memory
|
|||||||
PageTable4 *Table = nullptr;
|
PageTable4 *Table = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum MapType
|
||||||
|
{
|
||||||
|
FourKB,
|
||||||
|
TwoMB,
|
||||||
|
OneGB
|
||||||
|
};
|
||||||
|
|
||||||
class PageMapIndexer
|
class PageMapIndexer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -572,7 +621,7 @@ namespace Memory
|
|||||||
* @return true if page has the specified flag.
|
* @return true if page has the specified flag.
|
||||||
* @return false if page is has the specified flag.
|
* @return false if page is has the specified flag.
|
||||||
*/
|
*/
|
||||||
bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P);
|
bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get physical address of the page.
|
* @brief Get physical address of the page.
|
||||||
@ -588,7 +637,7 @@ namespace Memory
|
|||||||
* @param PhysicalAddress Physical address of the page.
|
* @param PhysicalAddress Physical address of the page.
|
||||||
* @param Flags Flags of the page. Check PTFlag enum.
|
* @param Flags Flags of the page. Check PTFlag enum.
|
||||||
*/
|
*/
|
||||||
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flag = PTFlag::P);
|
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flag = PTFlag::P, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map multiple pages.
|
* @brief Map multiple pages.
|
||||||
@ -598,22 +647,22 @@ namespace Memory
|
|||||||
* @param PageCount Number of pages.
|
* @param PageCount Number of pages.
|
||||||
* @param Flags Flags of the page. Check PTFlag enum.
|
* @param Flags Flags of the page. Check PTFlag enum.
|
||||||
*/
|
*/
|
||||||
void Map(void *VirtualAddress, void *PhysicalAddress, size_t PageCount, uint64_t Flags);
|
void Map(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unmap page.
|
* @brief Unmap page.
|
||||||
*
|
*
|
||||||
* @param VirtualAddress Virtual address of the page.
|
* @param VirtualAddress Virtual address of the page.
|
||||||
*/
|
*/
|
||||||
void Unmap(void *VirtualAddress);
|
void Unmap(void *VirtualAddress, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unmap multiple pages.
|
* @brief Unmap multiple pages.
|
||||||
*
|
*
|
||||||
* @param VirtualAddress First virtual address of the page.
|
* @param VirtualAddress First virtual address of the page.
|
||||||
* @param PageCount Number of pages.
|
* @param Length Number of pages.
|
||||||
*/
|
*/
|
||||||
void Unmap(void *VirtualAddress, size_t PageCount);
|
void Unmap(void *VirtualAddress, size_t Length, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remap page.
|
* @brief Remap page.
|
||||||
@ -622,7 +671,7 @@ namespace Memory
|
|||||||
* @param PhysicalAddress Physical address of the page.
|
* @param PhysicalAddress Physical address of the page.
|
||||||
* @param Flags Flags of the page. Check PTFlag enum.
|
* @param Flags Flags of the page. Check PTFlag enum.
|
||||||
*/
|
*/
|
||||||
void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags);
|
void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type = MapType::FourKB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Virtual object
|
* @brief Construct a new Virtual object
|
||||||
|
Loading…
x
Reference in New Issue
Block a user