Sync with trunk (48237)
[reactos.git] / ntoskrnl / mm / ARM3 / mminit.c
index 63be4f6..28358f1 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,7 +151,7 @@ PMMPTE MiSessionLastPte;
 // By default, it is a 16MB region.
 //
 PVOID MiSystemViewStart;
-ULONG MmSystemViewSize;
+SIZE_T MmSystemViewSize;
 
 //
 // A copy of the system page directory (the page directory associated with the
@@ -175,13 +175,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 +205,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,13 +215,13 @@ 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;
 
@@ -328,8 +328,29 @@ PFN_NUMBER MmSystemCacheWsMaximum = 350;
 /* FIXME: Move to cache/working set code later */
 BOOLEAN MmLargeSystemCache;
 
+/*
+ * 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;
+
+/*
+ * 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;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
+#ifndef _M_AMD64
 //
 // In Bavaria, this is probably a hate crime
 //
@@ -341,17 +362,18 @@ MiSyncARM3WithROS(IN PVOID AddressStart,
     //
     // Puerile piece of junk-grade carbonized horseshit puss sold to the lowest bidder
     //
-    ULONG Pde = MiGetPdeOffset(AddressStart);
-    while (Pde <= MiGetPdeOffset(AddressEnd))
+    ULONG Pde = ADDR_TO_PDE_OFFSET(AddressStart);
+    while (Pde <= ADDR_TO_PDE_OFFSET(AddressEnd))
     {
         //
         // This both odious and heinous
         //
-        extern ULONG MmGlobalKernelPageDirectory[];
+        extern ULONG MmGlobalKernelPageDirectory[1024];
         MmGlobalKernelPageDirectory[Pde] = ((PULONG)PDE_BASE)[Pde];
         Pde++;
     }
 }
+#endif
 
 PFN_NUMBER
 NTAPI
@@ -387,10 +409,10 @@ MiComputeColorInformation(VOID)
     if (!MmSecondaryColors)
     {
         /* Get L2 cache information */
-        L2Associativity = KiGetSecondLevelDCacheSize();
+        L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
         
         /* The number of colors is the number of cache bytes by set/way */
-        MmSecondaryColors = KiGetSecondLevelDCacheSize();
+        MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
         if (L2Associativity) MmSecondaryColors /= L2Associativity;
     }
     
@@ -439,7 +461,7 @@ MiInitializeColorTables(VOID)
     MMPTE TempPte = ValidKernelPte;
     
     /* The color table starts after the ARM3 PFN database */
-    MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[1][MmHighestPhysicalPage + 1];
+    MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[MmHighestPhysicalPage + 1];
     
     /* Loop the PTEs. We have two color tables for each secondary color */
     PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]);
@@ -453,9 +475,8 @@ MiInitializeColorTables(VOID)
         {
             /* Get a page and map it */
             TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1);
-            ASSERT(TempPte.u.Hard.Valid == 1);
-            *PointerPte = TempPte;
-            
+            MI_WRITE_VALID_PTE(PointerPte, TempPte);
+
             /* Zero out the page */
             RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
         }
@@ -585,50 +606,8 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
         }
         
         /* 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++;
-        }
-        
-        /* Get the PTEs for this range */
-        PointerPte = MiAddressToPte(&MmPfnDatabase[1][BasePage]);
-        LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[1][BasePage + PageCount]) - 1);
+        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 */
@@ -656,9 +635,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                 
                 /* Write out this PTE */
                 PagesLeft++;
-                ASSERT(PointerPte->u.Hard.Valid == 0);
-                ASSERT(TempPte.u.Hard.Valid == 1);
-                *PointerPte = TempPte;
+                MI_WRITE_VALID_PTE(PointerPte, TempPte);
                 
                 /* Zero this page */
                 RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
@@ -667,7 +644,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
             /* Next! */
             PointerPte++;
         }
-        
+
         /* Do the next address range */
         NextEntry = MdBlock->ListEntry.Flink;
     }
@@ -706,9 +683,9 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
             if (MiIsRegularMemory(LoaderBlock, PageFrameIndex))
             {
                 /* Yes we do, set it up */
-                Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+                Pfn1 = MiGetPfnEntry(PageFrameIndex);
                 Pfn1->u4.PteFrame = StartupPdIndex;
-                Pfn1->PteAddress = (PMMPTE)PointerPde;
+                Pfn1->PteAddress = PointerPde;
                 Pfn1->u2.ShareCount++;
                 Pfn1->u3.e2.ReferenceCount = 1;
                 Pfn1->u3.e1.PageLocation = ActiveAndValid;
@@ -745,7 +722,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                                             MmSizeOfNonPagedPoolInBytes)))
                         {
                             /* Get the PFN entry and make sure it too is valid */
-                            Pfn2 = MI_PFN_TO_PFNENTRY(PtePageIndex);
+                            Pfn2 = MiGetPfnEntry(PtePageIndex);
                             if ((MmIsAddressValid(Pfn2)) &&
                                 (MmIsAddressValid(Pfn2 + 1)))
                             {
@@ -785,13 +762,13 @@ MiBuildPfnDatabaseZeroPage(VOID)
     PMMPDE PointerPde;
     
     /* Grab the lowest page and check if it has no real references */
-    Pfn1 = MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage);
+    Pfn1 = MiGetPfnEntry(MmLowestPhysicalPage);
     if (!(MmLowestPhysicalPage) && !(Pfn1->u3.e2.ReferenceCount))
     {
         /* Make it a bogus page to catch errors */
         PointerPde = MiAddressToPde(0xFFFFFFFF);
         Pfn1->u4.PteFrame = PFN_FROM_PTE(PointerPde);
-        Pfn1->PteAddress = (PMMPTE)PointerPde;
+        Pfn1->PteAddress = PointerPde;
         Pfn1->u2.ShareCount++;
         Pfn1->u3.e2.ReferenceCount = 0xFFF0;
         Pfn1->u3.e1.PageLocation = ActiveAndValid;
@@ -810,6 +787,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     PMMPFN Pfn1;
     PMMPTE PointerPte;
     PMMPDE PointerPde;
+    KIRQL OldIrql;
     
     /* Now loop through the descriptors */
     NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
@@ -860,14 +838,18 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
                 /* Get the last page of this descriptor. Note we loop backwards */
                 PageFrameIndex += PageCount - 1;
-                Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+                Pfn1 = MiGetPfnEntry(PageFrameIndex);
+                
+                /* Lock the PFN Database */
+                OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
                 while (PageCount--)
                 {
                     /* If the page really has no references, mark it as free */
                     if (!Pfn1->u3.e2.ReferenceCount)
                     {
+                        /* Add it to the free list */
                         Pfn1->u3.e1.CacheAttribute = MiNonCached;
-                        //MiInsertPageInFreeList(PageFrameIndex);
+                        MiInsertPageInFreeList(PageFrameIndex);
                     }
 
                     /* Go to the next page */
@@ -875,6 +857,9 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                     PageFrameIndex--;
                 }
                 
+                /* Release PFN database */
+                KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+                
                 /* Done with this block */
                 break;
 
@@ -890,7 +875,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
                 /* Map these pages with the KSEG0 mapping that adds 0x80000000 */
                 PointerPte = MiAddressToPte(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT));
-                Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+                Pfn1 = MiGetPfnEntry(PageFrameIndex);
                 while (PageCount--)
                 {
                     /* Check if the page is really unused */
@@ -940,15 +925,15 @@ MiBuildPfnDatabaseSelf(VOID)
     PMMPFN Pfn1;
     
     /* Loop the PFN database page */
-    PointerPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage));
-    LastPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmHighestPhysicalPage));
+    PointerPte = MiAddressToPte(MiGetPfnEntry(MmLowestPhysicalPage));
+    LastPte = MiAddressToPte(MiGetPfnEntry(MmHighestPhysicalPage));
     while (PointerPte <= LastPte)
     {
         /* Make sure the page is valid */
         if (PointerPte->u.Hard.Valid == 1)
         {
             /* Get the PFN entry and just mark it referenced */
-            Pfn1 = MI_PFN_TO_PFNENTRY(PointerPte->u.Hard.PageFrameNumber);
+            Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
             Pfn1->u2.ShareCount = 1;
             Pfn1->u3.e2.ReferenceCount = 1;
         }
@@ -1202,7 +1187,7 @@ MiAddHalIoMappings(VOID)
 
     /* Check how many PDEs the heap has */
     PointerPde = MiAddressToPde(BaseAddress);
-    PdeCount = PDE_COUNT - MiGetPdeOffset(BaseAddress);
+    PdeCount = PDE_COUNT - ADDR_TO_PDE_OFFSET(BaseAddress);
     for (i = 0; i < PdeCount; i++)
     {
         /* Does the HAL own this mapping? */
@@ -1258,7 +1243,7 @@ MmDumpArmPfnDatabase(VOID)
     //
     for (i = 0; i <= MmHighestPhysicalPage; i++)
     {
-        Pfn1 = MI_PFN_TO_PFNENTRY(i);
+        Pfn1 = MiGetPfnEntry(i);
         if (!Pfn1) continue;
         
         //
@@ -1486,10 +1471,8 @@ VOID
 NTAPI
 MiBuildPagedPool(VOID)
 {
-    PMMPTE PointerPte;
-    PMMPDE PointerPde;
+    PMMPTE PointerPte, PointerPde;
     MMPTE TempPte = ValidKernelPte;
-    MMPDE TempPde = ValidKernelPde;
     PFN_NUMBER PageFrameIndex;
     KIRQL OldIrql;
     ULONG Size, BitMapSize;
@@ -1518,9 +1501,7 @@ MiBuildPagedPool(VOID)
     TempPte = ValidKernelPte;
     ASSERT(PD_COUNT == 1);
     TempPte.u.Hard.PageFrameNumber = MmSystemPageDirectory[0];
-    ASSERT(PointerPte->u.Hard.Valid == 0);
-    ASSERT(TempPte.u.Hard.Valid == 1);
-    *PointerPte = TempPte;
+    MI_WRITE_VALID_PTE(PointerPte, TempPte);
 
     //
     // Let's get back to paged pool work: size it up.
@@ -1588,14 +1569,15 @@ MiBuildPagedPool(VOID)
     //
     OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
-    //
-    // Allocate a page and map the first paged pool PDE
-    //
-    PageFrameIndex = MmAllocPage(MC_NPPOOL);
-    TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
-    ASSERT(PointerPde->u.Hard.Valid == 0);
-    ASSERT(TempPde.u.Hard.Valid == 1);
-    *PointerPde = TempPde;
+    /* Allocate a page and map the first paged pool PDE */
+    PageFrameIndex = MiRemoveZeroPage(0);
+    TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
+    MI_WRITE_VALID_PTE(PointerPde, TempPte);
+
+    /* Initialize the PFN entry for it */
+    MiInitializePfnForOtherProcess(PageFrameIndex,
+                                   PointerPde,
+                                   MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]);
 
     //
     // Release the PFN database lock
@@ -1607,7 +1589,7 @@ MiBuildPagedPool(VOID)
     // will be allocated to handle paged pool growth. This is where they'll have
     // to start.
     //
-    MmPagedPoolInfo.NextPdeForPagedPoolExpansion = (PMMPTE)(PointerPde + 1);
+    MmPagedPoolInfo.NextPdeForPagedPoolExpansion = PointerPde + 1;
 
     //
     // We keep track of each page via a bit, so check how big the bitmap will
@@ -1839,6 +1821,44 @@ 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);
@@ -1847,7 +1867,7 @@ MmArmInitSystem(IN ULONG Phase,
         // Sync us up with ReactOS Mm
         //
         MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
-        MiSyncARM3WithROS(MmPfnDatabase[0], (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
+        MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
         MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
       
         //
@@ -1929,12 +1949,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;
@@ -2026,8 +2046,22 @@ 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 */
+        MmDebugPte = MiAddressToPte(MiDebugMapping);
+
+        /* Initialize the loaded module list */
+        MiInitializeLoadedModuleList(LoaderBlock);
     }
     
     //