[CMAKE]
[reactos.git] / ntoskrnl / mm / ARM3 / mminit.c
index 1e79a23..6a36dd3 100644 (file)
@@ -23,8 +23,8 @@
 // figure out the most appropriate values.
 //
 ULONG MmMaximumNonPagedPoolPercent;
-ULONG MmSizeOfNonPagedPoolInBytes;
-ULONG MmMaximumNonPagedPoolInBytes;
+SIZE_T MmSizeOfNonPagedPoolInBytes;
+SIZE_T MmMaximumNonPagedPoolInBytes;
 
 /* Some of the same values, in pages */
 PFN_NUMBER MmMaximumNonPagedPoolInPages;
@@ -36,9 +36,9 @@ PFN_NUMBER MmMaximumNonPagedPoolInPages;
 // They are described on http://support.microsoft.com/default.aspx/kb/126402/ja
 // along with the algorithm that uses them, which is implemented later below.
 //
-ULONG MmMinimumNonPagedPoolSize = 256 * 1024;
+SIZE_T MmMinimumNonPagedPoolSize = 256 * 1024;
 ULONG MmMinAdditionNonPagedPoolPerMb = 32 * 1024;
-ULONG MmDefaultMaximumNonPagedPool = 1024 * 1024; 
+SIZE_T MmDefaultMaximumNonPagedPool = 1024 * 1024; 
 ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024;
 
 //
@@ -107,7 +107,7 @@ PVOID MmPagedPoolEnd;
 //
 // And this is its default size
 //
-ULONG MmSizeOfPagedPoolInBytes = MI_MIN_INIT_PAGED_POOLSIZE;
+SIZE_T MmSizeOfPagedPoolInBytes = MI_MIN_INIT_PAGED_POOLSIZE;
 PFN_NUMBER MmSizeOfPagedPoolInPages = MI_MIN_INIT_PAGED_POOLSIZE / PAGE_SIZE;
 
 //
@@ -131,10 +131,10 @@ PVOID MiSessionViewStart;   // 0xBE000000
 PVOID MiSessionPoolEnd;     // 0xBE000000
 PVOID MiSessionPoolStart;   // 0xBD000000
 PVOID MmSessionBase;        // 0xBD000000
-ULONG MmSessionSize;
-ULONG MmSessionViewSize;
-ULONG MmSessionPoolSize;
-ULONG MmSessionImageSize;
+SIZE_T MmSessionSize;
+SIZE_T MmSessionViewSize;
+SIZE_T MmSessionPoolSize;
+SIZE_T MmSessionImageSize;
 
 /*
  * These are the PTE addresses of the boundaries carved out above
@@ -151,8 +151,9 @@ PMMPTE MiSessionLastPte;
 // By default, it is a 16MB region.
 //
 PVOID MiSystemViewStart;
-ULONG MmSystemViewSize;
+SIZE_T MmSystemViewSize;
 
+#if (_MI_PAGING_LEVELS == 2)
 //
 // A copy of the system page directory (the page directory associated with the
 // System process) is kept (double-mapped) by the manager in order to lazily
@@ -161,6 +162,7 @@ ULONG MmSystemViewSize;
 //
 PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
 PMMPTE MmSystemPagePtes;
+#endif
 
 //
 // The system cache starts right after hyperspace. The first few pages are for
@@ -175,13 +177,13 @@ PMMWSL MmSystemCacheWorkingSetList = MI_SYSTEM_CACHE_WS_START;
 // On systems with more than 32MB, this number is then doubled, and further
 // aligned up to a PDE boundary (4MB).
 //
-ULONG MmNumberOfSystemPtes;
+ULONG_PTR MmNumberOfSystemPtes;
 
 //
 // This is how many pages the PFN database will take up
 // In Windows, this includes the Quark Color Table, but not in ARMĀ³
 //
-ULONG MxPfnAllocation;
+PFN_NUMBER MxPfnAllocation;
 
 //
 // Unlike the old ReactOS Memory Manager, ARMĀ³ (and Windows) does not keep track
@@ -205,7 +207,7 @@ PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
 //
 // This is where we keep track of the most basic physical layout markers
 //
-ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1;
+PFN_NUMBER MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1;
 
 //
 // The total number of pages mapped by the boot loader, which include the kernel
@@ -215,19 +217,22 @@ ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1;
 //
 // This number is later aligned up to a PDE boundary.
 //
-ULONG MmBootImageSize;
+SIZE_T MmBootImageSize;
 
 //
 // These three variables keep track of the core separation of address space that
 // exists between kernel mode and user mode.
 //
-ULONG MmUserProbeAddress;
+ULONG_PTR MmUserProbeAddress;
 PVOID MmHighestUserAddress;
 PVOID MmSystemRangeStart;
 
 /* And these store the respective highest PTE/PDE address */
 PMMPTE MiHighestUserPte;
 PMMPDE MiHighestUserPde;
+#if (_MI_PAGING_LEVELS >= 3)
+/* We need the highest PPE and PXE addresses */
+#endif
 
 /* These variables define the system cache address space */
 PVOID MmSystemCacheStart;
@@ -328,33 +333,39 @@ PFN_NUMBER MmSystemCacheWsMaximum = 350;
 /* FIXME: Move to cache/working set code later */
 BOOLEAN MmLargeSystemCache;
 
-/* PRIVATE FUNCTIONS **********************************************************/
+/*
+ * This value determines in how many fragments/chunks the subsection prototype
+ * PTEs should be allocated when mapping a section object. It is configurable in
+ * the registry through the MapAllocationFragment parameter.
+ *
+ * The default is 64KB on systems with more than 1GB of RAM, 32KB on systems with
+ * more than 256MB of RAM, and 16KB on systems with less than 256MB of RAM.
+ *
+ * The maximum it can be set to is 2MB, and the minimum is 4KB.
+ */
+SIZE_T MmAllocationFragment;
 
-//
-// In Bavaria, this is probably a hate crime
-//
-VOID
-FASTCALL
-MiSyncARM3WithROS(IN PVOID AddressStart,
-                  IN PVOID AddressEnd)
-{
-    //
-    // Puerile piece of junk-grade carbonized horseshit puss sold to the lowest bidder
-    //
-    ULONG Pde = ADDR_TO_PDE_OFFSET(AddressStart);
-    while (Pde <= ADDR_TO_PDE_OFFSET(AddressEnd))
-    {
-        //
-        // This both odious and heinous
-        //
-        extern ULONG MmGlobalKernelPageDirectory[1024];
-        MmGlobalKernelPageDirectory[Pde] = ((PULONG)PDE_BASE)[Pde];
-        Pde++;
-    }
-}
+/*
+ * These two values track how much virtual memory can be committed, and when
+ * expansion should happen.
+ */
+ // FIXME: They should be moved elsewhere since it's not an "init" setting?
+SIZE_T MmTotalCommitLimit;
+SIZE_T MmTotalCommitLimitMaximum;
+
+/* Internal setting used for debugging memory descriptors */
+BOOLEAN MiDbgEnableMdDump =
+#ifdef _ARM_
+TRUE;
+#else
+FALSE;
+#endif
+
+/* PRIVATE FUNCTIONS **********************************************************/
 
 PFN_NUMBER
 NTAPI
+INIT_FUNCTION
 MxGetNextPage(IN PFN_NUMBER PageCount)
 {
     PFN_NUMBER Pfn;
@@ -379,6 +390,7 @@ MxGetNextPage(IN PFN_NUMBER PageCount)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiComputeColorInformation(VOID)
 {
     ULONG L2Associativity;
@@ -432,6 +444,7 @@ MiComputeColorInformation(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiInitializeColorTables(VOID)
 {
     ULONG i;
@@ -481,6 +494,7 @@ MiInitializeColorTables(VOID)
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                   IN PFN_NUMBER Pfn)
 {
@@ -539,6 +553,7 @@ MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     ULONG FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
@@ -634,6 +649,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     PMMPDE PointerPde;
@@ -668,6 +684,10 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                 Pfn1->u3.e2.ReferenceCount = 1;
                 Pfn1->u3.e1.PageLocation = ActiveAndValid;
                 Pfn1->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+                Pfn1->PfnUsage = MI_USAGE_INIT_MEMORY;
+                memcpy(Pfn1->ProcessName, "Initial PDE", 16);
+#endif
             }
             else
             {
@@ -711,6 +731,10 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                                 Pfn2->u3.e2.ReferenceCount = 1;
                                 Pfn2->u3.e1.PageLocation = ActiveAndValid;
                                 Pfn2->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+                                Pfn2->PfnUsage = MI_USAGE_INIT_MEMORY;
+                                memcpy(Pfn1->ProcessName, "Initial PTE", 16);
+#endif
                             }
                         }
                     }
@@ -734,6 +758,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiBuildPfnDatabaseZeroPage(VOID)
 {
     PMMPFN Pfn1;
@@ -756,6 +781,7 @@ MiBuildPfnDatabaseZeroPage(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     PLIST_ENTRY NextEntry;
@@ -804,8 +830,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
             /* Check for bad RAM */
             case LoaderBad:
             
-                DPRINT1("You have damaged RAM modules. Stopping boot\n");
-                while (TRUE);
+                DPRINT1("You either have specified /BURNMEMORY or damaged RAM modules.\n");
                 break;
 
             /* Check for free RAM */
@@ -867,6 +892,9 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                         Pfn1->u3.e2.ReferenceCount = 1;
                         Pfn1->u3.e1.PageLocation = ActiveAndValid;
                         Pfn1->u3.e1.CacheAttribute = MiNonCached;
+#if MI_TRACE_PFNS
+                        Pfn1->PfnUsage = MI_USAGE_BOOT_DRIVER;
+#endif
                         
                         /* Check for RAM disk page */
                         if (MdBlock->MemoryType == LoaderXIPRom)
@@ -897,6 +925,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiBuildPfnDatabaseSelf(VOID)
 {
     PMMPTE PointerPte, LastPte;
@@ -914,6 +943,9 @@ MiBuildPfnDatabaseSelf(VOID)
             Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
             Pfn1->u2.ShareCount = 1;
             Pfn1->u3.e2.ReferenceCount = 1;
+#if MI_TRACE_PFNS
+            Pfn1->PfnUsage = MI_USAGE_PFN_DATABASE;
+#endif
         }
         
         /* Next */
@@ -923,6 +955,7 @@ MiBuildPfnDatabaseSelf(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiInitializePfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     /* Scan memory and start setting up PFN entries */
@@ -940,6 +973,7 @@ MiInitializePfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
 {
     /* This function needs to do more work, for now, we tune page minimums */
@@ -954,6 +988,7 @@ MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiNotifyMemoryEvents(VOID)
 {
     /* Are we in a low-memory situation? */
@@ -979,6 +1014,7 @@ MiNotifyMemoryEvents(VOID)
 
 NTSTATUS
 NTAPI
+INIT_FUNCTION
 MiCreateMemoryEvent(IN PUNICODE_STRING Name,
                     OUT PKEVENT *Event)
 {
@@ -1073,6 +1109,7 @@ CleanUp:
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 MiInitializeMemoryEvents(VOID)
 {
     UNICODE_STRING LowString = RTL_CONSTANT_STRING(L"\\KernelObjects\\LowMemoryCondition");
@@ -1151,6 +1188,7 @@ MiInitializeMemoryEvents(VOID)
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiAddHalIoMappings(VOID)
 {
     PVOID BaseAddress;
@@ -1206,24 +1244,53 @@ MiAddHalIoMappings(VOID)
 
 VOID
 NTAPI
-MmDumpArmPfnDatabase(VOID)
+MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
 {
     ULONG i;
     PMMPFN Pfn1;
     PCHAR Consumer = "Unknown";
     KIRQL OldIrql;
     ULONG ActivePages = 0, FreePages = 0, OtherPages = 0;
-    
-    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-    
+#if MI_TRACE_PFNS
+    ULONG UsageBucket[MI_USAGE_FREE_PAGE + 1] = {0};
+    PCHAR MI_USAGE_TEXT[MI_USAGE_FREE_PAGE + 1] =
+    {
+        "Not set",
+        "Paged Pool",
+        "Nonpaged Pool",
+        "Nonpaged Pool Ex",
+        "Kernel Stack",
+        "Kernel Stack Ex",
+        "System PTE",
+        "VAD",
+        "PEB/TEB",
+        "Section",
+        "Page Table",
+        "Page Directory",
+        "Old Page Table",
+        "Driver Page",
+        "Contiguous Alloc",
+        "MDL",
+        "Demand Zero",
+        "Zero Loop",
+        "Cache",
+        "PFN Database",
+        "Boot Driver",
+        "Initial Memory",
+        "Free Page"
+    };
+#endif
     //
     // Loop the PFN database
     //
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
     for (i = 0; i <= MmHighestPhysicalPage; i++)
     {
         Pfn1 = MiGetPfnEntry(i);
         if (!Pfn1) continue;
-        
+#if MI_TRACE_PFNS
+        ASSERT(Pfn1->PfnUsage <= MI_USAGE_FREE_PAGE);
+#endif
         //
         // Get the page location
         //
@@ -1234,12 +1301,18 @@ MmDumpArmPfnDatabase(VOID)
                 Consumer = "Active and Valid";
                 ActivePages++;
                 break;
-                
+   
+            case ZeroedPageList:
+
+                Consumer = "Zero Page List";
+                FreePages++;
+                break;//continue;
+                                 
             case FreePageList:
                 
                 Consumer = "Free Page List";
                 FreePages++;
-                break;
+                break;//continue;
                 
             default:
                 
@@ -1247,23 +1320,55 @@ MmDumpArmPfnDatabase(VOID)
                 OtherPages++;
                 break;
         }
-                
+        
+#if MI_TRACE_PFNS
+        /* Add into bucket */
+        UsageBucket[Pfn1->PfnUsage]++;
+#endif
+
         //
         // Pretty-print the page
         //
-        DbgPrint("0x%08p:\t%20s\t(%02d.%02d) [%08p-%08p])\n",
+        if (!StatusOnly)
+        DbgPrint("0x%08p:\t%20s\t(%04d.%04d)\t[%16s - %16s])\n",
                  i << PAGE_SHIFT,
                  Consumer,
                  Pfn1->u3.e2.ReferenceCount,
-                 Pfn1->u2.ShareCount,
-                 Pfn1->PteAddress,
-                 Pfn1->u4.PteFrame);
+                 Pfn1->u2.ShareCount == LIST_HEAD ? 0xFFFF : Pfn1->u2.ShareCount,
+#if MI_TRACE_PFNS
+                 MI_USAGE_TEXT[Pfn1->PfnUsage],
+                 Pfn1->ProcessName);
+#else
+                 "Page tracking",
+                 "is disabled");
+#endif
     }
     
-    DbgPrint("Active:               %d pages\t[%d KB]\n", ActivePages,  (ActivePages    << PAGE_SHIFT) / 1024);
-    DbgPrint("Free:                 %d pages\t[%d KB]\n", FreePages,    (FreePages      << PAGE_SHIFT) / 1024);
-    DbgPrint("Other:                %d pages\t[%d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
-    
+    DbgPrint("Active:               %5d pages\t[%6d KB]\n", ActivePages,  (ActivePages    << PAGE_SHIFT) / 1024);
+    DbgPrint("Free:                 %5d pages\t[%6d KB]\n", FreePages,    (FreePages      << PAGE_SHIFT) / 1024);
+    DbgPrint("-----------------------------------------\n");
+#if MI_TRACE_PFNS
+    OtherPages = UsageBucket[MI_USAGE_BOOT_DRIVER];
+    DbgPrint("Boot Images:          %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_DRIVER_PAGE];
+    DbgPrint("System Drivers:       %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_PFN_DATABASE];
+    DbgPrint("PFN Database:         %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_PAGE_TABLE] + UsageBucket[MI_USAGE_LEGACY_PAGE_DIRECTORY];
+    DbgPrint("Page Tables:          %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_NONPAGED_POOL] + UsageBucket[MI_USAGE_NONPAGED_POOL_EXPANSION];
+    DbgPrint("NonPaged Pool:        %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_PAGED_POOL];
+    DbgPrint("Paged Pool:           %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_KERNEL_STACK] + UsageBucket[MI_USAGE_KERNEL_STACK_EXPANSION];
+    DbgPrint("Kernel Stack:         %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_INIT_MEMORY];
+    DbgPrint("Init Memory:          %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_SECTION];
+    DbgPrint("Sections:             %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+    OtherPages = UsageBucket[MI_USAGE_CACHE];
+    DbgPrint("Cache:                %5d pages\t[%6d KB]\n", OtherPages,   (OtherPages     << PAGE_SHIFT) / 1024);
+#endif
     KeLowerIrql(OldIrql);
 }
 
@@ -1311,6 +1416,7 @@ MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
 PPHYSICAL_MEMORY_DESCRIPTOR
 NTAPI
+INIT_FUNCTION
 MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                          IN PBOOLEAN IncludeType)
 {
@@ -1447,6 +1553,7 @@ MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
 VOID
 NTAPI
+INIT_FUNCTION
 MiBuildPagedPool(VOID)
 {
     PMMPTE PointerPte, PointerPde;
@@ -1454,7 +1561,7 @@ MiBuildPagedPool(VOID)
     PFN_NUMBER PageFrameIndex;
     KIRQL OldIrql;
     ULONG Size, BitMapSize;
-    
+#if (_MI_PAGING_LEVELS == 2)
     //
     // Get the page frame number for the system page directory
     //
@@ -1480,7 +1587,7 @@ MiBuildPagedPool(VOID)
     ASSERT(PD_COUNT == 1);
     TempPte.u.Hard.PageFrameNumber = MmSystemPageDirectory[0];
     MI_WRITE_VALID_PTE(PointerPte, TempPte);
-
+#endif
     //
     // Let's get back to paged pool work: size it up.
     // By default, it should be twice as big as nonpaged pool.
@@ -1532,6 +1639,14 @@ MiBuildPagedPool(VOID)
     // So now get the PDE for paged pool and zero it out
     //
     PointerPde = MiAddressToPde(MmPagedPoolStart);
+    
+#if (_MI_PAGING_LEVELS >= 3)
+    /* On these systems, there's no double-mapping, so instead, the PPE and PXEs
+     * are setup to span the entire paged pool area, so there's no need for the
+     * system PD */
+     ASSERT(FALSE);
+#endif
+
     RtlZeroMemory(PointerPde,
                   (1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * sizeof(MMPTE));
 
@@ -1548,14 +1663,24 @@ MiBuildPagedPool(VOID)
     OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
     /* Allocate a page and map the first paged pool PDE */
+    MI_SET_USAGE(MI_USAGE_PAGED_POOL);
+    MI_SET_PROCESS2("Kernel");
     PageFrameIndex = MiRemoveZeroPage(0);
     TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
     MI_WRITE_VALID_PTE(PointerPde, TempPte);
+#if (_MI_PAGING_LEVELS >= 3)
+    /* Use the PPE of MmPagedPoolStart that was setup above */
+//    Bla = PFN_FROM_PTE(PpeAddress(MmPagedPool...));
+    ASSERT(FALSE);
+#else
+    /* Do it this way */
+//    Bla = MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]
 
     /* Initialize the PFN entry for it */
     MiInitializePfnForOtherProcess(PageFrameIndex,
                                    PointerPde,
                                    MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]);
+#endif
 
     //
     // Release the PFN database lock
@@ -1632,10 +1757,66 @@ MiBuildPagedPool(VOID)
     MiHighPagedPoolThreshold = (60 * _1MB) >> PAGE_SHIFT;
     MiHighPagedPoolThreshold = min(MiHighPagedPoolThreshold, (Size * 2) / 5);
     ASSERT(MiLowPagedPoolThreshold < MiHighPagedPoolThreshold);
+    
+    /* Setup the global session space */
+    MiInitializeSystemSpaceMap(NULL);
 }
 
-NTSTATUS
+VOID
 NTAPI
+INIT_FUNCTION
+MiDbgDumpMemoryDescriptors(VOID)
+{
+    PLIST_ENTRY NextEntry;
+    PMEMORY_ALLOCATION_DESCRIPTOR Md;
+    ULONG TotalPages = 0;
+    PCHAR
+    MemType[] =
+    {
+        "ExceptionBlock    ",
+        "SystemBlock       ",
+        "Free              ",
+        "Bad               ",
+        "LoadedProgram     ",
+        "FirmwareTemporary ",
+        "FirmwarePermanent ",
+        "OsloaderHeap      ",
+        "OsloaderStack     ",
+        "SystemCode        ",
+        "HalCode           ",
+        "BootDriver        ",
+        "ConsoleInDriver   ",
+        "ConsoleOutDriver  ",
+        "StartupDpcStack   ",
+        "StartupKernelStack",
+        "StartupPanicStack ",
+        "StartupPcrPage    ",
+        "StartupPdrPage    ",
+        "RegistryData      ",
+        "MemoryData        ",
+        "NlsData           ",
+        "SpecialMemory     ",
+        "BBTMemory         ",
+        "LoaderReserve     ",
+        "LoaderXIPRom      "
+    };
+    
+    DPRINT1("Base\t\tLength\t\tType\n");
+    for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
+         NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
+         NextEntry = NextEntry->Flink)
+    {
+        Md = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
+        DPRINT1("%08lX\t%08lX\t%s\n", Md->BasePage, Md->PageCount, MemType[Md->MemoryType]);
+        TotalPages += Md->PageCount;
+    }
+
+    DPRINT1("Total: %08lX (%d MB)\n", TotalPages, (TotalPages * PAGE_SIZE) / 1024 / 1024);
+}
+
+BOOLEAN
+NTAPI
+INIT_FUNCTION
 MmArmInitSystem(IN ULONG Phase,
                 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
@@ -1645,6 +1826,9 @@ MmArmInitSystem(IN ULONG Phase,
     PPHYSICAL_MEMORY_RUN Run;
     PFN_NUMBER PageCount;
     
+    /* Dump memory descriptors */
+    if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors();
+        
     //
     // Instantiate memory that we don't consider RAM/usable
     // We use the same exclusions that Windows does, in order to try to be
@@ -1678,7 +1862,10 @@ MmArmInitSystem(IN ULONG Phase,
         /* Highest PTE and PDE based on the addresses above */
         MiHighestUserPte = MiAddressToPte(MmHighestUserAddress);
         MiHighestUserPde = MiAddressToPde(MmHighestUserAddress);
-        
+#if (_MI_PAGING_LEVELS >= 3)
+        /* We need the highest PPE and PXE addresses */
+        ASSERT(FALSE);
+#endif
         //
         // Get the size of the boot loader's image allocations and then round
         // that region up to a PDE size, so that any PDEs we might create for
@@ -1766,7 +1953,11 @@ MmArmInitSystem(IN ULONG Phase,
         
         /* Initialize the Loader Lock */
         KeInitializeMutant(&MmSystemLoadLock, FALSE);        
-                                    
+
+        /* Set the zero page event */
+        KeInitializeEvent(&MmZeroingPageEvent, SynchronizationEvent, FALSE);
+        MmZeroingPageThreadActive = FALSE;
+                                            
         //
         // Count physical pages on the system
         //
@@ -1799,17 +1990,48 @@ MmArmInitSystem(IN ULONG Phase,
         
         DPRINT("System PTE count has been tuned to %d (%d bytes)\n",
                MmNumberOfSystemPtes, MmNumberOfSystemPtes * PAGE_SIZE);
+               
+        /* Initialize the working set lock */
+        ExInitializePushLock((PULONG_PTR)&MmSystemCacheWs.WorkingSetMutex);
+        
+        /* Set commit limit */
+        MmTotalCommitLimit = 2 * _1GB;
+        MmTotalCommitLimitMaximum = MmTotalCommitLimit;
+        
+        /* Has the allocation fragment been setup? */
+        if (!MmAllocationFragment)
+        {
+            /* Use the default value */
+            MmAllocationFragment = MI_ALLOCATION_FRAGMENT;
+            if (PageCount < ((256 * _1MB) / PAGE_SIZE))
+            {
+                /* On memory systems with less than 256MB, divide by 4 */
+                MmAllocationFragment = MI_ALLOCATION_FRAGMENT / 4;
+            }
+            else if (PageCount < (_1GB / PAGE_SIZE))
+            {
+                /* On systems with less than 1GB, divide by 2 */
+                MmAllocationFragment = MI_ALLOCATION_FRAGMENT / 2;
+            }
+        }
+        else
+        {
+            /* Convert from 1KB fragments to pages */
+            MmAllocationFragment *= _1KB;
+            MmAllocationFragment = ROUND_TO_PAGES(MmAllocationFragment);
+            
+            /* Don't let it past the maximum */
+            MmAllocationFragment = min(MmAllocationFragment,
+                                       MI_MAX_ALLOCATION_FRAGMENT);
+            
+            /* Don't let it too small either */
+            MmAllocationFragment = max(MmAllocationFragment,
+                                       MI_MIN_ALLOCATION_FRAGMENT);
+        }
         
         /* Initialize the platform-specific parts */       
         MiInitMachineDependent(LoaderBlock);
-        
-        //
-        // Sync us up with ReactOS Mm
-        //
-        MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
-        MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
-        MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
-      
+
         //
         // Build the physical memory block
         //
@@ -1889,12 +2111,12 @@ MmArmInitSystem(IN ULONG Phase,
         /* FIXME: Call out into Driver Verifier for initialization  */
 
         /* Check how many pages the system has */
-        if (MmNumberOfPhysicalPages <= (13 * _1MB))
+        if (MmNumberOfPhysicalPages <= ((13 * _1MB) / PAGE_SIZE))
         {
             /* Set small system */
             MmSystemSize = MmSmallSystem;
         }
-        else if (MmNumberOfPhysicalPages <= (19 * _1MB))
+        else if (MmNumberOfPhysicalPages <= ((19 * _1MB) / PAGE_SIZE))
         {
             /* Set small system and add 100 pages for the cache */
             MmSystemSize = MmSmallSystem;
@@ -1986,11 +2208,19 @@ MmArmInitSystem(IN ULONG Phase,
             return FALSE;
         }
         
+        /* Initialize the system cache */
+        //MiInitializeSystemCache(MmSystemCacheWsMinimum, MmAvailablePages);
+        
+        /* Update the commit limit */
+        MmTotalCommitLimit = MmAvailablePages;
+        if (MmTotalCommitLimit > 1024) MmTotalCommitLimit -= 1024;
+        MmTotalCommitLimitMaximum = MmTotalCommitLimit;
+        
         /* Size up paged pool and build the shadow system page directory */
         MiBuildPagedPool();
         
         /* Debugger physical memory support is now ready to be used */
-        MiDbgReadyForPhysical = TRUE;
+        MmDebugPte = MiAddressToPte(MiDebugMapping);
 
         /* Initialize the loaded module list */
         MiInitializeLoadedModuleList(LoaderBlock);
@@ -1999,7 +2229,7 @@ MmArmInitSystem(IN ULONG Phase,
     //
     // Always return success for now
     //
-    return STATUS_SUCCESS;
+    return TRUE;
 }
 
 /* EOF */