|
|
|
|
@@ -730,55 +730,6 @@ MM::Pfn::LinkPage(IN PMMPFNLIST ListHead,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initializes the PFN database entry for a physical page that is used as a page table.
|
|
|
|
|
*
|
|
|
|
|
* @param PageFrameIndex
|
|
|
|
|
* The page frame number of the physical page being used as a page table.
|
|
|
|
|
*
|
|
|
|
|
* @param PointerPte
|
|
|
|
|
* A pointer to the higher-level PTE that maps this page table page.
|
|
|
|
|
*
|
|
|
|
|
* @return This routine does not return any value.
|
|
|
|
|
*
|
|
|
|
|
* @since XT 1.0
|
|
|
|
|
*/
|
|
|
|
|
XTAPI
|
|
|
|
|
VOID
|
|
|
|
|
MM::Pfn::LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
IN PMMPTE PointerPte)
|
|
|
|
|
{
|
|
|
|
|
PMMPFN Pfn;
|
|
|
|
|
PMMPDE PointerPde;
|
|
|
|
|
PVOID EndAddress;
|
|
|
|
|
|
|
|
|
|
/* Retrieve the PFN database entry for the physical page of the page table */
|
|
|
|
|
Pfn = GetPfnEntry(PageFrameIndex);
|
|
|
|
|
|
|
|
|
|
/* Calculate the end address of the PFN entry to ensure it's mapped */
|
|
|
|
|
EndAddress = (PUCHAR)(Pfn + 1) - 1;
|
|
|
|
|
|
|
|
|
|
/* Validate that the PFN entry corresponds to a valid, active physical page */
|
|
|
|
|
if((PageFrameIndex <= HighestPhysicalPage) && (MM::Pte::AddressValid(Pfn)) &&
|
|
|
|
|
(MM::Pte::AddressValid(EndAddress)) && (Pfn->u3.e1.PageLocation == ActiveAndValid))
|
|
|
|
|
{
|
|
|
|
|
/* Initialize the PFN entry for this page table page */
|
|
|
|
|
Pfn->OriginalPte = *PointerPte;
|
|
|
|
|
Pfn->PteAddress = PointerPte;
|
|
|
|
|
Pfn->u1.WsIndex = 0;
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
|
|
|
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
|
|
|
Pfn->u3.e2.ReferenceCount = 1;
|
|
|
|
|
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(PointerPte));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Increment the share count of the parent page table that contains the mapping */
|
|
|
|
|
PointerPde = MM::Paging::GetPdeAddress(MM::Paging::GetPteVirtualAddress(PointerPte));
|
|
|
|
|
Pfn = GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPde));
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Links a PFN entry to its corresponding PTE and ensures the page table that contains the PTE is resident in memory.
|
|
|
|
|
*
|
|
|
|
|
@@ -797,7 +748,7 @@ MM::Pfn::LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
*/
|
|
|
|
|
XTAPI
|
|
|
|
|
VOID
|
|
|
|
|
MM::Pfn::LinkPfnToPte(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
MM::Pfn::LinkPfn(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
IN PMMPTE PointerPte,
|
|
|
|
|
IN BOOLEAN Modified)
|
|
|
|
|
{
|
|
|
|
|
@@ -857,6 +808,110 @@ MM::Pfn::LinkPfnToPte(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initializes the PFN database entry for a physical page that is used as a page table.
|
|
|
|
|
*
|
|
|
|
|
* @param PageFrameIndex
|
|
|
|
|
* The page frame number of the physical page being used as a page table.
|
|
|
|
|
*
|
|
|
|
|
* @param PointerPte
|
|
|
|
|
* A pointer to the higher-level PTE that maps this page table page.
|
|
|
|
|
*
|
|
|
|
|
* @return This routine does not return any value.
|
|
|
|
|
*
|
|
|
|
|
* @since XT 1.0
|
|
|
|
|
*/
|
|
|
|
|
XTAPI
|
|
|
|
|
VOID
|
|
|
|
|
MM::Pfn::LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
IN PMMPTE PointerPte)
|
|
|
|
|
{
|
|
|
|
|
PMMPFN Pfn;
|
|
|
|
|
PMMPDE PointerPde;
|
|
|
|
|
PVOID EndAddress;
|
|
|
|
|
|
|
|
|
|
/* Retrieve the PFN database entry for the physical page of the page table */
|
|
|
|
|
Pfn = GetPfnEntry(PageFrameIndex);
|
|
|
|
|
|
|
|
|
|
/* Calculate the end address of the PFN entry to ensure it's mapped */
|
|
|
|
|
EndAddress = (PUCHAR)(Pfn + 1) - 1;
|
|
|
|
|
|
|
|
|
|
/* Validate that the PFN entry corresponds to a valid, active physical page */
|
|
|
|
|
if((PageFrameIndex <= HighestPhysicalPage) && (MM::Pte::AddressValid(Pfn)) &&
|
|
|
|
|
(MM::Pte::AddressValid(EndAddress)) && (Pfn->u3.e1.PageLocation == ActiveAndValid))
|
|
|
|
|
{
|
|
|
|
|
/* Initialize the PFN entry for this page table page */
|
|
|
|
|
Pfn->OriginalPte = *PointerPte;
|
|
|
|
|
Pfn->PteAddress = PointerPte;
|
|
|
|
|
Pfn->u1.WsIndex = 0;
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
|
|
|
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
|
|
|
Pfn->u3.e2.ReferenceCount = 1;
|
|
|
|
|
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(PointerPte));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Increment the share count of the parent page table that contains the mapping */
|
|
|
|
|
PointerPde = MM::Paging::GetPdeAddress(MM::Paging::GetPteVirtualAddress(PointerPte));
|
|
|
|
|
Pfn = GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPde));
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Links a PFN entry to its corresponding PTE and ensures the page table that contains the PTE is resident in memory.
|
|
|
|
|
*
|
|
|
|
|
* @param PageFrameIndex
|
|
|
|
|
* Supplies the index into the PFN database for the page being initialized.
|
|
|
|
|
*
|
|
|
|
|
* @param PointerPte
|
|
|
|
|
* Supplies the pointer to the PTE which maps the physical page.
|
|
|
|
|
*
|
|
|
|
|
* @param ParentFrame
|
|
|
|
|
* Supplies the page frame number of the page table that contains the PTE.
|
|
|
|
|
*
|
|
|
|
|
* @return This routine does not return any value.
|
|
|
|
|
*
|
|
|
|
|
* @since XT 1.0
|
|
|
|
|
*/
|
|
|
|
|
XTAPI
|
|
|
|
|
VOID
|
|
|
|
|
MM::Pfn::LinkPfnWithParent(IN PFN_NUMBER PageFrameIndex,
|
|
|
|
|
IN PMMPTE PointerPte,
|
|
|
|
|
IN PFN_NUMBER ParentFrame)
|
|
|
|
|
{
|
|
|
|
|
PMMMEMORY_LAYOUT MemoryLayout;
|
|
|
|
|
PMMPFN Pfn;
|
|
|
|
|
|
|
|
|
|
/* Get the memory layout */
|
|
|
|
|
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
|
|
|
|
|
|
|
|
/* Point the PFN to its PTE */
|
|
|
|
|
Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];
|
|
|
|
|
Pfn->PteAddress = PointerPte;
|
|
|
|
|
|
|
|
|
|
/* Initialize the PTE */
|
|
|
|
|
MM::Paging::SetPte(&Pfn->OriginalPte, 0, MM_PTE_GUARDED);
|
|
|
|
|
|
|
|
|
|
/* Initialize the PFN entry */
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
Pfn->u3.e1.CacheAttribute = PfnCached;
|
|
|
|
|
Pfn->u3.e1.Modified = TRUE;
|
|
|
|
|
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
|
|
|
Pfn->u3.e2.ReferenceCount++;
|
|
|
|
|
Pfn->u4.InPageError = FALSE;
|
|
|
|
|
|
|
|
|
|
/* Check if parent PTE frame exists */
|
|
|
|
|
if(ParentFrame)
|
|
|
|
|
{
|
|
|
|
|
/* Link the page table to its parent */
|
|
|
|
|
Pfn->u4.PteFrame = ParentFrame;
|
|
|
|
|
|
|
|
|
|
/* Get the PFN entry for parent PTE and increment share count */
|
|
|
|
|
Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[ParentFrame];
|
|
|
|
|
Pfn->u2.ShareCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Links a page to the beginning of the appropriate standby or ROM list.
|
|
|
|
|
*
|
|
|
|
|
|