[ros-diffs] [sir_richard] 45566: [NTOS]: Move more functions from the i386 ARM3 directory to the portable/shared directory, since they apply to all architectures. [NTOS]: Refactor the mapping of the PTEs for the PFN database into MiMapPfnDatabase and move the code to portable directory. [NTOS]: Move and refactor some other definitions, and make some numbers more portable by defining arch-specific subvalues. [NTOS]: Make the PFN database actually 2 PFN Databases: MmPfnDatabase[0] which is the ReactOS mapping of PHYSICAL_PAGE structures, and MmPfnDatabase[1] which will be the ARM3 mapping of MMPFN structures. The latter is as-of-yet unused, but memory for it is now being reserved.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Thu Feb 11 01:01:32 CET 2010


Author: sir_richard
Date: Thu Feb 11 01:01:32 2010
New Revision: 45566

URL: http://svn.reactos.org/svn/reactos?rev=45566&view=rev
Log:
[NTOS]: Move more functions from the i386 ARM3 directory to the portable/shared directory, since they apply to all architectures.
[NTOS]: Refactor the mapping of the PTEs for the PFN database into MiMapPfnDatabase and move the code to portable directory.
[NTOS]: Move and refactor some other definitions, and make some numbers more portable by defining arch-specific subvalues.
[NTOS]: Make the PFN database actually 2 PFN Databases: MmPfnDatabase[0] which is the ReactOS mapping of PHYSICAL_PAGE structures, and MmPfnDatabase[1] which will be the ARM3 mapping of MMPFN structures. The latter is as-of-yet unused, but memory for it is now being reserved.

Modified:
    trunk/reactos/ntoskrnl/include/internal/mm.h
    trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
    trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
    trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
    trunk/reactos/ntoskrnl/mm/freelist.c
    trunk/reactos/ntoskrnl/mm/mminit.c

Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/mm.h?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -365,7 +365,7 @@
     } u4;
 } MMPFN, *PMMPFN;
 
-extern PMMPFN MmPfnDatabase;
+extern PMMPFN MmPfnDatabase[2];
 
 typedef struct _MMPFNLIST
 {
@@ -1098,7 +1098,7 @@
     if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, Pfn))) return NULL;
 
     /* Get the entry */
-    Page = &MmPfnDatabase[Pfn];
+    Page = &MmPfnDatabase[0][Pfn];
 
     /* Make sure it's valid */
     ASSERT_PFN(Page);
@@ -1114,7 +1114,7 @@
     //
     // This will return the Page Frame Number (PFN) from the MMPFN
     //
-    return Pfn1 - MmPfnDatabase;
+    return Pfn1 - MmPfnDatabase[0];
 }
 
 PFN_TYPE

Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -18,41 +18,9 @@
 
 /* GLOBALS ********************************************************************/
 
-//
-// Before we have a PFN database, memory comes straight from our physical memory
-// blocks, which is nice because it's guaranteed contiguous and also because once
-// we take a page from here, the system doesn't see it anymore.
-// However, once the fun is over, those pages must be re-integrated back into
-// PFN society life, and that requires us keeping a copy of the original layout
-// so that we can parse it later.
-//
-PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
-MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
-
 /* Template PTE and PDE for a kernel page */
 MMPTE ValidKernelPde = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
 MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1, .u.Hard.Accessed = 1};
-
-/*
- * For each page's worth bytes of L2 cache in a given set/way line, the zero and
- * free lists are organized in what is called a "color".
- *
- * This array points to the two lists, so it can be thought of as a multi-dimensional
- * array of MmFreePagesByColor[2][MmSecondaryColors]. Since the number is dynamic,
- * we describe the array in pointer form instead.
- *
- * On a final note, the color tables themselves are right after the PFN database.
- */
-C_ASSERT(FreePageList == 1);
-PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
-
-/* Make the code cleaner with some definitions for size multiples */
-#define _1KB (1024)
-#define _1MB (1000 * _1KB)
-
-/* Architecture specific size of a PDE directory, and size of a page table */
-#define PDE_SIZE (4096 * sizeof(MMPDE))
-#define PT_SIZE  (1024 * sizeof(MMPTE))
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
@@ -171,109 +139,6 @@
     }
 }
 
-VOID
-NTAPI
-MiComputeColorInformation(VOID)
-{
-    ULONG L2Associativity;
-    
-    /* Check if no setting was provided already */
-    if (!MmSecondaryColors)
-    {
-        /* Get L2 cache information */
-        L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
-        
-        /* The number of colors is the number of cache bytes by set/way */
-        MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
-        if (L2Associativity) MmSecondaryColors /= L2Associativity;
-    }
-    
-    /* Now convert cache bytes into pages */
-    MmSecondaryColors >>= PAGE_SHIFT;
-    if (!MmSecondaryColors)
-    {
-        /* If there was no cache data from the KPCR, use the default colors */
-        MmSecondaryColors = MI_SECONDARY_COLORS;
-    }
-    else
-    {
-        /* Otherwise, make sure there aren't too many colors */
-        if (MmSecondaryColors > MI_MAX_SECONDARY_COLORS)
-        {
-            /* Set the maximum */
-            MmSecondaryColors = MI_MAX_SECONDARY_COLORS;
-        }
-        
-        /* Make sure there aren't too little colors */
-        if (MmSecondaryColors < MI_MIN_SECONDARY_COLORS)
-        {
-            /* Set the default */
-            MmSecondaryColors = MI_SECONDARY_COLORS;
-        }
-        
-        /* Finally make sure the colors are a power of two */
-        if (MmSecondaryColors & (MmSecondaryColors - 1))
-        {
-            /* Set the default */
-            MmSecondaryColors = MI_SECONDARY_COLORS;
-        }
-    }
-    
-    /* Compute the mask and store it */
-    MmSecondaryColorMask = MmSecondaryColors - 1;
-    KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;    
-}
-
-VOID
-NTAPI
-MiInitializeColorTables(VOID)
-{
-    ULONG i;
-    PMMPTE PointerPte, LastPte;
-    MMPTE TempPte = ValidKernelPte;
-    
-    /* The color table starts after the PFN database */
-    MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[MmHighestPhysicalPage + 1];
-    
-    /* Loop the PTEs. We have two color tables for each secondary color */
-    PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]);
-    LastPte = MiAddressToPte((ULONG_PTR)MmFreePagesByColor[0] +
-                             (2 * MmSecondaryColors * sizeof(MMCOLOR_TABLES))
-                             - 1);
-    while (PointerPte <= LastPte)
-    {
-        /* Check for valid PTE */
-        if (PointerPte->u.Hard.Valid == 0)
-        {
-            /* Get a page and map it */
-            TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1);
-            ASSERT(TempPte.u.Hard.Valid == 1);
-            *PointerPte = TempPte;
-            
-            /* Zero out the page */
-            RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
-        }
-        
-        /* Next */
-        PointerPte++;
-    }
-    
-    /* Now set the address of the next list, right after this one */
-    MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
-    
-    /* Now loop the lists to set them up */
-    for (i = 0; i < MmSecondaryColors; i++)
-    {
-        /* Set both free and zero lists for each color */
-        MmFreePagesByColor[ZeroedPageList][i].Flink = 0xFFFFFFFF;
-        MmFreePagesByColor[ZeroedPageList][i].Blink = (PVOID)0xFFFFFFFF;
-        MmFreePagesByColor[ZeroedPageList][i].Count = 0;
-        MmFreePagesByColor[FreePageList][i].Flink = 0xFFFFFFFF;
-        MmFreePagesByColor[FreePageList][i].Blink = (PVOID)0xFFFFFFFF;
-        MmFreePagesByColor[FreePageList][i].Count = 0;
-    }
-}
-
 NTSTATUS
 NTAPI
 MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
@@ -286,7 +151,6 @@
     MMPTE TempPde, TempPte;
     PVOID NonPagedPoolExpansionVa;
     ULONG OldCount;
-    PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
 
     /* Check for kernel stack size that's too big */
     if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
@@ -436,10 +300,11 @@
     MiComputeColorInformation();
     
     //
-    // Calculate the number of bytes for the PFN database, and the color tables,
-    // and then convert to pages
+    // Calculate the number of bytes for the PFN database, double it for ARM3,
+    // then add the color tables and convert to pages
     //
     MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN);
+    MxPfnAllocation <<= 1;
     MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2);
     MxPfnAllocation >>= PAGE_SHIFT;
     
@@ -513,13 +378,19 @@
     // with the old memory manager, so we'll create a "Shadow PFN Database"
     // instead, and arbitrarly start it at 0xB0000000.
     //
-    MmPfnDatabase = (PVOID)0xB0000000;
-    ASSERT(((ULONG_PTR)MmPfnDatabase & ((4 * 1024 * 1024) - 1)) == 0);
+    // We actually create two PFN databases, one for ReactOS starting here,
+    // and the next one used for ARM3, which starts right after. The MmPfnAllocation
+    // variable actually holds the size of both (the colored tables come after
+    // the ARM3 PFN database).
+    //
+    MmPfnDatabase[0] = (PVOID)0xB0000000;
+    MmPfnDatabase[1] = &MmPfnDatabase[0][MmHighestPhysicalPage];
+    ASSERT(((ULONG_PTR)MmPfnDatabase[0] & ((4 * 1024 * 1024) - 1)) == 0);
             
     //
     // Non paged pool comes after the PFN database
     //
-    MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase +
+    MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase[0] +
                                   (MxPfnAllocation << PAGE_SHIFT));
 
     //
@@ -567,7 +438,7 @@
     //
     // Now we need pages for the page tables which will map initial NP
     //
-    StartPde = MiAddressToPde(MmPfnDatabase);
+    StartPde = MiAddressToPde(MmPfnDatabase[0]);
     EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart +
                                     MmSizeOfNonPagedPoolInBytes - 1));
     while (StartPde <= EndPde)
@@ -629,134 +500,16 @@
     //
     MiInitializeArmPool();
 
-    //
-    // Get current page data, since we won't be using MxGetNextPage as it
-    // would corrupt our state
-    //
-    FreePage = MxFreeDescriptor->BasePage;
-    FreePageCount = MxFreeDescriptor->PageCount;
-    PagesLeft = 0;
-    
-    //
-    // Loop the memory descriptors
-    //
-    NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
-    while (NextEntry != &KeLoaderBlock->MemoryDescriptorListHead)
-    {
-        //
-        // Get the descriptor
-        //
-        MdBlock = CONTAINING_RECORD(NextEntry,
-                                    MEMORY_ALLOCATION_DESCRIPTOR,
-                                    ListEntry);
-        if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
-            (MdBlock->MemoryType == LoaderBBTMemory) ||
-            (MdBlock->MemoryType == LoaderSpecialMemory))
-        {
-            //
-            // These pages are not part of the PFN database
-            //
-            NextEntry = MdBlock->ListEntry.Flink;
-            continue;
-        }
-        
-        //
-        // Next, check if this is our special free descriptor we've found
-        //
-        if (MdBlock == MxFreeDescriptor)
-        {
-            //
-            // Use the real numbers instead
-            //
-            BasePage = MxOldFreeDescriptor.BasePage;
-            PageCount = MxOldFreeDescriptor.PageCount;
-        }
-        else
-        {
-            //
-            // Use the descriptor's numbers
-            //
-            BasePage = MdBlock->BasePage;
-            PageCount = MdBlock->PageCount;
-        }
-        
-        //
-        // Get the PTEs for this range
-        //
-        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
-        //
-        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++;
-        }
-        
-        //
-        // Do the next address range
-        //
-        NextEntry = MdBlock->ListEntry.Flink;
-    }
-    
-    //
-    // Now update the free descriptors to consume the pages we used up during
-    // the PFN allocation loop
-    //
-    MxFreeDescriptor->BasePage = FreePage;
-    MxFreeDescriptor->PageCount = FreePageCount;
+    /* Map the PFN database pages */
+    MiMapPfnDatabase(LoaderBlock);
     
     /* Initialize the color tables */
     MiInitializeColorTables();
-
-    /* Call back into shitMM to setup the PFN database */
+    
+    /* Build the PFN Database */
+    //MiInitializePfnDatabase(LoaderBlock);
+
+    /* Call back into shitMM to setup the ReactOS PFN database */
     MmInitializePageList();
         
     //

Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -38,6 +38,26 @@
 #define MM_HIGHEST_VAD_ADDRESS \
     (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
 
+/* Make the code cleaner with some definitions for size multiples */
+#define _1KB (1024)
+#define _1MB (1000 * _1KB)
+
+/* Size of a PDE directory, and size of a page table */
+#define PDE_SIZE (PDE_COUNT * sizeof(MMPDE))
+#define PT_SIZE  (PTE_COUNT * sizeof(MMPTE))
+
+/* Architecture specific count of PDEs in a directory, and count of PTEs in a PT */
+#ifdef _M_IX86
+#define PD_COUNT  1
+#define PDE_COUNT 4096
+#define PTE_COUNT 1024
+#elif _M_ARM
+#define PD_COUNT  1
+#define PDE_COUNT 1024
+#define PTE_COUNT 256
+#else
+#error Define these please!
+#endif
 
 //
 // FIXFIX: These should go in ex.h after the pool merge
@@ -190,11 +210,10 @@
 extern ULONG MmSecondaryColorMask;
 extern ULONG MmNumberOfSystemPtes;
 extern ULONG MmMaximumNonPagedPoolPercent;
-
-//
-// Actual (registry-configurable) size of a GUI thread's stack
-//
-ULONG MmLargeStackSize;
+extern ULONG MmLargeStackSize;
+
+#define MI_PFN_TO_PFNENTRY(x)     (&MmPfnDatabase[1][x])
+#define MI_PFNENTRY_TO_PFN(x)     (Pfn - &MmPfnDatabase[1])
 
 NTSTATUS
 NTAPI
@@ -206,6 +225,30 @@
 NTSTATUS
 NTAPI
 MiInitMachineDependent(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+VOID
+NTAPI
+MiComputeColorInformation(
+    VOID
+);
+
+VOID
+NTAPI
+MiMapPfnDatabase(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+VOID
+NTAPI
+MiInitializeColorTables(
+    VOID
+);
+
+VOID
+NTAPI
+MiInitializePfnDatabase(
     IN PLOADER_PARAMETER_BLOCK LoaderBlock
 );
 

Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -234,6 +234,30 @@
 //
 ULONG MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
 
+//
+// Before we have a PFN database, memory comes straight from our physical memory
+// blocks, which is nice because it's guaranteed contiguous and also because once
+// we take a page from here, the system doesn't see it anymore.
+// However, once the fun is over, those pages must be re-integrated back into
+// PFN society life, and that requires us keeping a copy of the original layout
+// so that we can parse it later.
+//
+PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
+MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
+
+/*
+ * For each page's worth bytes of L2 cache in a given set/way line, the zero and
+ * free lists are organized in what is called a "color".
+ *
+ * This array points to the two lists, so it can be thought of as a multi-dimensional
+ * array of MmFreePagesByColor[2][MmSecondaryColors]. Since the number is dynamic,
+ * we describe the array in pointer form instead.
+ *
+ * On a final note, the color tables themselves are right after the PFN database.
+ */
+C_ASSERT(FreePageList == 1);
+PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 //
@@ -281,6 +305,264 @@
     MxFreeDescriptor->BasePage += PageCount;
     MxFreeDescriptor->PageCount -= PageCount;
     return Pfn;
+}
+
+VOID
+NTAPI
+MiComputeColorInformation(VOID)
+{
+    ULONG L2Associativity;
+    
+    /* Check if no setting was provided already */
+    if (!MmSecondaryColors)
+    {
+        /* Get L2 cache information */
+        L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
+        
+        /* The number of colors is the number of cache bytes by set/way */
+        MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
+        if (L2Associativity) MmSecondaryColors /= L2Associativity;
+    }
+    
+    /* Now convert cache bytes into pages */
+    MmSecondaryColors >>= PAGE_SHIFT;
+    if (!MmSecondaryColors)
+    {
+        /* If there was no cache data from the KPCR, use the default colors */
+        MmSecondaryColors = MI_SECONDARY_COLORS;
+    }
+    else
+    {
+        /* Otherwise, make sure there aren't too many colors */
+        if (MmSecondaryColors > MI_MAX_SECONDARY_COLORS)
+        {
+            /* Set the maximum */
+            MmSecondaryColors = MI_MAX_SECONDARY_COLORS;
+        }
+        
+        /* Make sure there aren't too little colors */
+        if (MmSecondaryColors < MI_MIN_SECONDARY_COLORS)
+        {
+            /* Set the default */
+            MmSecondaryColors = MI_SECONDARY_COLORS;
+        }
+        
+        /* Finally make sure the colors are a power of two */
+        if (MmSecondaryColors & (MmSecondaryColors - 1))
+        {
+            /* Set the default */
+            MmSecondaryColors = MI_SECONDARY_COLORS;
+        }
+    }
+    
+    /* Compute the mask and store it */
+    MmSecondaryColorMask = MmSecondaryColors - 1;
+    KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;    
+}
+
+VOID
+NTAPI
+MiInitializeColorTables(VOID)
+{
+    ULONG i;
+    PMMPTE PointerPte, LastPte;
+    MMPTE TempPte = ValidKernelPte;
+    
+    /* The color table starts after the ARM3 PFN database */
+    MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[1][MmHighestPhysicalPage + 1];
+    
+    /* Loop the PTEs. We have two color tables for each secondary color */
+    PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]);
+    LastPte = MiAddressToPte((ULONG_PTR)MmFreePagesByColor[0] +
+                             (2 * MmSecondaryColors * sizeof(MMCOLOR_TABLES))
+                             - 1);
+    while (PointerPte <= LastPte)
+    {
+        /* Check for valid PTE */
+        if (PointerPte->u.Hard.Valid == 0)
+        {
+            /* Get a page and map it */
+            TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1);
+            ASSERT(TempPte.u.Hard.Valid == 1);
+            *PointerPte = TempPte;
+            
+            /* Zero out the page */
+            RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE);
+        }
+        
+        /* Next */
+        PointerPte++;
+    }
+    
+    /* Now set the address of the next list, right after this one */
+    MmFreePagesByColor[1] = &MmFreePagesByColor[0][MmSecondaryColors];
+    
+    /* Now loop the lists to set them up */
+    for (i = 0; i < MmSecondaryColors; i++)
+    {
+        /* Set both free and zero lists for each color */
+        MmFreePagesByColor[ZeroedPageList][i].Flink = 0xFFFFFFFF;
+        MmFreePagesByColor[ZeroedPageList][i].Blink = (PVOID)0xFFFFFFFF;
+        MmFreePagesByColor[ZeroedPageList][i].Count = 0;
+        MmFreePagesByColor[FreePageList][i].Flink = 0xFFFFFFFF;
+        MmFreePagesByColor[FreePageList][i].Blink = (PVOID)0xFFFFFFFF;
+        MmFreePagesByColor[FreePageList][i].Count = 0;
+    }
+}
+
+BOOLEAN
+NTAPI
+MiIsRegularMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                  IN PFN_NUMBER Pfn)
+{
+    PLIST_ENTRY NextEntry;
+    PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+
+    /* Loop the memory descriptors */
+    NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+    while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
+    {
+        /* Get the memory descriptor */
+        MdBlock = CONTAINING_RECORD(NextEntry,
+                                    MEMORY_ALLOCATION_DESCRIPTOR,
+                                    ListEntry);
+
+        /* Check if this PFN could be part of the block */
+        if (Pfn >= (MdBlock->BasePage))
+        {
+            /* Check if it really is part of the block */
+            if (Pfn < (MdBlock->BasePage + MdBlock->PageCount))
+            {
+                /* Check if the block is actually memory we don't map */
+                if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
+                    (MdBlock->MemoryType == LoaderBBTMemory) ||
+                    (MdBlock->MemoryType == LoaderSpecialMemory))
+                {
+                    /* We don't need PFN database entries for this memory */
+                    break;
+                }
+
+                /* This is memory we want to map */
+                return TRUE;
+            }
+        }
+        else
+        {
+            /* Blocks are ordered, so if it's not here, it doesn't exist */
+            break;
+        }
+
+        /* Get to the next descriptor */
+        NextEntry = MdBlock->ListEntry.Flink;
+    }
+
+    /* Check if this PFN is actually from our free memory descriptor */
+    if ((Pfn >= MxOldFreeDescriptor.BasePage) &&
+        (Pfn < MxOldFreeDescriptor.BasePage + MxOldFreeDescriptor.PageCount))
+    {
+        /* We use these pages for initial mappings, so we do want to count them */
+        return TRUE;
+    }
+
+    /* Otherwise this isn't memory that we describe or care about */
+    return FALSE;
+}
+
+VOID
+NTAPI
+MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    ULONG FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
+    PLIST_ENTRY NextEntry;
+    PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+    PMMPTE PointerPte, LastPte;
+    MMPTE TempPte = ValidKernelPte;
+    
+    /* Get current page data, since we won't be using MxGetNextPage as it would corrupt our state */
+    FreePage = MxFreeDescriptor->BasePage;
+    FreePageCount = MxFreeDescriptor->PageCount;
+    PagesLeft = 0;
+    
+    /* Loop the memory descriptors */
+    NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+    while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
+    {
+        /* Get the descriptor */
+        MdBlock = CONTAINING_RECORD(NextEntry,
+                                    MEMORY_ALLOCATION_DESCRIPTOR,
+                                    ListEntry);
+        if ((MdBlock->MemoryType == LoaderFirmwarePermanent) ||
+            (MdBlock->MemoryType == LoaderBBTMemory) ||
+            (MdBlock->MemoryType == LoaderSpecialMemory))
+        {
+            /* These pages are not part of the PFN database */
+            NextEntry = MdBlock->ListEntry.Flink;
+            continue;
+        }
+        
+        /* Next, check if this is our special free descriptor we've found */
+        if (MdBlock == MxFreeDescriptor)
+        {
+            /* Use the real numbers instead */
+            BasePage = MxOldFreeDescriptor.BasePage;
+            PageCount = MxOldFreeDescriptor.PageCount;
+        }
+        else
+        {
+            /* Use the descriptor's numbers */
+            BasePage = MdBlock->BasePage;
+            PageCount = MdBlock->PageCount;
+        }
+        
+        /* 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++;
+        }
+        
+        /* Do the next address range */
+        NextEntry = MdBlock->ListEntry.Flink;
+    }
+    
+    /* Now update the free descriptors to consume the pages we used up during the PFN allocation loop */
+    MxFreeDescriptor->BasePage = FreePage;
+    MxFreeDescriptor->PageCount = FreePageCount;
 }
 
 PFN_NUMBER
@@ -788,7 +1070,7 @@
         // Sync us up with ReactOS Mm
         //
         MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1));
-        MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
+        MiSyncARM3WithROS(MmPfnDatabase[0], (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1));
         MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1));
       
         //

Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -48,7 +48,8 @@
 #define PHYSICAL_PAGE        MMPFN
 #define PPHYSICAL_PAGE       PMMPFN
 
-PPHYSICAL_PAGE MmPfnDatabase;
+/* The first array contains ReactOS PFNs, the second contains ARM3 PFNs */
+PPHYSICAL_PAGE MmPfnDatabase[2];
 
 ULONG MmAvailablePages;
 ULONG MmResidentAvailablePages;
@@ -59,7 +60,7 @@
 SIZE_T MmDriverCommit;
 SIZE_T MmProcessCommit;
 SIZE_T MmPagedPoolCommit;
-SIZE_T MmPeakCommitment;
+SIZE_T MmPeakCommitment; 
 SIZE_T MmtotalCommitLimitMaximum;
 
 MMPFNLIST MmZeroedPageListHead;
@@ -101,7 +102,7 @@
    PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
    ASSERT_PFN(PageDescriptor);
    KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
-   return PageDescriptor - MmPfnDatabase;
+   return PageDescriptor - MmPfnDatabase[0];
 }
 
 VOID
@@ -142,7 +143,7 @@
    }
    PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
    KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
-   return PageDescriptor - MmPfnDatabase;
+   return PageDescriptor - MmPfnDatabase[0];
 }
 
 VOID
@@ -758,9 +759,9 @@
             for (i = 0; i < Md->PageCount; i++)
             {
                 /* Mark it as a free page */
-                MmPfnDatabase[Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
+                MmPfnDatabase[0][Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
                 InsertTailList(&FreeUnzeroedPageListHead,
-                               &MmPfnDatabase[Md->BasePage + i].ListEntry);
+                               &MmPfnDatabase[0][Md->BasePage + i].ListEntry);
                 UnzeroedPageCount++;
                 MmAvailablePages++;
             }
@@ -771,7 +772,7 @@
             for (i = 0; i < Md->PageCount; i++)
             {
                 /* Everything else is used memory */
-                MmPfnDatabase[Md->BasePage + i] = UsedPage;
+                MmPfnDatabase[0][Md->BasePage + i] = UsedPage;
                 NrSystemPages++;
             }
         }
@@ -781,10 +782,10 @@
     for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
     {
         /* Ensure this page was not added previously */
-        ASSERT(MmPfnDatabase[i].Flags.Type == 0);
+        ASSERT(MmPfnDatabase[0][i].Flags.Type == 0);
 
         /* Mark it as used kernel memory */
-        MmPfnDatabase[i] = UsedPage;
+        MmPfnDatabase[0][i] = UsedPage;
         NrSystemPages++;
     }
     
@@ -1082,7 +1083,7 @@
 
    MmAvailablePages--;
 
-   PfnOffset = PageDescriptor - MmPfnDatabase;
+   PfnOffset = PageDescriptor - MmPfnDatabase[0];
    if ((NeedClear) && (Consumer != MC_SYSTEM))
    {
       MiZeroPage(PfnOffset);
@@ -1155,7 +1156,7 @@
          /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
          PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
          KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
-         Pfn = PageDescriptor - MmPfnDatabase;
+         Pfn = PageDescriptor - MmPfnDatabase[0];
          Status = MiZeroPage(Pfn);
 
          oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);

Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=45566&r1=45565&r2=45566&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Thu Feb 11 01:01:32 2010
@@ -109,7 +109,7 @@
     //
     // Protect the PFN database
     //
-    BaseAddress = MmPfnDatabase;
+    BaseAddress = MmPfnDatabase[0];
     Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
                                 MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
                                 &BaseAddress,
@@ -292,8 +292,8 @@
             (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize,
             "Paged Pool");
     DPRINT1("          0x%p - 0x%p\t%s\n",
-            MmPfnDatabase,
-            (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT),
+            MmPfnDatabase[0],
+            (ULONG_PTR)MmPfnDatabase[0] + (MxPfnAllocation << PAGE_SHIFT),
             "PFN Database");
     DPRINT1("          0x%p - 0x%p\t%s\n",
             MmNonPagedPoolStart,




More information about the Ros-diffs mailing list