Initialize system PTE pools and implement reservation routines
This commit is contained in:
@@ -18,6 +18,11 @@ namespace MM
|
|||||||
class Pte
|
class Pte
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
|
||||||
|
STATIC PMMPTE SystemPteBase;
|
||||||
|
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
|
||||||
|
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
|
||||||
|
STATIC ULONG TotalSystemFreePtes[MaximumPtePoolTypes];
|
||||||
STATIC MMPTE ValidPte;
|
STATIC MMPTE ValidPte;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -25,6 +30,7 @@ namespace MM
|
|||||||
STATIC XTAPI ULONG GetPtesPerPage(VOID);
|
STATIC XTAPI ULONG GetPtesPerPage(VOID);
|
||||||
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
||||||
STATIC XTAPI VOID InitializePageTable(VOID);
|
STATIC XTAPI VOID InitializePageTable(VOID);
|
||||||
|
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
|
||||||
STATIC XTAPI VOID MapP5E(PVOID StartAddress,
|
STATIC XTAPI VOID MapP5E(PVOID StartAddress,
|
||||||
PVOID EndAddress,
|
PVOID EndAddress,
|
||||||
PMMP5E TemplateP5e);
|
PMMP5E TemplateP5e);
|
||||||
@@ -40,6 +46,19 @@ namespace MM
|
|||||||
STATIC XTAPI VOID MapPXE(PVOID StartAddress,
|
STATIC XTAPI VOID MapPXE(PVOID StartAddress,
|
||||||
PVOID EndAddress,
|
PVOID EndAddress,
|
||||||
PMMPXE TemplatePxe);
|
PMMPXE TemplatePxe);
|
||||||
|
STATIC XTAPI PMMPTE ReserveSystemPtes(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
IN ULONG Alignment);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTAPI BOOLEAN FindFreeCluster(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
OUT PMMPTE *FoundCluster,
|
||||||
|
OUT PMMPTE *PreviousClusterNode);
|
||||||
|
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
|
||||||
|
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
|
||||||
|
IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ namespace MM
|
|||||||
class Pte
|
class Pte
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
|
||||||
|
STATIC PMMPTE SystemPteBase;
|
||||||
|
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
|
||||||
|
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
|
||||||
|
STATIC ULONG TotalSystemFreePtes[MaximumPtePoolTypes];
|
||||||
STATIC MMPTE ValidPte;
|
STATIC MMPTE ValidPte;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -25,6 +30,7 @@ namespace MM
|
|||||||
STATIC XTAPI ULONG GetPtesPerPage(VOID);
|
STATIC XTAPI ULONG GetPtesPerPage(VOID);
|
||||||
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
||||||
STATIC XTAPI VOID InitializePageTable(VOID);
|
STATIC XTAPI VOID InitializePageTable(VOID);
|
||||||
|
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
|
||||||
STATIC XTAPI VOID MapPDE(PVOID StartAddress,
|
STATIC XTAPI VOID MapPDE(PVOID StartAddress,
|
||||||
PVOID EndAddress,
|
PVOID EndAddress,
|
||||||
PMMPDE TemplatePde);
|
PMMPDE TemplatePde);
|
||||||
@@ -34,6 +40,19 @@ namespace MM
|
|||||||
STATIC XTAPI VOID MapPTE(PVOID StartAddress,
|
STATIC XTAPI VOID MapPTE(PVOID StartAddress,
|
||||||
PVOID EndAddress,
|
PVOID EndAddress,
|
||||||
PMMPTE TemplatePte);
|
PMMPTE TemplatePte);
|
||||||
|
STATIC XTAPI PMMPTE ReserveSystemPtes(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
IN ULONG Alignment);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTAPI BOOLEAN FindFreeCluster(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
OUT PMMPTE *FoundCluster,
|
||||||
|
OUT PMMPTE *PreviousClusterNode);
|
||||||
|
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
|
||||||
|
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
|
||||||
|
IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,5 +57,20 @@ LOADER_MEMORY_DESCRIPTOR MM::Pfn::OriginalFreeDescriptor;
|
|||||||
/* Size of the PFN database in pages */
|
/* Size of the PFN database in pages */
|
||||||
PFN_NUMBER MM::Pfn::PfnDatabaseSize;
|
PFN_NUMBER MM::Pfn::PfnDatabaseSize;
|
||||||
|
|
||||||
|
/* Array of lists for available System PTEs, separated by pool type */
|
||||||
|
MMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes];
|
||||||
|
|
||||||
|
/* Virtual base address of the System PTE space */
|
||||||
|
PMMPTE MM::Pte::SystemPteBase;
|
||||||
|
|
||||||
|
/* End addresses for the System PTE ranges */
|
||||||
|
PMMPTE MM::Pte::SystemPtesEnd[MaximumPtePoolTypes];
|
||||||
|
|
||||||
|
/* Start addresses for the System PTE ranges */
|
||||||
|
PMMPTE MM::Pte::SystemPtesStart[MaximumPtePoolTypes];
|
||||||
|
|
||||||
|
/* Total count of available System PTEs */
|
||||||
|
ULONG MM::Pte::TotalSystemFreePtes[MaximumPtePoolTypes];
|
||||||
|
|
||||||
/* Template PTE entry containing standard flags for a valid, present kernel page */
|
/* Template PTE entry containing standard flags for a valid, present kernel page */
|
||||||
MMPTE MM::Pte::ValidPte = {MM_PTE_VALID|MM_PTE_EXECUTE_READWRITE|MM_PTE_DIRTY|MM_PTE_ACCESSED};
|
MMPTE MM::Pte::ValidPte = {MM_PTE_VALID|MM_PTE_EXECUTE_READWRITE|MM_PTE_DIRTY|MM_PTE_ACCESSED};
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ MM::Manager::InitializeMemoryManager(VOID)
|
|||||||
|
|
||||||
/* Initialize page table */
|
/* Initialize page table */
|
||||||
MM::Pte::InitializePageTable();
|
MM::Pte::InitializePageTable();
|
||||||
|
|
||||||
|
/* Initialize system PTE space */
|
||||||
|
MM::Pte::InitializeSystemPteSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,86 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a free cluster of system PTEs that can satisfy a given size.
|
||||||
|
*
|
||||||
|
* @param NumberOfPtes
|
||||||
|
* The number of contiguous PTEs required.
|
||||||
|
*
|
||||||
|
* @param SystemPtePoolType
|
||||||
|
* Specifies the system PTE pool to search within.
|
||||||
|
*
|
||||||
|
* @param FoundCluster
|
||||||
|
* On success, receives a pointer to the first PTE of the found cluster.
|
||||||
|
*
|
||||||
|
* @param PreviousClusterNode
|
||||||
|
* On success, receives a pointer to the list node that precedes the found cluster.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if a suitable cluster was found, FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
BOOLEAN
|
||||||
|
MM::Pte::FindFreeCluster(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
OUT PMMPTE *FoundCluster,
|
||||||
|
OUT PMMPTE *PreviousClusterNode)
|
||||||
|
{
|
||||||
|
PMMPTE CurrentCluster;
|
||||||
|
PMMPTE PreviousNode = &FirstSystemFreePte[SystemPtePoolType];
|
||||||
|
ULONG ClusterSize;
|
||||||
|
|
||||||
|
/* Find a free PTE cluster large enough for the request */
|
||||||
|
while(MM::Paging::GetNextEntry(PreviousNode) != MAXULONG)
|
||||||
|
{
|
||||||
|
/* Retrieve the cluster and its size */
|
||||||
|
CurrentCluster = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousNode));
|
||||||
|
ClusterSize = GetClusterSize(CurrentCluster);
|
||||||
|
|
||||||
|
/* Check if this cluster is large enough */
|
||||||
|
if(NumberOfPtes <= ClusterSize)
|
||||||
|
{
|
||||||
|
/* Found a suitable cluster */
|
||||||
|
*FoundCluster = CurrentCluster;
|
||||||
|
*PreviousClusterNode = PreviousNode;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This cluster is too small, check the next one */
|
||||||
|
PreviousNode = CurrentCluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No suitable cluster was found */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes and returns the size of a free PTE cluster.
|
||||||
|
*
|
||||||
|
* @param Pte
|
||||||
|
* Supplies a pointer to the first PTE of the free cluster to inspect.
|
||||||
|
*
|
||||||
|
* @return This routine returns the total number of contiguous PTEs in the free cluster.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::Pte::GetClusterSize(IN PMMPTE Pte)
|
||||||
|
{
|
||||||
|
/* A special flag in the first PTE indicates a free cluster of size one */
|
||||||
|
if(MM::Paging::GetOneEntry(Pte))
|
||||||
|
{
|
||||||
|
/* Flag is set, so the cluster size is 1 by definition */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For larger clusters, the size is encoded in the second PTE of the block */
|
||||||
|
Pte = MM::Paging::GetNextPte(Pte);
|
||||||
|
return MM::Paging::GetNextEntry(Pte);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the number of Page Table Entries (PTEs) that fit within a single page.
|
* Calculates the number of Page Table Entries (PTEs) that fit within a single page.
|
||||||
*
|
*
|
||||||
@@ -24,6 +104,86 @@ MM::Pte::GetPtesPerPage(VOID)
|
|||||||
return MM_PAGE_SIZE / MM::Paging::GetPteSize();
|
return MM_PAGE_SIZE / MM::Paging::GetPteSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a range of PTEs into a freelist-based pool for system allocations.
|
||||||
|
*
|
||||||
|
* @param StartingPte
|
||||||
|
* Supplies a pointer to the start of the PTE range to be formatted.
|
||||||
|
*
|
||||||
|
* @param NumberOfPtes
|
||||||
|
* Supplies the total number of PTEs in the contiguous range.
|
||||||
|
*
|
||||||
|
* @param PoolType
|
||||||
|
* The system PTE pool type that this range will be used for.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Pte::InitializeSystemPtePool(IN PMMPTE StartingPte,
|
||||||
|
IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE PoolType)
|
||||||
|
{
|
||||||
|
/* Set the system PTE base address */
|
||||||
|
SystemPteBase = GetSystemPteBaseAddress();
|
||||||
|
|
||||||
|
/* Record the boundaries of this new PTE pool */
|
||||||
|
SystemPtesStart[PoolType] = StartingPte;
|
||||||
|
SystemPtesEnd[PoolType] = MM::Paging::AdvancePte(StartingPte, NumberOfPtes - 1);
|
||||||
|
|
||||||
|
/* Zero the memory for the new PTE pool before use */
|
||||||
|
RTL::Memory::ZeroMemory(StartingPte, NumberOfPtes * MM::Paging::GetPteSize());
|
||||||
|
|
||||||
|
/* Build the free list head to point to the start of the pool */
|
||||||
|
MM::Paging::SetNextEntry(StartingPte, MAXULONG);
|
||||||
|
MM::Paging::ClearPte(&FirstSystemFreePte[PoolType]);
|
||||||
|
MM::Paging::SetNextEntry(&FirstSystemFreePte[PoolType], MM::Paging::GetPteDistance(StartingPte, SystemPteBase));
|
||||||
|
|
||||||
|
/* Use the second PTE slot to store the total size of this pool */
|
||||||
|
StartingPte = MM::Paging::GetNextPte(StartingPte);
|
||||||
|
MM::Paging::ClearPte(StartingPte);
|
||||||
|
MM::Paging::SetNextEntry(StartingPte, NumberOfPtes);
|
||||||
|
|
||||||
|
/* Record the total number of free PTEs in this pool */
|
||||||
|
TotalSystemFreePtes[PoolType] = NumberOfPtes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the entire system PTE address space.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Pte::InitializeSystemPteSpace(VOID)
|
||||||
|
{
|
||||||
|
PMMPTE PointerPte;
|
||||||
|
PMMPTE FirstZeroingPte;
|
||||||
|
PMMMEMORY_LAYOUT MemoryLayout;
|
||||||
|
|
||||||
|
/* Retrieve the system's memory layout */
|
||||||
|
MemoryLayout = MM::Manager::GetMemoryLayout();
|
||||||
|
|
||||||
|
/* Map the page table hierarchy for the entire system PTE space */
|
||||||
|
MM::Pte::MapPPE(MemoryLayout->SystemSpaceStart, MemoryLayout->SystemSpaceEnd, &ValidPte);
|
||||||
|
MM::Pte::MapPDE(MemoryLayout->SystemSpaceStart, MemoryLayout->SystemSpaceEnd, &ValidPte);
|
||||||
|
|
||||||
|
/* Format the main block of system PTEs into a free list pool */
|
||||||
|
PointerPte = MM::Paging::GetPteAddress(MemoryLayout->SystemSpaceStart);
|
||||||
|
InitializeSystemPtePool(PointerPte, MM::Manager::GetNumberOfSystemPtes(), SystemPteSpace);
|
||||||
|
|
||||||
|
/* Reserve and zero a dedicated block of system PTEs */
|
||||||
|
FirstZeroingPte = ReserveSystemPtes(MM_RESERVED_ZERO_PTES + 1, SystemPteSpace, 0);
|
||||||
|
RTL::Memory::ZeroMemory(FirstZeroingPte, (MM_RESERVED_ZERO_PTES + 1) * MM::Paging::GetPteSize());
|
||||||
|
|
||||||
|
/* Use the first PTE of this block as a counter for available zeroing PTEs */
|
||||||
|
MM::Paging::SetPte(FirstZeroingPte, MM_RESERVED_ZERO_PTES, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a range of virtual addresses at the PDE (Page Directory Entry) level.
|
* Maps a range of virtual addresses at the PDE (Page Directory Entry) level.
|
||||||
*
|
*
|
||||||
@@ -117,3 +277,119 @@ MM::Pte::MapPTE(PVOID StartAddress,
|
|||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserves a contiguous block of system PTEs from a specified pool.
|
||||||
|
*
|
||||||
|
* @param NumberOfPtes
|
||||||
|
* The number of contiguous PTEs to reserve.
|
||||||
|
*
|
||||||
|
* @param SystemPtePoolType
|
||||||
|
* Specifies the system PTE pool from which to allocate.
|
||||||
|
*
|
||||||
|
* @param Alignment
|
||||||
|
* This parameter is currently unused.
|
||||||
|
*
|
||||||
|
* @return This routine returns a pointer to the beginning of the reserved block,
|
||||||
|
* or NULLPTR if not enough contiguous PTEs are available.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PMMPTE
|
||||||
|
MM::Pte::ReserveSystemPtes(IN ULONG NumberOfPtes,
|
||||||
|
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
||||||
|
IN ULONG Alignment)
|
||||||
|
{
|
||||||
|
PMMPTE PreviousPte, NextPte, ReservedPte;
|
||||||
|
ULONG ClusterSize;
|
||||||
|
|
||||||
|
/* Raise runlevel and acquire lock to protect the PTE pool */
|
||||||
|
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
||||||
|
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
||||||
|
|
||||||
|
/* Find a free PTE cluster large enough for the request */
|
||||||
|
if(!FindFreeCluster(NumberOfPtes, SystemPtePoolType, &NextPte, &PreviousPte))
|
||||||
|
{
|
||||||
|
/* Out of system PTEs for this pool, return NULLPTR */
|
||||||
|
return NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have the cluster, now get its size for the allocation logic below */
|
||||||
|
ClusterSize = GetClusterSize(NextPte);
|
||||||
|
|
||||||
|
/* Unlink the found cluster from the free list for processing */
|
||||||
|
MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetNextEntry(NextPte));
|
||||||
|
|
||||||
|
/* Handle the allocation based on whether the cluster size is an exact match */
|
||||||
|
if(ClusterSize == NumberOfPtes)
|
||||||
|
{
|
||||||
|
/* Exact match, allocate the entire cluster */
|
||||||
|
ReservedPte = NextPte;
|
||||||
|
|
||||||
|
/* Handle metadata cleanup for a single-PTE cluster */
|
||||||
|
if(MM::Paging::GetOneEntry(NextPte))
|
||||||
|
{
|
||||||
|
/* Clear the PTE that held the list metadata */
|
||||||
|
MM::Paging::ClearPte(NextPte);
|
||||||
|
NextPte = MM::Paging::GetNextPte(NextPte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the PTE that held the cluster size */
|
||||||
|
MM::Paging::ClearPte(NextPte);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Cluster is larger than needed, so it will be split */
|
||||||
|
ClusterSize -= NumberOfPtes;
|
||||||
|
ReservedPte = MM::Paging::AdvancePte(NextPte, ClusterSize);
|
||||||
|
|
||||||
|
/* Update metadata for the new, smaller leftover cluster */
|
||||||
|
if(ClusterSize == 1)
|
||||||
|
{
|
||||||
|
/* The leftover fragment is a single PTE */
|
||||||
|
MM::Paging::SetOneEntry(NextPte, 1);
|
||||||
|
MM::Paging::ClearPte(ReservedPte);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The leftover fragment is larger than one PTE */
|
||||||
|
NextPte = MM::Paging::GetNextPte(NextPte);
|
||||||
|
MM::Paging::SetNextEntry(NextPte, ClusterSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the correct sorted position to re-insert the leftover fragment */
|
||||||
|
PreviousPte = &FirstSystemFreePte[SystemPtePoolType];
|
||||||
|
while(MM::Paging::GetNextEntry(PreviousPte) != MAXULONG)
|
||||||
|
{
|
||||||
|
/* Get the next free cluster to check its size */
|
||||||
|
NextPte = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousPte));
|
||||||
|
|
||||||
|
/* Check if the leftover fragment should be inserted here */
|
||||||
|
if(ClusterSize <= GetClusterSize(NextPte))
|
||||||
|
{
|
||||||
|
/* Found the correct sorted position */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next entry */
|
||||||
|
PreviousPte = NextPte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a pointer to the start of the leftover fragment */
|
||||||
|
NextPte = MM::Paging::AdvancePte(ReservedPte, -ClusterSize);
|
||||||
|
|
||||||
|
/* Insert the leftover fragment back into the free list at its sorted position */
|
||||||
|
MM::Paging::SetNextEntry(NextPte, MM::Paging::GetNextEntry(PreviousPte));
|
||||||
|
MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetPteDistance(NextPte, SystemPteBase));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement the total number of available PTEs in this pool */
|
||||||
|
TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes;
|
||||||
|
|
||||||
|
/* Flush the TLB to ensure address translation consistency */
|
||||||
|
AR::CpuFunc::FlushTlb();
|
||||||
|
|
||||||
|
/* Return a pointer to the start of the reserved PTE block */
|
||||||
|
return ReservedPte;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user