Implement unified PTE accessors and management helpers
This commit is contained in:
@@ -21,14 +21,35 @@ namespace MM
|
||||
MMPAGEMAP_INFO PageMapInfo;
|
||||
|
||||
public:
|
||||
XTAPI PMMPTE AdvancePte(PMMPTE Pte,
|
||||
ULONG Count);
|
||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||
XTAPI ULONGLONG GetEmptyPteList(VOID);
|
||||
XTAPI ULONG_PTR GetNextEntry(PMMPTE Pte);
|
||||
XTAPI PMMPTE GetNextPte(PMMPTE Pte);
|
||||
XTAPI BOOLEAN GetOneEntry(PMMPTE Pte);
|
||||
XTAPI PMMP5E GetP5eAddress(PVOID Address);
|
||||
XTAPI ULONG GetP5eIndex(PVOID Address);
|
||||
XTAPI PVOID GetP5eVirtualAddress(PMMP5E P5ePointer);
|
||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||
XTAPI ULONG GetPdeIndex(PVOID Address);
|
||||
XTAPI PVOID GetPdeVirtualAddress(PMMPDE PdePointer);
|
||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||
XTAPI ULONG GetPpeIndex(PVOID Address);
|
||||
XTAPI PVOID GetPpeVirtualAddress(PMMPPE PpePointer);
|
||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||
XTAPI ULONG GetPteIndex(PVOID Address);
|
||||
XTAPI ULONG GetPteSize(VOID);
|
||||
XTAPI PVOID GetPteVirtualAddress(PMMPTE PtePointer);
|
||||
XTAPI PMMPXE GetPxeAddress(PVOID Address);
|
||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
XTAPI ULONG GetPxeIndex(PVOID Address);
|
||||
XTAPI PVOID GetPxeVirtualAddress(PMMPXE PxePointer);
|
||||
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value);
|
||||
XTAPI VOID SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
|
||||
@@ -21,16 +21,33 @@ namespace MM
|
||||
MMPAGEMAP_INFO PageMapInfo;
|
||||
|
||||
public:
|
||||
VIRTUAL XTAPI PMMPTE AdvancePte(PMMPTE Pte,
|
||||
ULONG Count) = 0;
|
||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||
XTAPI ULONG GetEmptyPteList(VOID);
|
||||
VIRTUAL XTAPI ULONG_PTR GetNextEntry(PMMPTE Pte) = 0;
|
||||
VIRTUAL XTAPI PMMPTE GetNextPte(PMMPTE Pte) = 0;
|
||||
VIRTUAL XTAPI BOOLEAN GetOneEntry(PMMPTE Pte) = 0;
|
||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||
XTAPI ULONG GetPdeIndex(PVOID Address);
|
||||
XTAPI PVOID GetPdeVirtualAddress(PMMPDE PdePointer);
|
||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||
XTAPI ULONG GetPpeIndex(PVOID Address);
|
||||
XTAPI PVOID GetPpeVirtualAddress(PMMPPE PpePointer);
|
||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
|
||||
virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
XTAPI ULONG GetPteIndex(PVOID Address);
|
||||
VIRTUAL XTAPI ULONG GetPteSize(VOID) = 0;
|
||||
XTAPI PVOID GetPteVirtualAddress(PMMPTE PtePointer);
|
||||
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
VIRTUAL XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
|
||||
VIRTUAL XTAPI VOID SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value) = 0;
|
||||
VIRTUAL XTAPI VOID SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value) = 0;
|
||||
VIRTUAL XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable) = 0;
|
||||
virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
VIRTUAL XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough) = 0;
|
||||
} PAGEMAP, *PPAGEMAP;
|
||||
@@ -38,8 +55,18 @@ namespace MM
|
||||
class PageMapBasic final : public PageMap
|
||||
{
|
||||
public:
|
||||
XTAPI PMMPTE AdvancePte(PMMPTE Pte,
|
||||
ULONG Count);
|
||||
XTAPI ULONG_PTR GetNextEntry(PMMPTE Pte);
|
||||
XTAPI PMMPTE GetNextPte(PMMPTE Pte);
|
||||
XTAPI BOOLEAN GetOneEntry(PMMPTE Pte);
|
||||
XTAPI ULONG GetPteSize(VOID);
|
||||
XTAPI VOID InitializePageMapInfo(VOID);
|
||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value);
|
||||
XTAPI VOID SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
@@ -51,8 +78,18 @@ namespace MM
|
||||
class PageMapXpa final : public PageMap
|
||||
{
|
||||
public:
|
||||
XTAPI PMMPTE AdvancePte(PMMPTE Pte,
|
||||
ULONG Count);
|
||||
XTAPI ULONG_PTR GetNextEntry(PMMPTE Pte);
|
||||
XTAPI PMMPTE GetNextPte(PMMPTE Pte);
|
||||
XTAPI BOOLEAN GetOneEntry(PMMPTE Pte);
|
||||
XTAPI ULONG GetPteSize(VOID);
|
||||
XTAPI VOID InitializePageMapInfo(VOID);
|
||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value);
|
||||
XTAPI VOID SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
|
||||
@@ -9,6 +9,27 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer by a given number of entries, considering the actual PTE size.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMap::AdvancePte(PMMPTE Pte,
|
||||
ULONG Count)
|
||||
{
|
||||
return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPTE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of a page table entry (PTE).
|
||||
*
|
||||
@@ -23,6 +44,7 @@ XTAPI
|
||||
VOID
|
||||
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||
{
|
||||
/* Clear PTE */
|
||||
PtePointer->CacheDisable = 0;
|
||||
PtePointer->PageFrameNumber = 0;
|
||||
PtePointer->Valid = 0;
|
||||
@@ -30,6 +52,75 @@ MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||
PtePointer->WriteThrough = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value representing an empty PTE list.
|
||||
*
|
||||
* @return This routine returns the value representing an empty PTE list.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONGLONG
|
||||
MM::PageMap::GetEmptyPteList(VOID)
|
||||
{
|
||||
/* Return empty PTE list mask */
|
||||
return PageMapInfo.EmptyPteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to get the next entry from.
|
||||
*
|
||||
* @return This routine returns the next entry in the PTE list.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG_PTR
|
||||
MM::PageMap::GetNextEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return next entry in PTE list */
|
||||
return Pte->List.NextEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer, considering the actual PTE size.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMap::GetNextPte(PMMPTE Pte)
|
||||
{
|
||||
/* Return advanced PTE pointer */
|
||||
return AdvancePte(Pte, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to check.
|
||||
*
|
||||
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMap::GetOneEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return one entry status */
|
||||
return Pte->List.OneEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.
|
||||
*
|
||||
@@ -51,6 +142,40 @@ MM::PageMap::GetP5eAddress(PVOID Address)
|
||||
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the P5E (Page Map Level 5 Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding P5E.
|
||||
*
|
||||
* @return This routine returns the index of the P5E, or NULLPTR if LA57 is not enabled.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetP5eIndex(PVOID Address)
|
||||
{
|
||||
return (((((ULONGLONG)Address) >> MM_P5I_SHIFT) & 0x1FF) * PageMapInfo.Xpa);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
|
||||
*
|
||||
* @param P5ePointer
|
||||
* Specifies the address of the P5E.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetP5eVirtualAddress(PMMP5E P5ePointer)
|
||||
{
|
||||
return (PVOID)((((LONGLONG)P5ePointer << 61) >> 16) * PageMapInfo.Xpa);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
||||
*
|
||||
@@ -73,11 +198,47 @@ MM::PageMap::GetPdeAddress(PVOID Address)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
* Gets the index of the PDE (Page Directory Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PDE.
|
||||
*
|
||||
* @return This routine returns the index of the PDE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPdeIndex(PVOID Address)
|
||||
{
|
||||
/* Return PDE index */
|
||||
return ((((ULONGLONG)Address) >> MM_PDI_SHIFT) & 0x1FF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Directory Entry.
|
||||
*
|
||||
* @param PdePointer
|
||||
* Specifies the address of the PDE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PDE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPdeVirtualAddress(PMMPDE PdePointer)
|
||||
{
|
||||
/* Return PDE virtual address */
|
||||
return (PVOID)(((LONGLONG)PdePointer << 34) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
||||
*
|
||||
* @return This routine returns the address of the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
@@ -93,6 +254,42 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
||||
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
||||
*
|
||||
* @return This routine returns the index of the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPpeIndex(PVOID Address)
|
||||
{
|
||||
/* Return PPE index */
|
||||
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry.
|
||||
*
|
||||
* @param PpePointer
|
||||
* Specifies the address of the PPE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPpeVirtualAddress(PMMPPE PpePointer)
|
||||
{
|
||||
/* Return PPE virtual address */
|
||||
return (PVOID)(((LONGLONG)PpePointer << 43) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||
*
|
||||
@@ -114,6 +311,57 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
||||
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PTE (Page Table Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PTE.
|
||||
*
|
||||
* @return This routine returns the index of the PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPteIndex(PVOID Address)
|
||||
{
|
||||
/* Return PTE index */
|
||||
return ((((ULONGLONG)Address) >> MM_PTI_SHIFT) & 0x1FF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of a PTE.
|
||||
*
|
||||
* @return This routine returns the size of a PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPteSize(VOID)
|
||||
{
|
||||
/* Return the size of MMPTE */
|
||||
return sizeof(MMPTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Table Entry.
|
||||
*
|
||||
* @param PtePointer
|
||||
* Specifies the address of the PTE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPteVirtualAddress(PMMPTE PtePointer)
|
||||
{
|
||||
/* Return PTE virtual address */
|
||||
return (PVOID)(((LONGLONG)PtePointer << 25) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
||||
*
|
||||
@@ -130,10 +378,47 @@ MM::PageMap::GetPxeAddress(PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
/* Calculate offset and return PXE address */
|
||||
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
||||
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PXE (Extended Page Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PXE.
|
||||
*
|
||||
* @return This routine returns the index of the PXE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPxeIndex(PVOID Address)
|
||||
{
|
||||
/* Return PXE index */
|
||||
return ((((ULONGLONG)Address) >> MM_PXI_SHIFT) & 0x1FF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Extended Page Entry.
|
||||
*
|
||||
* @param PxePointer
|
||||
* Specifies the address of the PXE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PXE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPxeVirtualAddress(PMMPXE PxePointer)
|
||||
{
|
||||
/* Return PXE virtual address */
|
||||
return (PVOID)(((LONGLONG)PxePointer << 52) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given PML2 page table entry (PTE) is valid.
|
||||
*
|
||||
@@ -148,9 +433,54 @@ XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
|
||||
{
|
||||
/* Check if PTE is valid */
|
||||
return (BOOLEAN)PtePointer->Valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set as the next entry.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMap::SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value)
|
||||
{
|
||||
/* Set next entry in PTE list */
|
||||
Pte->List.NextEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag indicating whether a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMap::SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value)
|
||||
{
|
||||
/* Set one entry status */
|
||||
Pte->List.OneEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
||||
*
|
||||
@@ -173,6 +503,7 @@ MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable)
|
||||
{
|
||||
/* Set PTE */
|
||||
PtePointer->PageFrameNumber = PageFrameNumber;
|
||||
PtePointer->Valid = 1;
|
||||
PtePointer->Writable = Writable;
|
||||
@@ -200,6 +531,7 @@ MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough)
|
||||
{
|
||||
/* Set caching attributes */
|
||||
PtePointer->CacheDisable = CacheDisable;
|
||||
PtePointer->WriteThrough = WriteThrough;
|
||||
}
|
||||
@@ -218,6 +550,9 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
|
||||
/* Set PML4 page map information */
|
||||
PageMapInfo.Xpa = FALSE;
|
||||
|
||||
/* Set PML4 empty PTE list mask */
|
||||
PageMapInfo.EmptyPteList = 0xFFFFFFFFUI64;
|
||||
|
||||
/* Set PML4 base addresses */
|
||||
PageMapInfo.PteBase = MM_PTE_BASE;
|
||||
PageMapInfo.PdeBase = MM_PDE_BASE;
|
||||
@@ -243,6 +578,9 @@ MM::PageMapXpa::InitializePageMapInfo(VOID)
|
||||
/* Set PML5 page map information */
|
||||
PageMapInfo.Xpa = TRUE;
|
||||
|
||||
/* Set PML5 empty PTE list mask */
|
||||
PageMapInfo.EmptyPteList = 0xFFFFFFFFUI64;
|
||||
|
||||
/* Set PML5 base addresses */
|
||||
PageMapInfo.PteBase = MM_PTE_LA57_BASE;
|
||||
PageMapInfo.PdeBase = MM_PDE_LA57_BASE;
|
||||
|
||||
@@ -23,9 +23,25 @@ XTAPI
|
||||
VOID
|
||||
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||
{
|
||||
/* Clear PTE */
|
||||
PtePointer->Long = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value representing an empty PTE list.
|
||||
*
|
||||
* @return This routine returns the value representing an empty PTE list.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetEmptyPteList(VOID)
|
||||
{
|
||||
/* Return empty PTE list mask */
|
||||
return PageMapInfo.EmptyPteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
||||
*
|
||||
@@ -47,6 +63,42 @@ MM::PageMap::GetPdeAddress(PVOID Address)
|
||||
return (PMMPDE)(PageMapInfo.PdeBase + Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PDE (Page Directory Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PDE.
|
||||
*
|
||||
* @return This routine returns the index of the PDE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPdeIndex(PVOID Address)
|
||||
{
|
||||
/* Return PDE index */
|
||||
return ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Directory Entry.
|
||||
*
|
||||
* @param PdePointer
|
||||
* Specifies the address of the PDE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PDE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPdeVirtualAddress(PMMPDE PdePointer)
|
||||
{
|
||||
/* Return PDE virtual address */
|
||||
return ((PVOID)((ULONG)(PdePointer) << 20));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
*
|
||||
@@ -65,6 +117,42 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
||||
return (PMMPPE)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
||||
*
|
||||
* @return This routine returns the index of the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPpeIndex(PVOID Address)
|
||||
{
|
||||
/* Return PPE index */
|
||||
return ((((ULONG_PTR)(Address)) >> MM_PPI_SHIFT) & 0x3) * PageMapInfo.Xpa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry.
|
||||
*
|
||||
* @param PpePointer
|
||||
* Specifies the virtual address of the PPE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPpeVirtualAddress(PMMPPE PpePointer)
|
||||
{
|
||||
/* Return PPE virtual address */
|
||||
return (PVOID)((ULONG)(PpePointer) << 30);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||
*
|
||||
@@ -86,6 +174,133 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
||||
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the PTE (Page Table Entry), that maps given address.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PTE.
|
||||
*
|
||||
* @return This routine returns the index of the PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMap::GetPteIndex(PVOID Address)
|
||||
{
|
||||
/* Return PTE index */
|
||||
return ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual address that is mapped by a given Page Table Entry.
|
||||
*
|
||||
* @param PtePointer
|
||||
* Specifies the virtual address of the PTE.
|
||||
*
|
||||
* @return This routine returns the virtual address mapped by the PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
MM::PageMap::GetPteVirtualAddress(PMMPTE PtePointer)
|
||||
{
|
||||
/* Return PTE virtual address */
|
||||
return ((PVOID)((ULONG)(PtePointer) << 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer by a given number of entries, considering the actual PTE size for PML2.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMapBasic::AdvancePte(PMMPTE Pte,
|
||||
ULONG Count)
|
||||
{
|
||||
/* Return advanced PTE pointer */
|
||||
return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPML2_PTE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to get the next entry from.
|
||||
*
|
||||
* @return This routine returns the next entry in the PTE list.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG_PTR
|
||||
MM::PageMapBasic::GetNextEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return next entry in PTE list */
|
||||
return Pte->Pml2.List.NextEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer, considering the actual PTE size for PML2.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMapBasic::GetNextPte(PMMPTE Pte)
|
||||
{
|
||||
/* Return advanced PTE pointer */
|
||||
return AdvancePte(Pte, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to check.
|
||||
*
|
||||
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMapBasic::GetOneEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return one entry status */
|
||||
return Pte->Pml2.List.OneEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of a PTE for basic paging (PML2).
|
||||
*
|
||||
* @return This routine returns the size of a PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMapBasic::GetPteSize(VOID)
|
||||
{
|
||||
/* Return the size of MMPTE */
|
||||
return sizeof(MMPML2_PTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes page map information for basic paging (PML2).
|
||||
*
|
||||
@@ -100,6 +315,9 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
|
||||
/* Set PML2 page map information */
|
||||
PageMapInfo.Xpa = FALSE;
|
||||
|
||||
/* Set PML2 empty PTE list mask */
|
||||
PageMapInfo.EmptyPteList = (ULONG)0xFFFFF;
|
||||
|
||||
/* Set PML2 base addresses */
|
||||
PageMapInfo.PteBase = MM_PTE_BASE;
|
||||
PageMapInfo.PdeBase = MM_PDE_LEGACY_BASE;
|
||||
@@ -123,9 +341,54 @@ XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMapBasic::PteValid(PHARDWARE_PTE PtePointer)
|
||||
{
|
||||
/* Check if PTE is valid */
|
||||
return (BOOLEAN)PtePointer->Pml2.Valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set as the next entry.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMapBasic::SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value)
|
||||
{
|
||||
/* Set next entry in PTE list */
|
||||
Pte->Pml2.List.NextEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag indicating whether a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMapBasic::SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value)
|
||||
{
|
||||
/* Set one entry status */
|
||||
Pte->Pml2.List.OneEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
||||
*
|
||||
@@ -148,6 +411,7 @@ MM::PageMapBasic::SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable)
|
||||
{
|
||||
/* Set PTE */
|
||||
PtePointer->Pml2.PageFrameNumber = PageFrameNumber;
|
||||
PtePointer->Pml2.Valid = 1;
|
||||
PtePointer->Pml2.Writable = Writable;
|
||||
@@ -175,10 +439,102 @@ MM::PageMapBasic::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough)
|
||||
{
|
||||
/* Set caching attributes */
|
||||
PtePointer->Pml2.CacheDisable = CacheDisable;
|
||||
PtePointer->Pml2.WriteThrough = WriteThrough;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer by a given number of entries, considering the actual PTE size for PML3.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMapXpa::AdvancePte(PMMPTE Pte,
|
||||
ULONG Count)
|
||||
{
|
||||
/* Return advanced PTE pointer */
|
||||
return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPML3_PTE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to get the next entry from.
|
||||
*
|
||||
* @return This routine returns the next entry in the PTE list.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG_PTR
|
||||
MM::PageMapXpa::GetNextEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return next entry in PTE list */
|
||||
return Pte->Pml3.List.NextEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a PTE pointer, considering the actual PTE size for PML3.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMapXpa::GetNextPte(PMMPTE Pte)
|
||||
{
|
||||
/* Return advanced PTE pointer */
|
||||
return AdvancePte(Pte, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to check.
|
||||
*
|
||||
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMapXpa::GetOneEntry(PMMPTE Pte)
|
||||
{
|
||||
/* Return one entry status */
|
||||
return Pte->Pml3.List.OneEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of a PTE for XPA paging (PML3).
|
||||
*
|
||||
* @return This routine returns the size of a PTE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG
|
||||
MM::PageMapXpa::GetPteSize(VOID)
|
||||
{
|
||||
/* Return the size of MMPTE */
|
||||
return sizeof(MMPML3_PTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes page map information for basic paging (PML3).
|
||||
*
|
||||
@@ -190,14 +546,17 @@ XTAPI
|
||||
VOID
|
||||
MM::PageMapXpa::InitializePageMapInfo(VOID)
|
||||
{
|
||||
/* Set PML2 page map information */
|
||||
/* Set PML3 page map information */
|
||||
PageMapInfo.Xpa = TRUE;
|
||||
|
||||
/* Set PML2 base addresses */
|
||||
/* Set PML3 empty PTE list mask */
|
||||
PageMapInfo.EmptyPteList = (ULONG)0xFFFFFFFF;
|
||||
|
||||
/* Set PML3 base addresses */
|
||||
PageMapInfo.PteBase = MM_PTE_BASE;
|
||||
PageMapInfo.PdeBase = MM_PDE_BASE;
|
||||
|
||||
/* Set PML2 shift values */
|
||||
/* Set PML3 shift values */
|
||||
PageMapInfo.PdiShift = MM_PDI_SHIFT;
|
||||
PageMapInfo.PteShift = MM_PTE_SHIFT;
|
||||
}
|
||||
@@ -219,6 +578,50 @@ MM::PageMapXpa::PteValid(PHARDWARE_PTE PtePointer)
|
||||
return (BOOLEAN)PtePointer->Pml3.Valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next entry in a PTE list.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set as the next entry.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMapXpa::SetNextEntry(PMMPTE Pte,
|
||||
ULONG_PTR Value)
|
||||
{
|
||||
/* Set next entry in PTE list */
|
||||
Pte->Pml3.List.NextEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag indicating whether a PTE list contains only one entry.
|
||||
*
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param Value
|
||||
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMapXpa::SetOneEntry(PMMPTE Pte,
|
||||
BOOLEAN Value)
|
||||
{
|
||||
/* Set one entry status */
|
||||
Pte->Pml3.List.OneEntry = Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a PML3 page table entry (PTE) with the specified physical page and access flags.
|
||||
*
|
||||
@@ -241,6 +644,7 @@ MM::PageMapXpa::SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable)
|
||||
{
|
||||
/* Set PTE */
|
||||
PtePointer->Pml3.PageFrameNumber = PageFrameNumber;
|
||||
PtePointer->Pml3.Valid = 1;
|
||||
PtePointer->Pml3.Writable = Writable;
|
||||
@@ -268,6 +672,7 @@ MM::PageMapXpa::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough)
|
||||
{
|
||||
/* Set caching attributes */
|
||||
PtePointer->Pml3.CacheDisable = CacheDisable;
|
||||
PtePointer->Pml3.WriteThrough = WriteThrough;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user