mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:12:59 +00:00
[NTOS]: Move more functions from the i386 ARM3 directory to the portable/shared directory, since they apply to all architectures.
[NTOS]: Refactor the mapping of the PTEs for the PFN database into MiMapPfnDatabase and move the code to portable directory. [NTOS]: Move and refactor some other definitions, and make some numbers more portable by defining arch-specific subvalues. [NTOS]: Make the PFN database actually 2 PFN Databases: MmPfnDatabase[0] which is the ReactOS mapping of PHYSICAL_PAGE structures, and MmPfnDatabase[1] which will be the ARM3 mapping of MMPFN structures. The latter is as-of-yet unused, but memory for it is now being reserved. svn path=/trunk/; revision=45566
This commit is contained in:
parent
dd6b443e89
commit
c7f7e3bac7
6 changed files with 367 additions and 288 deletions
|
@ -365,7 +365,7 @@ typedef struct _MMPFN
|
||||||
} u4;
|
} u4;
|
||||||
} MMPFN, *PMMPFN;
|
} MMPFN, *PMMPFN;
|
||||||
|
|
||||||
extern PMMPFN MmPfnDatabase;
|
extern PMMPFN MmPfnDatabase[2];
|
||||||
|
|
||||||
typedef struct _MMPFNLIST
|
typedef struct _MMPFNLIST
|
||||||
{
|
{
|
||||||
|
@ -1098,7 +1098,7 @@ MiGetPfnEntry(IN PFN_TYPE Pfn)
|
||||||
if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, Pfn))) return NULL;
|
if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, Pfn))) return NULL;
|
||||||
|
|
||||||
/* Get the entry */
|
/* Get the entry */
|
||||||
Page = &MmPfnDatabase[Pfn];
|
Page = &MmPfnDatabase[0][Pfn];
|
||||||
|
|
||||||
/* Make sure it's valid */
|
/* Make sure it's valid */
|
||||||
ASSERT_PFN(Page);
|
ASSERT_PFN(Page);
|
||||||
|
@ -1114,7 +1114,7 @@ MiGetPfnEntryIndex(IN PMMPFN Pfn1)
|
||||||
//
|
//
|
||||||
// This will return the Page Frame Number (PFN) from the MMPFN
|
// This will return the Page Frame Number (PFN) from the MMPFN
|
||||||
//
|
//
|
||||||
return Pfn1 - MmPfnDatabase;
|
return Pfn1 - MmPfnDatabase[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
PFN_TYPE
|
PFN_TYPE
|
||||||
|
|
|
@ -18,42 +18,10 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
//
|
|
||||||
// Before we have a PFN database, memory comes straight from our physical memory
|
|
||||||
// blocks, which is nice because it's guaranteed contiguous and also because once
|
|
||||||
// we take a page from here, the system doesn't see it anymore.
|
|
||||||
// However, once the fun is over, those pages must be re-integrated back into
|
|
||||||
// PFN society life, and that requires us keeping a copy of the original layout
|
|
||||||
// so that we can parse it later.
|
|
||||||
//
|
|
||||||
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
|
|
||||||
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
|
|
||||||
|
|
||||||
/* Template PTE and PDE for a kernel page */
|
/* Template PTE and PDE for a kernel page */
|
||||||
MMPTE ValidKernelPde = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
MMPTE ValidKernelPde = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
||||||
MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
|
||||||
|
|
||||||
/*
|
|
||||||
* For each page's worth bytes of L2 cache in a given set/way line, the zero and
|
|
||||||
* free lists are organized in what is called a "color".
|
|
||||||
*
|
|
||||||
* This array points to the two lists, so it can be thought of as a multi-dimensional
|
|
||||||
* array of MmFreePagesByColor[2][MmSecondaryColors]. Since the number is dynamic,
|
|
||||||
* we describe the array in pointer form instead.
|
|
||||||
*
|
|
||||||
* On a final note, the color tables themselves are right after the PFN database.
|
|
||||||
*/
|
|
||||||
C_ASSERT(FreePageList == 1);
|
|
||||||
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
|
|
||||||
|
|
||||||
/* Make the code cleaner with some definitions for size multiples */
|
|
||||||
#define _1KB (1024)
|
|
||||||
#define _1MB (1000 * _1KB)
|
|
||||||
|
|
||||||
/* Architecture specific size of a PDE directory, and size of a page table */
|
|
||||||
#define PDE_SIZE (4096 * sizeof(MMPDE))
|
|
||||||
#define PT_SIZE (1024 * sizeof(MMPTE))
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -171,109 +139,6 @@ MiComputeNonPagedPoolVa(IN ULONG FreePages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
MiComputeColorInformation(VOID)
|
|
||||||
{
|
|
||||||
ULONG L2Associativity;
|
|
||||||
|
|
||||||
/* Check if no setting was provided already */
|
|
||||||
if (!MmSecondaryColors)
|
|
||||||
{
|
|
||||||
/* Get L2 cache information */
|
|
||||||
L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
|
|
||||||
|
|
||||||
/* The number of colors is the number of cache bytes by set/way */
|
|
||||||
MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
|
|
||||||
if (L2Associativity) MmSecondaryColors /= L2Associativity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now convert cache bytes into pages */
|
|
||||||
MmSecondaryColors >>= PAGE_SHIFT;
|
|
||||||
if (!MmSecondaryColors)
|
|
||||||
{
|
|
||||||
/* If there was no cache data from the KPCR, use the default colors */
|
|
||||||
MmSecondaryColors = MI_SECONDARY_COLORS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise, make sure there aren't too many colors */
|
|
||||||
if (MmSecondaryColors > MI_MAX_SECONDARY_COLORS)
|
|
||||||
{
|
|
||||||
/* Set the maximum */
|
|
||||||
MmSecondaryColors = MI_MAX_SECONDARY_COLORS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure there aren't too little colors */
|
|
||||||
if (MmSecondaryColors < MI_MIN_SECONDARY_COLORS)
|
|
||||||
{
|
|
||||||
/* Set the default */
|
|
||||||
MmSecondaryColors = MI_SECONDARY_COLORS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally make sure the colors are a power of two */
|
|
||||||
if (MmSecondaryColors & (MmSecondaryColors - 1))
|
|
||||||
{
|
|
||||||
/* Set the default */
|
|
||||||
MmSecondaryColors = MI_SECONDARY_COLORS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute the mask and store it */
|
|
||||||
MmSecondaryColorMask = MmSecondaryColors - 1;
|
|
||||||
KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
MiInitializeColorTables(VOID)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
PMMPTE PointerPte, LastPte;
|
|
||||||
MMPTE TempPte = ValidKernelPte;
|
|
||||||
|
|
||||||
/* The color table starts after the PFN database */
|
|
||||||
MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[MmHighestPhysicalPage + 1];
|
|
||||||
|
|
||||||
/* Loop the PTEs. We have two color tables for each secondary color */
|
|
||||||
PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]);
|
|
||||||
LastPte = MiAddressToPte((ULONG_PTR)MmFreePagesByColor[0] +
|
|
||||||
(2 * MmSecondaryColors * sizeof(MMCOLOR_TABLES))
|
|
||||||
- 1);
|
|
||||||
while (PointerPte <= LastPte)
|
|
||||||
{
|
|
||||||
/* Check for valid PTE */
|
|
||||||
if (PointerPte->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
/* Get a page and map it */
|
|
||||||
TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1);
|
|
||||||
ASSERT(TempPte.u.Hard.Valid == 1);
|
|
||||||
*PointerPte = TempPte;
|
|
||||||
|
|
||||||
/* Zero out the page */
|
|
||||||
RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next */
|
|
||||||
PointerPte++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now set the address of the next list, right after this one */
|
|
||||||
MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
|
|
||||||
|
|
||||||
/* Now loop the lists to set them up */
|
|
||||||
for (i = 0; i < MmSecondaryColors; i++)
|
|
||||||
{
|
|
||||||
/* Set both free and zero lists for each color */
|
|
||||||
MmFreePagesByColor[ZeroedPageList][i].Flink = 0xFFFFFFFF;
|
|
||||||
MmFreePagesByColor[ZeroedPageList][i].Blink = (PVOID)0xFFFFFFFF;
|
|
||||||
MmFreePagesByColor[ZeroedPageList][i].Count = 0;
|
|
||||||
MmFreePagesByColor[FreePageList][i].Flink = 0xFFFFFFFF;
|
|
||||||
MmFreePagesByColor[FreePageList][i].Blink = (PVOID)0xFFFFFFFF;
|
|
||||||
MmFreePagesByColor[FreePageList][i].Count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
@ -286,7 +151,6 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
MMPTE TempPde, TempPte;
|
MMPTE TempPde, TempPte;
|
||||||
PVOID NonPagedPoolExpansionVa;
|
PVOID NonPagedPoolExpansionVa;
|
||||||
ULONG OldCount;
|
ULONG OldCount;
|
||||||
PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
|
|
||||||
|
|
||||||
/* Check for kernel stack size that's too big */
|
/* Check for kernel stack size that's too big */
|
||||||
if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
|
if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
|
||||||
|
@ -436,10 +300,11 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
MiComputeColorInformation();
|
MiComputeColorInformation();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Calculate the number of bytes for the PFN database, and the color tables,
|
// Calculate the number of bytes for the PFN database, double it for ARM3,
|
||||||
// and then convert to pages
|
// then add the color tables and convert to pages
|
||||||
//
|
//
|
||||||
MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN);
|
MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN);
|
||||||
|
MxPfnAllocation <<= 1;
|
||||||
MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2);
|
MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2);
|
||||||
MxPfnAllocation >>= PAGE_SHIFT;
|
MxPfnAllocation >>= PAGE_SHIFT;
|
||||||
|
|
||||||
|
@ -513,13 +378,19 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
// with the old memory manager, so we'll create a "Shadow PFN Database"
|
// with the old memory manager, so we'll create a "Shadow PFN Database"
|
||||||
// instead, and arbitrarly start it at 0xB0000000.
|
// instead, and arbitrarly start it at 0xB0000000.
|
||||||
//
|
//
|
||||||
MmPfnDatabase = (PVOID)0xB0000000;
|
// We actually create two PFN databases, one for ReactOS starting here,
|
||||||
ASSERT(((ULONG_PTR)MmPfnDatabase & ((4 * 1024 * 1024) - 1)) == 0);
|
// and the next one used for ARM3, which starts right after. The MmPfnAllocation
|
||||||
|
// variable actually holds the size of both (the colored tables come after
|
||||||
|
// the ARM3 PFN database).
|
||||||
|
//
|
||||||
|
MmPfnDatabase[0] = (PVOID)0xB0000000;
|
||||||
|
MmPfnDatabase[1] = &MmPfnDatabase[0][MmHighestPhysicalPage];
|
||||||
|
ASSERT(((ULONG_PTR)MmPfnDatabase[0] & ((4 * 1024 * 1024) - 1)) == 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Non paged pool comes after the PFN database
|
// Non paged pool comes after the PFN database
|
||||||
//
|
//
|
||||||
MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase +
|
MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase[0] +
|
||||||
(MxPfnAllocation << PAGE_SHIFT));
|
(MxPfnAllocation << PAGE_SHIFT));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -567,7 +438,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
//
|
//
|
||||||
// Now we need pages for the page tables which will map initial NP
|
// Now we need pages for the page tables which will map initial NP
|
||||||
//
|
//
|
||||||
StartPde = MiAddressToPde(MmPfnDatabase);
|
StartPde = MiAddressToPde(MmPfnDatabase[0]);
|
||||||
EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart +
|
EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart +
|
||||||
MmSizeOfNonPagedPoolInBytes - 1));
|
MmSizeOfNonPagedPoolInBytes - 1));
|
||||||
while (StartPde <= EndPde)
|
while (StartPde <= EndPde)
|
||||||
|
@ -629,134 +500,16 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
//
|
//
|
||||||
MiInitializeArmPool();
|
MiInitializeArmPool();
|
||||||
|
|
||||||
//
|
/* Map the PFN database pages */
|
||||||
// Get current page data, since we won't be using MxGetNextPage as it
|
MiMapPfnDatabase(LoaderBlock);
|
||||||
// would corrupt our state
|
|
||||||
//
|
|
||||||
FreePage = MxFreeDescriptor->BasePage;
|
|
||||||
FreePageCount = MxFreeDescriptor->PageCount;
|
|
||||||
PagesLeft = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Loop the memory descriptors
|
|
||||||
//
|
|
||||||
NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
|
|
||||||
while (NextEntry != &KeLoaderBlock->MemoryDescriptorListHead)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Get the descriptor
|
|
||||||
//
|
|
||||||
MdBlock = CONTAINING_RECORD(NextEntry,
|
|
||||||
MEMORY_ALLOCATION_DESCRIPTOR,
|
|
||||||
ListEntry);
|
|
||||||
if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
|
|
||||||
(MdBlock->MemoryType == LoaderBBTMemory) ||
|
|
||||||
(MdBlock->MemoryType == LoaderSpecialMemory))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// These pages are not part of the PFN database
|
|
||||||
//
|
|
||||||
NextEntry = MdBlock->ListEntry.Flink;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Next, check if this is our special free descriptor we've found
|
|
||||||
//
|
|
||||||
if (MdBlock == MxFreeDescriptor)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Use the real numbers instead
|
|
||||||
//
|
|
||||||
BasePage = MxOldFreeDescriptor.BasePage;
|
|
||||||
PageCount = MxOldFreeDescriptor.PageCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Use the descriptor's numbers
|
|
||||||
//
|
|
||||||
BasePage = MdBlock->BasePage;
|
|
||||||
PageCount = MdBlock->PageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the PTEs for this range
|
|
||||||
//
|
|
||||||
PointerPte = MiAddressToPte(&MmPfnDatabase[BasePage]);
|
|
||||||
LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[BasePage + PageCount]) - 1);
|
|
||||||
DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Loop them
|
|
||||||
//
|
|
||||||
while (PointerPte <= LastPte)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// We'll only touch PTEs that aren't already valid
|
|
||||||
//
|
|
||||||
if (PointerPte->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Use the next free page
|
|
||||||
//
|
|
||||||
TempPte.u.Hard.PageFrameNumber = FreePage;
|
|
||||||
ASSERT(FreePageCount != 0);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Consume free pages
|
|
||||||
//
|
|
||||||
FreePage++;
|
|
||||||
FreePageCount--;
|
|
||||||
if (!FreePageCount)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Out of memory
|
|
||||||
//
|
|
||||||
KeBugCheckEx(INSTALL_MORE_MEMORY,
|
|
||||||
MmNumberOfPhysicalPages,
|
|
||||||
FreePageCount,
|
|
||||||
MxOldFreeDescriptor.PageCount,
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write out this PTE
|
|
||||||
//
|
|
||||||
PagesLeft++;
|
|
||||||
ASSERT(PointerPte->u.Hard.Valid == 0);
|
|
||||||
ASSERT(TempPte.u.Hard.Valid == 1);
|
|
||||||
*PointerPte = TempPte;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Zero this page
|
|
||||||
//
|
|
||||||
RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Next!
|
|
||||||
//
|
|
||||||
PointerPte++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do the next address range
|
|
||||||
//
|
|
||||||
NextEntry = MdBlock->ListEntry.Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Now update the free descriptors to consume the pages we used up during
|
|
||||||
// the PFN allocation loop
|
|
||||||
//
|
|
||||||
MxFreeDescriptor->BasePage = FreePage;
|
|
||||||
MxFreeDescriptor->PageCount = FreePageCount;
|
|
||||||
|
|
||||||
/* Initialize the color tables */
|
/* Initialize the color tables */
|
||||||
MiInitializeColorTables();
|
MiInitializeColorTables();
|
||||||
|
|
||||||
|
/* Build the PFN Database */
|
||||||
|
//MiInitializePfnDatabase(LoaderBlock);
|
||||||
|
|
||||||
/* Call back into shitMM to setup the PFN database */
|
/* Call back into shitMM to setup the ReactOS PFN database */
|
||||||
MmInitializePageList();
|
MmInitializePageList();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -38,6 +38,26 @@
|
||||||
#define MM_HIGHEST_VAD_ADDRESS \
|
#define MM_HIGHEST_VAD_ADDRESS \
|
||||||
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
||||||
|
|
||||||
|
/* Make the code cleaner with some definitions for size multiples */
|
||||||
|
#define _1KB (1024)
|
||||||
|
#define _1MB (1000 * _1KB)
|
||||||
|
|
||||||
|
/* Size of a PDE directory, and size of a page table */
|
||||||
|
#define PDE_SIZE (PDE_COUNT * sizeof(MMPDE))
|
||||||
|
#define PT_SIZE (PTE_COUNT * sizeof(MMPTE))
|
||||||
|
|
||||||
|
/* Architecture specific count of PDEs in a directory, and count of PTEs in a PT */
|
||||||
|
#ifdef _M_IX86
|
||||||
|
#define PD_COUNT 1
|
||||||
|
#define PDE_COUNT 4096
|
||||||
|
#define PTE_COUNT 1024
|
||||||
|
#elif _M_ARM
|
||||||
|
#define PD_COUNT 1
|
||||||
|
#define PDE_COUNT 1024
|
||||||
|
#define PTE_COUNT 256
|
||||||
|
#else
|
||||||
|
#error Define these please!
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXFIX: These should go in ex.h after the pool merge
|
// FIXFIX: These should go in ex.h after the pool merge
|
||||||
|
@ -190,11 +210,10 @@ extern ULONG MmSecondaryColors;
|
||||||
extern ULONG MmSecondaryColorMask;
|
extern ULONG MmSecondaryColorMask;
|
||||||
extern ULONG MmNumberOfSystemPtes;
|
extern ULONG MmNumberOfSystemPtes;
|
||||||
extern ULONG MmMaximumNonPagedPoolPercent;
|
extern ULONG MmMaximumNonPagedPoolPercent;
|
||||||
|
extern ULONG MmLargeStackSize;
|
||||||
|
|
||||||
//
|
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
|
||||||
// Actual (registry-configurable) size of a GUI thread's stack
|
#define MI_PFNENTRY_TO_PFN(x) (Pfn - &MmPfnDatabase[1])
|
||||||
//
|
|
||||||
ULONG MmLargeStackSize;
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -209,6 +228,30 @@ MiInitMachineDependent(
|
||||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiComputeColorInformation(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiMapPfnDatabase(
|
||||||
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiInitializeColorTables(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiInitializePfnDatabase(
|
||||||
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
|
);
|
||||||
|
|
||||||
PFN_NUMBER
|
PFN_NUMBER
|
||||||
NTAPI
|
NTAPI
|
||||||
MxGetNextPage(
|
MxGetNextPage(
|
||||||
|
|
|
@ -234,6 +234,30 @@ ULONG MmSecondaryColorMask;
|
||||||
//
|
//
|
||||||
ULONG MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
|
ULONG MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Before we have a PFN database, memory comes straight from our physical memory
|
||||||
|
// blocks, which is nice because it's guaranteed contiguous and also because once
|
||||||
|
// we take a page from here, the system doesn't see it anymore.
|
||||||
|
// However, once the fun is over, those pages must be re-integrated back into
|
||||||
|
// PFN society life, and that requires us keeping a copy of the original layout
|
||||||
|
// so that we can parse it later.
|
||||||
|
//
|
||||||
|
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
|
||||||
|
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For each page's worth bytes of L2 cache in a given set/way line, the zero and
|
||||||
|
* free lists are organized in what is called a "color".
|
||||||
|
*
|
||||||
|
* This array points to the two lists, so it can be thought of as a multi-dimensional
|
||||||
|
* array of MmFreePagesByColor[2][MmSecondaryColors]. Since the number is dynamic,
|
||||||
|
* we describe the array in pointer form instead.
|
||||||
|
*
|
||||||
|
* On a final note, the color tables themselves are right after the PFN database.
|
||||||
|
*/
|
||||||
|
C_ASSERT(FreePageList == 1);
|
||||||
|
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -283,6 +307,264 @@ MxGetNextPage(IN PFN_NUMBER PageCount)
|
||||||
return Pfn;
|
return Pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiComputeColorInformation(VOID)
|
||||||
|
{
|
||||||
|
ULONG L2Associativity;
|
||||||
|
|
||||||
|
/* Check if no setting was provided already */
|
||||||
|
if (!MmSecondaryColors)
|
||||||
|
{
|
||||||
|
/* Get L2 cache information */
|
||||||
|
L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
|
||||||
|
|
||||||
|
/* The number of colors is the number of cache bytes by set/way */
|
||||||
|
MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
|
||||||
|
if (L2Associativity) MmSecondaryColors /= L2Associativity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now convert cache bytes into pages */
|
||||||
|
MmSecondaryColors >>= PAGE_SHIFT;
|
||||||
|
if (!MmSecondaryColors)
|
||||||
|
{
|
||||||
|
/* If there was no cache data from the KPCR, use the default colors */
|
||||||
|
MmSecondaryColors = MI_SECONDARY_COLORS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, make sure there aren't too many colors */
|
||||||
|
if (MmSecondaryColors > MI_MAX_SECONDARY_COLORS)
|
||||||
|
{
|
||||||
|
/* Set the maximum */
|
||||||
|
MmSecondaryColors = MI_MAX_SECONDARY_COLORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there aren't too little colors */
|
||||||
|
if (MmSecondaryColors < MI_MIN_SECONDARY_COLORS)
|
||||||
|
{
|
||||||
|
/* Set the default */
|
||||||
|
MmSecondaryColors = MI_SECONDARY_COLORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally make sure the colors are a power of two */
|
||||||
|
if (MmSecondaryColors & (MmSecondaryColors - 1))
|
||||||
|
{
|
||||||
|
/* Set the default */
|
||||||
|
MmSecondaryColors = MI_SECONDARY_COLORS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the mask and store it */
|
||||||
|
MmSecondaryColorMask = MmSecondaryColors - 1;
|
||||||
|
KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiInitializeColorTables(VOID)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
PMMPTE PointerPte, LastPte;
|
||||||
|
MMPTE TempPte = ValidKernelPte;
|
||||||
|
|
||||||
|
/* The color table starts after the ARM3 PFN database */
|
||||||
|
MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[1][MmHighestPhysicalPage + 1];
|
||||||
|
|
||||||
|
/* Loop the PTEs. We have two color tables for each secondary color */
|
||||||
|
PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]);
|
||||||
|
LastPte = MiAddressToPte((ULONG_PTR)MmFreePagesByColor[0] +
|
||||||
|
(2 * MmSecondaryColors * sizeof(MMCOLOR_TABLES))
|
||||||
|
- 1);
|
||||||
|
while (PointerPte <= LastPte)
|
||||||
|
{
|
||||||
|
/* Check for valid PTE */
|
||||||
|
if (PointerPte->u.Hard.Valid == 0)
|
||||||
|
{
|
||||||
|
/* Get a page and map it */
|
||||||
|
TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1);
|
||||||
|
ASSERT(TempPte.u.Hard.Valid == 1);
|
||||||
|
*PointerPte = TempPte;
|
||||||
|
|
||||||
|
/* Zero out the page */
|
||||||
|
RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next */
|
||||||
|
PointerPte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set the address of the next list, right after this one */
|
||||||
|
MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
|
||||||
|
|
||||||
|
/* Now loop the lists to set them up */
|
||||||
|
for (i = 0; i < MmSecondaryColors; i++)
|
||||||
|
{
|
||||||
|
/* Set both free and zero lists for each color */
|
||||||
|
MmFreePagesByColor[ZeroedPageList][i].Flink = 0xFFFFFFFF;
|
||||||
|
MmFreePagesByColor[ZeroedPageList][i].Blink = (PVOID)0xFFFFFFFF;
|
||||||
|
MmFreePagesByColor[ZeroedPageList][i].Count = 0;
|
||||||
|
MmFreePagesByColor[FreePageList][i].Flink = 0xFFFFFFFF;
|
||||||
|
MmFreePagesByColor[FreePageList][i].Blink = (PVOID)0xFFFFFFFF;
|
||||||
|
MmFreePagesByColor[FreePageList][i].Count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
|
IN PFN_NUMBER Pfn)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
|
||||||
|
|
||||||
|
/* Loop the memory descriptors */
|
||||||
|
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||||||
|
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
|
||||||
|
{
|
||||||
|
/* Get the memory descriptor */
|
||||||
|
MdBlock = CONTAINING_RECORD(NextEntry,
|
||||||
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
||||||
|
ListEntry);
|
||||||
|
|
||||||
|
/* Check if this PFN could be part of the block */
|
||||||
|
if (Pfn >= (MdBlock->BasePage))
|
||||||
|
{
|
||||||
|
/* Check if it really is part of the block */
|
||||||
|
if (Pfn < (MdBlock->BasePage + MdBlock->PageCount))
|
||||||
|
{
|
||||||
|
/* Check if the block is actually memory we don't map */
|
||||||
|
if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
|
||||||
|
(MdBlock->MemoryType == LoaderBBTMemory) ||
|
||||||
|
(MdBlock->MemoryType == LoaderSpecialMemory))
|
||||||
|
{
|
||||||
|
/* We don't need PFN database entries for this memory */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is memory we want to map */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Blocks are ordered, so if it's not here, it doesn't exist */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get to the next descriptor */
|
||||||
|
NextEntry = MdBlock->ListEntry.Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this PFN is actually from our free memory descriptor */
|
||||||
|
if ((Pfn >= MxOldFreeDescriptor.BasePage) &&
|
||||||
|
(Pfn < MxOldFreeDescriptor.BasePage + MxOldFreeDescriptor.PageCount))
|
||||||
|
{
|
||||||
|
/* We use these pages for initial mappings, so we do want to count them */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise this isn't memory that we describe or care about */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
{
|
||||||
|
ULONG FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
|
||||||
|
PMMPTE PointerPte, LastPte;
|
||||||
|
MMPTE TempPte = ValidKernelPte;
|
||||||
|
|
||||||
|
/* Get current page data, since we won't be using MxGetNextPage as it would corrupt our state */
|
||||||
|
FreePage = MxFreeDescriptor->BasePage;
|
||||||
|
FreePageCount = MxFreeDescriptor->PageCount;
|
||||||
|
PagesLeft = 0;
|
||||||
|
|
||||||
|
/* Loop the memory descriptors */
|
||||||
|
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||||||
|
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
|
||||||
|
{
|
||||||
|
/* Get the descriptor */
|
||||||
|
MdBlock = CONTAINING_RECORD(NextEntry,
|
||||||
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
||||||
|
ListEntry);
|
||||||
|
if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
|
||||||
|
(MdBlock->MemoryType == LoaderBBTMemory) ||
|
||||||
|
(MdBlock->MemoryType == LoaderSpecialMemory))
|
||||||
|
{
|
||||||
|
/* These pages are not part of the PFN database */
|
||||||
|
NextEntry = MdBlock->ListEntry.Flink;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next, check if this is our special free descriptor we've found */
|
||||||
|
if (MdBlock == MxFreeDescriptor)
|
||||||
|
{
|
||||||
|
/* Use the real numbers instead */
|
||||||
|
BasePage = MxOldFreeDescriptor.BasePage;
|
||||||
|
PageCount = MxOldFreeDescriptor.PageCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use the descriptor's numbers */
|
||||||
|
BasePage = MdBlock->BasePage;
|
||||||
|
PageCount = MdBlock->PageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the PTEs for this range */
|
||||||
|
PointerPte = MiAddressToPte(&MmPfnDatabase[0][BasePage]);
|
||||||
|
LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[0][BasePage + PageCount]) - 1);
|
||||||
|
DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount);
|
||||||
|
|
||||||
|
/* Loop them */
|
||||||
|
while (PointerPte <= LastPte)
|
||||||
|
{
|
||||||
|
/* We'll only touch PTEs that aren't already valid */
|
||||||
|
if (PointerPte->u.Hard.Valid == 0)
|
||||||
|
{
|
||||||
|
/* Use the next free page */
|
||||||
|
TempPte.u.Hard.PageFrameNumber = FreePage;
|
||||||
|
ASSERT(FreePageCount != 0);
|
||||||
|
|
||||||
|
/* Consume free pages */
|
||||||
|
FreePage++;
|
||||||
|
FreePageCount--;
|
||||||
|
if (!FreePageCount)
|
||||||
|
{
|
||||||
|
/* Out of memory */
|
||||||
|
KeBugCheckEx(INSTALL_MORE_MEMORY,
|
||||||
|
MmNumberOfPhysicalPages,
|
||||||
|
FreePageCount,
|
||||||
|
MxOldFreeDescriptor.PageCount,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write out this PTE */
|
||||||
|
PagesLeft++;
|
||||||
|
ASSERT(PointerPte->u.Hard.Valid == 0);
|
||||||
|
ASSERT(TempPte.u.Hard.Valid == 1);
|
||||||
|
*PointerPte = TempPte;
|
||||||
|
|
||||||
|
/* Zero this page */
|
||||||
|
RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next! */
|
||||||
|
PointerPte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the next address range */
|
||||||
|
NextEntry = MdBlock->ListEntry.Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now update the free descriptors to consume the pages we used up during the PFN allocation loop */
|
||||||
|
MxFreeDescriptor->BasePage = FreePage;
|
||||||
|
MxFreeDescriptor->PageCount = FreePageCount;
|
||||||
|
}
|
||||||
|
|
||||||
PFN_NUMBER
|
PFN_NUMBER
|
||||||
NTAPI
|
NTAPI
|
||||||
MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
|
@ -788,7 +1070,7 @@ MmArmInitSystem(IN ULONG Phase,
|
||||||
// Sync us up with ReactOS Mm
|
// Sync us up with ReactOS Mm
|
||||||
//
|
//
|
||||||
MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
|
MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
|
||||||
MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
|
MiSyncARM3WithROS(MmPfnDatabase[0], (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
|
||||||
MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
|
MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -48,7 +48,8 @@
|
||||||
#define PHYSICAL_PAGE MMPFN
|
#define PHYSICAL_PAGE MMPFN
|
||||||
#define PPHYSICAL_PAGE PMMPFN
|
#define PPHYSICAL_PAGE PMMPFN
|
||||||
|
|
||||||
PPHYSICAL_PAGE MmPfnDatabase;
|
/* The first array contains ReactOS PFNs, the second contains ARM3 PFNs */
|
||||||
|
PPHYSICAL_PAGE MmPfnDatabase[2];
|
||||||
|
|
||||||
ULONG MmAvailablePages;
|
ULONG MmAvailablePages;
|
||||||
ULONG MmResidentAvailablePages;
|
ULONG MmResidentAvailablePages;
|
||||||
|
@ -59,7 +60,7 @@ SIZE_T MmSharedCommit;
|
||||||
SIZE_T MmDriverCommit;
|
SIZE_T MmDriverCommit;
|
||||||
SIZE_T MmProcessCommit;
|
SIZE_T MmProcessCommit;
|
||||||
SIZE_T MmPagedPoolCommit;
|
SIZE_T MmPagedPoolCommit;
|
||||||
SIZE_T MmPeakCommitment;
|
SIZE_T MmPeakCommitment;
|
||||||
SIZE_T MmtotalCommitLimitMaximum;
|
SIZE_T MmtotalCommitLimitMaximum;
|
||||||
|
|
||||||
MMPFNLIST MmZeroedPageListHead;
|
MMPFNLIST MmZeroedPageListHead;
|
||||||
|
@ -101,7 +102,7 @@ MmGetLRUFirstUserPage(VOID)
|
||||||
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
||||||
ASSERT_PFN(PageDescriptor);
|
ASSERT_PFN(PageDescriptor);
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||||
return PageDescriptor - MmPfnDatabase;
|
return PageDescriptor - MmPfnDatabase[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -142,7 +143,7 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn)
|
||||||
}
|
}
|
||||||
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||||
return PageDescriptor - MmPfnDatabase;
|
return PageDescriptor - MmPfnDatabase[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -758,9 +759,9 @@ MmInitializePageList(VOID)
|
||||||
for (i = 0; i < Md->PageCount; i++)
|
for (i = 0; i < Md->PageCount; i++)
|
||||||
{
|
{
|
||||||
/* Mark it as a free page */
|
/* Mark it as a free page */
|
||||||
MmPfnDatabase[Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
|
MmPfnDatabase[0][Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
|
||||||
InsertTailList(&FreeUnzeroedPageListHead,
|
InsertTailList(&FreeUnzeroedPageListHead,
|
||||||
&MmPfnDatabase[Md->BasePage + i].ListEntry);
|
&MmPfnDatabase[0][Md->BasePage + i].ListEntry);
|
||||||
UnzeroedPageCount++;
|
UnzeroedPageCount++;
|
||||||
MmAvailablePages++;
|
MmAvailablePages++;
|
||||||
}
|
}
|
||||||
|
@ -771,7 +772,7 @@ MmInitializePageList(VOID)
|
||||||
for (i = 0; i < Md->PageCount; i++)
|
for (i = 0; i < Md->PageCount; i++)
|
||||||
{
|
{
|
||||||
/* Everything else is used memory */
|
/* Everything else is used memory */
|
||||||
MmPfnDatabase[Md->BasePage + i] = UsedPage;
|
MmPfnDatabase[0][Md->BasePage + i] = UsedPage;
|
||||||
NrSystemPages++;
|
NrSystemPages++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -781,10 +782,10 @@ MmInitializePageList(VOID)
|
||||||
for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
|
for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
|
||||||
{
|
{
|
||||||
/* Ensure this page was not added previously */
|
/* Ensure this page was not added previously */
|
||||||
ASSERT(MmPfnDatabase[i].Flags.Type == 0);
|
ASSERT(MmPfnDatabase[0][i].Flags.Type == 0);
|
||||||
|
|
||||||
/* Mark it as used kernel memory */
|
/* Mark it as used kernel memory */
|
||||||
MmPfnDatabase[i] = UsedPage;
|
MmPfnDatabase[0][i] = UsedPage;
|
||||||
NrSystemPages++;
|
NrSystemPages++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,7 +1083,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
|
||||||
|
|
||||||
MmAvailablePages--;
|
MmAvailablePages--;
|
||||||
|
|
||||||
PfnOffset = PageDescriptor - MmPfnDatabase;
|
PfnOffset = PageDescriptor - MmPfnDatabase[0];
|
||||||
if ((NeedClear) && (Consumer != MC_SYSTEM))
|
if ((NeedClear) && (Consumer != MC_SYSTEM))
|
||||||
{
|
{
|
||||||
MiZeroPage(PfnOffset);
|
MiZeroPage(PfnOffset);
|
||||||
|
@ -1155,7 +1156,7 @@ MmZeroPageThreadMain(PVOID Ignored)
|
||||||
/* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
|
/* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
|
||||||
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||||
Pfn = PageDescriptor - MmPfnDatabase;
|
Pfn = PageDescriptor - MmPfnDatabase[0];
|
||||||
Status = MiZeroPage(Pfn);
|
Status = MiZeroPage(Pfn);
|
||||||
|
|
||||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
|
|
@ -109,7 +109,7 @@ MiInitSystemMemoryAreas()
|
||||||
//
|
//
|
||||||
// Protect the PFN database
|
// Protect the PFN database
|
||||||
//
|
//
|
||||||
BaseAddress = MmPfnDatabase;
|
BaseAddress = MmPfnDatabase[0];
|
||||||
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
|
||||||
MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
|
MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
|
@ -292,8 +292,8 @@ MiDbgDumpAddressSpace(VOID)
|
||||||
(ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
|
(ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
|
||||||
"Paged Pool");
|
"Paged Pool");
|
||||||
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
||||||
MmPfnDatabase,
|
MmPfnDatabase[0],
|
||||||
(ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
|
(ULONG_PTR)MmPfnDatabase[0] + (MxPfnAllocation << PAGE_SHIFT),
|
||||||
"PFN Database");
|
"PFN Database");
|
||||||
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
DPRINT1(" 0x%p - 0x%p\t%s\n",
|
||||||
MmNonPagedPoolStart,
|
MmNonPagedPoolStart,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue