- Call MmArmInitSystem for a second time, this time in Phase 1.
authorReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Sat, 27 Jun 2009 22:16:47 +0000 (22:16 +0000)
committerReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Sat, 27 Jun 2009 22:16:47 +0000 (22:16 +0000)
  - 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

reactos/ntoskrnl/mm/ARM3/init.c
reactos/ntoskrnl/mm/ARM3/miarm.h
reactos/ntoskrnl/mm/mminit.c

index f946909..2073975 100644 (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
index 9d49047..aa9850b 100644 (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
index 84806ef..117bbcc 100644 (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