Deduplicate PFN descriptor processing logic across architectures
This commit is contained in:
@@ -260,125 +260,6 @@ MM::Pfn::InitializePageTablePfns(VOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes a memory descriptor and initializes the corresponding PFN database entries
|
|
||||||
*
|
|
||||||
* @param BasePage
|
|
||||||
* The starting physical page number of the memory run
|
|
||||||
*
|
|
||||||
* @param PageCount
|
|
||||||
* The number of pages in the memory run
|
|
||||||
*
|
|
||||||
* @param MemoryType
|
|
||||||
* The type of memory as reported by the bootloader (e.g., free, ROM, in-use)
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
|
|
||||||
IN PFN_NUMBER PageCount,
|
|
||||||
IN LOADER_MEMORY_TYPE MemoryType)
|
|
||||||
{
|
|
||||||
PVOID VirtualRangeStart, VirtualRangeEnd;
|
|
||||||
PFN_NUMBER PageNumber;
|
|
||||||
PMMPDE PointerPde;
|
|
||||||
PMMPFN Pfn;
|
|
||||||
|
|
||||||
/* Check if the memory descriptor describes a free memory region */
|
|
||||||
if(MM::Manager::VerifyMemoryTypeFree(MemoryType))
|
|
||||||
{
|
|
||||||
/* Iterate over each page in this free memory run */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current page and ensure it is not referenced */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Add the page to the free list to make it available for allocation */
|
|
||||||
LinkFreePage(BasePage + PageNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Calculate the virtual address range for this physical memory region */
|
|
||||||
VirtualRangeStart = (PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT));
|
|
||||||
VirtualRangeEnd = (PVOID)(KSEG0_BASE + ((BasePage + PageCount) << MM_PAGE_SHIFT));
|
|
||||||
|
|
||||||
/* Handle all other (non-free) memory types */
|
|
||||||
switch(MemoryType)
|
|
||||||
{
|
|
||||||
case LoaderBad:
|
|
||||||
/* This memory is marked as bad and should not be used */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Link the page to the bad pages list */
|
|
||||||
LinkPage(&BadPagesList, BasePage + PageNumber);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LoaderXIPRom:
|
|
||||||
/* Get the page directory entry for the current page */
|
|
||||||
PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);
|
|
||||||
|
|
||||||
/* Initialize the page directory entries covering this memory range */
|
|
||||||
InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));
|
|
||||||
|
|
||||||
/* This memory range contains Read-Only Memory (ROM) */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current ROM page */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
|
|
||||||
/* Ensure that the page is not already in-use */
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Initialize the PFN entry to represent a ROM page */
|
|
||||||
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
|
|
||||||
Pfn->u1.Flink = 0;
|
|
||||||
Pfn->u2.ShareCount = 0;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnCached;
|
|
||||||
Pfn->u3.e1.PageLocation = 0;
|
|
||||||
Pfn->u3.e1.PrototypePte = 1;
|
|
||||||
Pfn->u3.e1.Rom = 1;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 0;
|
|
||||||
Pfn->u4.InPageError = 0;
|
|
||||||
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Get the page directory entry for the current page */
|
|
||||||
PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);
|
|
||||||
|
|
||||||
/* Initialize the page directory entries covering this memory range */
|
|
||||||
InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));
|
|
||||||
|
|
||||||
/* All other types are considered in-use (ie, by the kernel, ACPI, etc) */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current in-use page */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
|
|
||||||
/* Ensure that the page is not already in-use */
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */
|
|
||||||
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
|
|
||||||
Pfn->u2.ShareCount++;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnCached;
|
|
||||||
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 1;
|
|
||||||
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively scans a page table to initialize PFN database entries for active pages.
|
* Recursively scans a page table to initialize PFN database entries for active pages.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -185,114 +185,6 @@ MM::Pfn::InitializePageTablePfns(VOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes a memory descriptor and initializes the corresponding PFN database entries
|
|
||||||
*
|
|
||||||
* @param BasePage
|
|
||||||
* The starting physical page number of the memory run
|
|
||||||
*
|
|
||||||
* @param PageCount
|
|
||||||
* The number of pages in the memory run
|
|
||||||
*
|
|
||||||
* @param MemoryType
|
|
||||||
* The type of memory as reported by the bootloader (e.g., free, ROM, in-use)
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
|
|
||||||
IN PFN_NUMBER PageCount,
|
|
||||||
IN LOADER_MEMORY_TYPE MemoryType)
|
|
||||||
{
|
|
||||||
PFN_NUMBER PageNumber;
|
|
||||||
PMMPDE PointerPde;
|
|
||||||
PMMPFN Pfn;
|
|
||||||
|
|
||||||
/* Check if the memory descriptor describes a free memory region */
|
|
||||||
if(MM::Manager::VerifyMemoryTypeFree(MemoryType))
|
|
||||||
{
|
|
||||||
/* Iterate over each page in this free memory run */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current page and ensure it is not referenced */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Add the page to the free list to make it available for allocation */
|
|
||||||
LinkFreePage(BasePage + PageNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Handle all other (non-free) memory types */
|
|
||||||
switch(MemoryType)
|
|
||||||
{
|
|
||||||
case LoaderBad:
|
|
||||||
/* This memory is marked as bad and should not be used */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Link the page to the bad pages list */
|
|
||||||
LinkPage(&BadPagesList, BasePage + PageNumber);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LoaderXIPRom:
|
|
||||||
/* This memory range contains Read-Only Memory (ROM) */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current ROM page */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
|
|
||||||
/* Ensure that the page is not already in-use */
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Get the page directory entry for the current page */
|
|
||||||
PointerPde = MM::Paging::GetPdeAddress((PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT)));
|
|
||||||
|
|
||||||
/* Initialize the PFN entry to represent a ROM page */
|
|
||||||
Pfn->PteAddress = MM::Paging::GetPteAddress((PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT)));
|
|
||||||
Pfn->u1.Flink = 0;
|
|
||||||
Pfn->u2.ShareCount = 0;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
||||||
Pfn->u3.e1.PageLocation = 0;
|
|
||||||
Pfn->u3.e1.PrototypePte = 1;
|
|
||||||
Pfn->u3.e1.Rom = 1;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 0;
|
|
||||||
Pfn->u4.InPageError = 0;
|
|
||||||
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* All other types are considered in-use (ie, by the kernel, ACPI, etc) */
|
|
||||||
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
|
||||||
{
|
|
||||||
/* Get the PFN entry for the current in-use page */
|
|
||||||
Pfn = GetPfnEntry(BasePage + PageNumber);
|
|
||||||
|
|
||||||
/* Ensure that the page is not already in-use */
|
|
||||||
if(Pfn->u3.e2.ReferenceCount == 0)
|
|
||||||
{
|
|
||||||
/* Get the page directory entry for the current page */
|
|
||||||
PointerPde = MM::Paging::GetPdeAddress((PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT)));
|
|
||||||
|
|
||||||
/* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */
|
|
||||||
Pfn->PteAddress = MM::Paging::GetPteAddress((PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT)));
|
|
||||||
Pfn->u2.ShareCount++;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
||||||
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 1;
|
|
||||||
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively scans a page table to initialize PFN database entries for active pages.
|
* Recursively scans a page table to initialize PFN database entries for active pages.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -942,6 +942,125 @@ MM::Pfn::LinkStandbyPage(IN PFN_NUMBER PageFrameIndex)
|
|||||||
IncrementAvailablePages();
|
IncrementAvailablePages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a memory descriptor and initializes the corresponding PFN database entries
|
||||||
|
*
|
||||||
|
* @param BasePage
|
||||||
|
* The starting physical page number of the memory run
|
||||||
|
*
|
||||||
|
* @param PageCount
|
||||||
|
* The number of pages in the memory run
|
||||||
|
*
|
||||||
|
* @param MemoryType
|
||||||
|
* The type of memory as reported by the bootloader (e.g., free, ROM, in-use)
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
|
||||||
|
IN PFN_NUMBER PageCount,
|
||||||
|
IN LOADER_MEMORY_TYPE MemoryType)
|
||||||
|
{
|
||||||
|
PVOID VirtualRangeStart, VirtualRangeEnd;
|
||||||
|
PFN_NUMBER PageNumber;
|
||||||
|
PMMPDE PointerPde;
|
||||||
|
PMMPFN Pfn;
|
||||||
|
|
||||||
|
/* Check if the memory descriptor describes a free memory region */
|
||||||
|
if(MM::Manager::VerifyMemoryTypeFree(MemoryType))
|
||||||
|
{
|
||||||
|
/* Iterate over each page in this free memory run */
|
||||||
|
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
||||||
|
{
|
||||||
|
/* Get the PFN entry for the current page and ensure it is not referenced */
|
||||||
|
Pfn = GetPfnEntry(BasePage + PageNumber);
|
||||||
|
if(Pfn->u3.e2.ReferenceCount == 0)
|
||||||
|
{
|
||||||
|
/* Add the page to the free list to make it available for allocation */
|
||||||
|
LinkFreePage(BasePage + PageNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Calculate the virtual address range for this physical memory region */
|
||||||
|
VirtualRangeStart = (PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT));
|
||||||
|
VirtualRangeEnd = (PVOID)(KSEG0_BASE + ((BasePage + PageCount) << MM_PAGE_SHIFT));
|
||||||
|
|
||||||
|
/* Handle all other (non-free) memory types */
|
||||||
|
switch(MemoryType)
|
||||||
|
{
|
||||||
|
case LoaderBad:
|
||||||
|
/* This memory is marked as bad and should not be used */
|
||||||
|
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
||||||
|
{
|
||||||
|
/* Link the page to the bad pages list */
|
||||||
|
LinkPage(&BadPagesList, BasePage + PageNumber);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LoaderXIPRom:
|
||||||
|
/* Get the page directory entry for the current page */
|
||||||
|
PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);
|
||||||
|
|
||||||
|
/* Initialize the page directory entries covering this memory range */
|
||||||
|
InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));
|
||||||
|
|
||||||
|
/* This memory range contains Read-Only Memory (ROM) */
|
||||||
|
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
||||||
|
{
|
||||||
|
/* Get the PFN entry for the current ROM page */
|
||||||
|
Pfn = GetPfnEntry(BasePage + PageNumber);
|
||||||
|
|
||||||
|
/* Ensure that the page is not already in-use */
|
||||||
|
if(Pfn->u3.e2.ReferenceCount == 0)
|
||||||
|
{
|
||||||
|
/* Initialize the PFN entry to represent a ROM page */
|
||||||
|
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
|
||||||
|
Pfn->u1.Flink = 0;
|
||||||
|
Pfn->u2.ShareCount = 0;
|
||||||
|
Pfn->u3.e1.CacheAttribute = PfnCached;
|
||||||
|
Pfn->u3.e1.PageLocation = 0;
|
||||||
|
Pfn->u3.e1.PrototypePte = 1;
|
||||||
|
Pfn->u3.e1.Rom = 1;
|
||||||
|
Pfn->u3.e2.ReferenceCount = 0;
|
||||||
|
Pfn->u4.InPageError = 0;
|
||||||
|
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Get the page directory entry for the current page */
|
||||||
|
PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);
|
||||||
|
|
||||||
|
/* Initialize the page directory entries covering this memory range */
|
||||||
|
InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));
|
||||||
|
|
||||||
|
/* All other types are considered in-use (ie, by the kernel, ACPI, etc) */
|
||||||
|
for(PageNumber = 0; PageNumber < PageCount; PageNumber++)
|
||||||
|
{
|
||||||
|
/* Get the PFN entry for the current in-use page */
|
||||||
|
Pfn = GetPfnEntry(BasePage + PageNumber);
|
||||||
|
|
||||||
|
/* Ensure that the page is not already in-use */
|
||||||
|
if(Pfn->u3.e2.ReferenceCount == 0)
|
||||||
|
{
|
||||||
|
/* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */
|
||||||
|
Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualRangeStart);
|
||||||
|
Pfn->u2.ShareCount++;
|
||||||
|
Pfn->u3.e1.CacheAttribute = PfnCached;
|
||||||
|
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
||||||
|
Pfn->u3.e2.ReferenceCount = 1;
|
||||||
|
Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans memory descriptors provided by the boot loader.
|
* Scans memory descriptors provided by the boot loader.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user