New dynamic paging implementation (3) #67

This commit is contained in:
Adrien Bourmault 2020-01-09 22:34:38 +01:00
parent ad5b70b08a
commit 334e1bbae5
1 changed files with 52 additions and 36 deletions

View File

@ -36,6 +36,8 @@ enum
NX = 1UL << 63 NX = 1UL << 63
}; };
//-----------
// //
// Creates our new page table structure and loads it // Creates our new page table structure and loads it
// //
@ -177,26 +179,38 @@ void MmInitPaging(void)
DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr)/MB); DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr)/MB);
} }
//
// Get a page from an address
//
static pte_t MmGetPageDescriptor(void *virtualAddr)
{
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
if (virtAddrPage > MmVirtLastAddress) {
KeStartPanic("MmSetPage() Out of bound of the address space !");
}
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pdp\t: %p\n", pdp);
pde_t *pd = (pde_t*)( (ulong)pdp[(virtAddrPage / ((ulong)KPAGESIZE * 0x40000)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pd\t: %p\n", pd);
pte_t *pt = (pte_t*)( (ulong)pd[(virtAddrPage / ((ulong)KPAGESIZE * 0x200)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pt\t: %p\n", pt);
ulong page = (ulong)pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
//DebugLog("page (with flags): %p\n", page);
return page;
}
// //
// Translates a virtual address to its physical equivalent // Translates a virtual address to its physical equivalent
// //
void *MmTransVirtToPhyAddr(void* virtualAddr) void *MmTransVirtToPhyAddr(void* virtualAddr)
{ {
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1)); ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
pte_t page = MmGetPageDescriptor(virtualAddr);
if (virtAddrPage > MmVirtLastAddress) {
KeStartPanic("MmTransVirtToPhyAddr() Out of bound of the address space !");
}
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
DebugLog("pdp\t: %p\n", pdp);
pde_t *pd = (pde_t*)( (ulong)pdp[(virtAddrPage / ((ulong)KPAGESIZE * 0x40000)) % 512] & ~(KPAGESIZE - 1));
DebugLog("pd\t: %p\n", pd);
pte_t *pt = (pte_t*)( (ulong)pd[(virtAddrPage / ((ulong)KPAGESIZE * 0x200)) % 512] & ~(KPAGESIZE - 1));
DebugLog("pt\t: %p\n", pt);
ulong page = (ulong)pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
DebugLog("page (with flags): %p\n", page);
if (page == (page & ~(KPAGESIZE - 1))) { if (page == (page & ~(KPAGESIZE - 1))) {
return NULL; return NULL;
@ -215,19 +229,11 @@ void *MmTransPhyToVirtAddr(void* physicalAddr)
// //
void MmSetPage(void* virtualAddr, ulong flags) void MmSetPage(void* virtualAddr, ulong flags)
{ {
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1)); pte_t page = MmGetPageDescriptor(virtualAddr);
if (virtAddrPage > MmVirtLastAddress) { page |= flags;
KeStartPanic("MmSetPage() Out of bound of the address space !");
}
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)] & ~(KPAGESIZE - 1)); KeFlushTlbSingle(page);
pde_t *pd = (pde_t*)( (ulong)pdp[virtAddrPage / ((ulong)KPAGESIZE * 0x40000)] & ~(KPAGESIZE - 1));
pte_t *pt = (pte_t*)( (ulong)pd[virtAddrPage / ((ulong)KPAGESIZE * 0x200)] & ~(KPAGESIZE - 1));
pt[virtAddrPage / ((ulong)KPAGESIZE)] |= flags;
KeFlushTlbSingle(virtAddrPage);
} }
// //
@ -235,21 +241,31 @@ void MmSetPage(void* virtualAddr, ulong flags)
// //
void MmUnsetPage(void* virtualAddr, ulong flags) void MmUnsetPage(void* virtualAddr, ulong flags)
{ {
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1)); pte_t page = MmGetPageDescriptor(virtualAddr);
if (virtAddrPage > MmVirtLastAddress) { page &= (~flags);
KeStartPanic("MmUnsetPage() Out of bound of the address space !");
}
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)] & ~(KPAGESIZE - 1)); KeFlushTlbSingle(page);
pde_t *pd = (pde_t*)( (ulong)pdp[virtAddrPage / ((ulong)KPAGESIZE * 0x40000)] & ~(KPAGESIZE - 1));
pte_t *pt = (pte_t*)( (ulong)pd[virtAddrPage / ((ulong)KPAGESIZE * 0x200)] & ~(KPAGESIZE - 1));
pt[virtAddrPage / ((ulong)KPAGESIZE)] &= (~flags);
KeFlushTlbSingle(virtAddrPage);
} }
//
// Map a page in memory
//
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
{
}
//
// Unmap a page in memory
//
void MmUnmapPage(void* virtualAddr)
{
}
//-----------
// //
// Returns the rank of the Stack Guards // Returns the rank of the Stack Guards
// //