- Call MmArmInitSystem for a second time, this time in Phase 1.

- This will call MmInitializeMemoryLimits (now implemented) which will go ahead and create the MmPhysicalMemoryBlock.
    - This block contains the physical memory "runs" that are valid on the system, allowing the PFN database to differentiate between valid and non-valid RAM (instead of marking things as "BIOS").
  - Also this will come in handy later for various utilities.


svn path=/trunk/; revision=41648
This commit is contained in:
ReactOS Portable Systems Group 2009-06-27 22:16:47 +00:00
parent d7a781de82
commit b254273e3b
3 changed files with 193 additions and 2 deletions

View file

@ -108,12 +108,16 @@ ULONG MmNumberOfSystemPtes;
//
ULONG MxPfnAllocation;
//
// The ARM³ PFN Database
//
PMMPFN MmArmPfnDatabase;
//
// This structure describes the different pieces of RAM-backed address space
//
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
/* PRIVATE FUNCTIONS **********************************************************/
//
@ -139,6 +143,142 @@ MiSyncARM3WithROS(IN PVOID AddressStart,
}
}
PPHYSICAL_MEMORY_DESCRIPTOR
NTAPI
MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType)
{
PLIST_ENTRY NextEntry;
ULONG Run = 0, InitialRuns = 0;
PFN_NUMBER NextPage = -1, PageCount = 0;
PPHYSICAL_MEMORY_DESCRIPTOR Buffer, NewBuffer;
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
//
// Scan the memory descriptors
//
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
{
//
// For each one, increase the memory allocation estimate
//
InitialRuns++;
NextEntry = NextEntry->Flink;
}
//
// Allocate the maximum we'll ever need
//
Buffer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
sizeof(PHYSICAL_MEMORY_RUN) *
(InitialRuns - 1),
'lMmM');
if (!Buffer) return NULL;
//
// For now that's how many runs we have
//
Buffer->NumberOfRuns = InitialRuns;
//
// Now loop through the descriptors again
//
NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
{
//
// Grab each one, and check if it's one we should include
//
MdBlock = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
if ((MdBlock->MemoryType < LoaderMaximum) &&
(IncludeType[MdBlock->MemoryType]))
{
//
// Add this to our running total
//
PageCount += MdBlock->PageCount;
//
// Check if the next page is described by the next descriptor
//
if (MdBlock->BasePage == NextPage)
{
//
// Combine it into the same physical run
//
ASSERT(MdBlock->PageCount != 0);
Buffer->Run[Run - 1].PageCount += MdBlock->PageCount;
NextPage += MdBlock->PageCount;
}
else
{
//
// Otherwise just duplicate the descriptor's contents
//
Buffer->Run[Run].BasePage = MdBlock->BasePage;
Buffer->Run[Run].PageCount = MdBlock->PageCount;
NextPage = Buffer->Run[Run].BasePage + Buffer->Run[Run].PageCount;
//
// And in this case, increase the number of runs
//
Run++;
}
}
//
// Try the next descriptor
//
NextEntry = MdBlock->ListEntry.Flink;
}
//
// We should not have been able to go past our initial estimate
//
ASSERT(Run <= Buffer->NumberOfRuns);
//
// Our guess was probably exaggerated...
//
if (InitialRuns > Run)
{
//
// Allocate a more accurately sized buffer
//
NewBuffer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
sizeof(PHYSICAL_MEMORY_RUN) *
(Run - 1),
'lMmM');
if (NewBuffer)
{
//
// Copy the old buffer into the new, then free it
//
RtlCopyMemory(NewBuffer->Run,
NewBuffer->Run,
sizeof(PHYSICAL_MEMORY_RUN) * Run);
ExFreePool(Buffer);
//
// Now use the new buffer
//
Buffer = NewBuffer;
}
}
//
// Write the final numbers, and return it
//
Buffer->NumberOfRuns = Run;
Buffer->NumberOfPages = PageCount;
return Buffer;
}
NTSTATUS
NTAPI
MmArmInitSystem(IN ULONG Phase,
@ -152,6 +292,8 @@ MmArmInitSystem(IN ULONG Phase,
PVOID NonPagedPoolExpansionVa, BaseAddress;
NTSTATUS Status;
ULONG OldCount;
BOOLEAN IncludeType[LoaderMaximum];
ULONG i;
BoundaryAddressMultiple.QuadPart = Low.QuadPart = 0;
High.QuadPart = -1;
@ -565,6 +707,36 @@ MmArmInitSystem(IN ULONG Phase,
MiSyncARM3WithROS(MmNonPagedPoolStart, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
}
else
{
//
// Instantiate memory that we don't consider RAM/usable
// We use the same exclusions that Windows does, in order to try to be
// compatible with WinLDR-style booting
//
for (i = 0; i < LoaderMaximum; i++) IncludeType[i] = TRUE;
IncludeType[LoaderBad] = FALSE;
IncludeType[LoaderFirmwarePermanent] = FALSE;
IncludeType[LoaderSpecialMemory] = FALSE;
IncludeType[LoaderBBTMemory] = FALSE;
//
// Build the physical memory block
//
MmPhysicalMemoryBlock = MmInitializeMemoryLimits(LoaderBlock,
IncludeType);
for (i = 0; i < MmPhysicalMemoryBlock->NumberOfRuns; i++)
{
//
// Dump it for debugging
//
PPHYSICAL_MEMORY_RUN Run;
Run = &MmPhysicalMemoryBlock->Run[i];
DPRINT1("PHYSICAL RAM [0x%08p to 0x%08p]\n",
Run->BasePage << PAGE_SHIFT,
(Run->BasePage + Run->PageCount) << PAGE_SHIFT);
}
}
//
// Always return success for now

View file

@ -28,6 +28,19 @@ typedef enum _MI_PFN_CACHE_ATTRIBUTE
MiNotMapped
} MI_PFN_CACHE_ATTRIBUTE, *PMI_PFN_CACHE_ATTRIBUTE;
typedef struct _PHYSICAL_MEMORY_RUN
{
ULONG BasePage;
ULONG PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
{
ULONG NumberOfRuns;
ULONG NumberOfPages;
PHYSICAL_MEMORY_RUN Run[1];
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
extern MMPTE HyperTemplatePte;
extern ULONG MmSizeOfNonPagedPoolInBytes;
@ -36,6 +49,7 @@ extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
extern PMMPTE MiFirstReservedZeroingPte;
extern PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
VOID
NTAPI

View file

@ -376,7 +376,7 @@ MmInit1(VOID)
MmInitializePageList();
//
// Initialize ARM³
// Initialize ARM³ in phase 0
//
MmArmInitSystem(0, KeLoaderBlock);
@ -391,6 +391,11 @@ MmInit1(VOID)
/* Initialize working sets */
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
//
// Initialize ARM³ in phase 1
//
MmArmInitSystem(1, KeLoaderBlock);
}
BOOLEAN