Author: ros-arm-bringup
Date: Sun Jun 28 02:16:47 2009
New Revision: 41648
URL:
http://svn.reactos.org/svn/reactos?rev=41648&view=rev
Log:
- 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.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/init.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/init.c [iso-8859-1] Sun Jun 28 02:16:47 2009
@@ -108,11 +108,15 @@
//
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 **********************************************************/
@@ -137,6 +141,142 @@
MmGlobalKernelPageDirectory[Pde] = ((PULONG)PAGEDIRECTORY_MAP)[Pde];
Pde++;
}
+}
+
+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
@@ -152,6 +292,8 @@
PVOID NonPagedPoolExpansionVa, BaseAddress;
NTSTATUS Status;
ULONG OldCount;
+ BOOLEAN IncludeType[LoaderMaximum];
+ ULONG i;
BoundaryAddressMultiple.QuadPart = Low.QuadPart = 0;
High.QuadPart = -1;
@@ -565,6 +707,36 @@
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
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sun Jun 28 02:16:47 2009
@@ -28,6 +28,19 @@
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 MmNonPagedPoolExpansionStart;
extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
extern PMMPTE MiFirstReservedZeroingPte;
+extern PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
VOID
NTAPI
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Sun Jun 28 02:16:47 2009
@@ -376,7 +376,7 @@
MmInitializePageList();
//
- // Initialize ARM³
+ // Initialize ARM³ in phase 0
//
MmArmInitSystem(0, KeLoaderBlock);
@@ -391,6 +391,11 @@
/* Initialize working sets */
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
+
+ //
+ // Initialize ARM³ in phase 1
+ //
+ MmArmInitSystem(1, KeLoaderBlock);
}
BOOLEAN