[ros-diffs] [sir_richard] 45610: [NTOS]: Build the actual ARM3 PFN database.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Thu Feb 18 17:56:54 CET 2010


Author: sir_richard
Date: Thu Feb 18 17:56:54 2010
New Revision: 45610

URL: http://svn.reactos.org/svn/reactos?rev=45610&view=rev
Log:
[NTOS]: Build the actual ARM3 PFN database.

Modified:
    trunk/reactos/ntoskrnl/mm/ARM3/mminit.c

Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?rev=45610&r1=45609&r2=45610&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 18 17:56:54 2010
@@ -636,14 +636,13 @@
             if (MiIsRegularMemory(LoaderBlock, PageFrameIndex))
             {
                 /* Yes we do, set it up */
-                //DPRINT1("PDE is valid, setting up PFN entry\n");
                 Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
                 Pfn1->u4.PteFrame = StartupPdIndex;
                 Pfn1->PteAddress = PointerPde;
                 Pfn1->u2.ShareCount++;
                 Pfn1->u3.e2.ReferenceCount = 1;
                 Pfn1->u3.e1.PageLocation = ActiveAndValid;
-                Pfn1->u3.e1.CacheAttribute = MiCached;
+                Pfn1->u3.e1.CacheAttribute = MiNonCached;
             }
             else
             {
@@ -686,7 +685,7 @@
                                 Pfn2->u2.ShareCount++;
                                 Pfn2->u3.e2.ReferenceCount = 1;
                                 Pfn2->u3.e1.PageLocation = ActiveAndValid;
-                                Pfn2->u3.e1.CacheAttribute = MiCached;
+                                Pfn2->u3.e1.CacheAttribute = MiNonCached;
                             }
                         }
                     }
@@ -712,21 +711,181 @@
 NTAPI
 MiBuildPfnDatabaseZeroPage(VOID)
 {
-    /* FIXME: TODO */
+    PMMPFN Pfn1;
+    PMMPDE PointerPde;
+    
+    /* Grab the lowest page and check if it has no real references */
+    Pfn1 = MI_PFN_TO_PFNENTRY(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 = PointerPde;
+        Pfn1->u2.ShareCount++;
+        Pfn1->u3.e2.ReferenceCount = 0xFFF0;
+        Pfn1->u3.e1.PageLocation = ActiveAndValid;
+        Pfn1->u3.e1.CacheAttribute = MiNonCached;
+    } 
 }
 
 VOID
 NTAPI
 MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
-    /* FIXME: TODO */   
+    PLIST_ENTRY NextEntry;
+    PFN_NUMBER PageCount = 0;
+    PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
+    PFN_NUMBER PageFrameIndex;
+    PMMPFN Pfn1;
+    PMMPTE PointerPte;
+    PMMPDE PointerPde;
+    
+    /* Now loop through the descriptors */
+    NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink;
+    while (NextEntry != &LoaderBlock->MemoryDescriptorListHead)
+    {
+        /* Get the current descriptor */
+        MdBlock = CONTAINING_RECORD(NextEntry,
+                                    MEMORY_ALLOCATION_DESCRIPTOR,
+                                    ListEntry);
+
+        /* Read its data */
+        PageCount = MdBlock->PageCount;
+        PageFrameIndex = MdBlock->BasePage;
+
+        /* Don't allow memory above what the PFN database is mapping */
+        if (PageFrameIndex > MmHighestPhysicalPage)
+        {
+            /* Since they are ordered, everything past here will be larger */
+            break;
+        }
+
+        /* On the other hand, the end page might be higher up... */
+        if ((PageFrameIndex + PageCount) > (MmHighestPhysicalPage + 1))
+        {
+            /* In which case we'll trim the descriptor to go as high as we can */
+            PageCount = MmHighestPhysicalPage + 1 - PageFrameIndex;
+            MdBlock->PageCount = PageCount;
+            
+            /* But if there's nothing left to trim, we got too high, so quit */
+            if (!PageCount) break;
+        }
+
+        /* Now check the descriptor type */
+        switch (MdBlock->MemoryType)
+        {
+            /* Check for bad RAM */
+            case LoaderBad:
+            
+                DPRINT1("You have damaged RAM modules. Stopping boot\n");
+                while (TRUE);
+                break;
+
+            /* Check for free RAM */
+            case LoaderFree:
+            case LoaderLoadedProgram:
+            case LoaderFirmwareTemporary:
+            case LoaderOsloaderStack:
+
+                /* Get the last page of this descriptor. Note we loop backwards */
+                PageFrameIndex += PageCount - 1;
+                Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+                while (PageCount--)
+                {
+                    /* If the page really has no references, mark it as free */
+                    if (!Pfn1->u3.e2.ReferenceCount)
+                    {
+                        Pfn1->u3.e1.CacheAttribute = MiNonCached;
+                        MiInsertPageInFreeList(PageFrameIndex);
+                    }
+
+                    /* Go to the next page */
+                    Pfn1--;
+                    PageFrameIndex--;
+                }
+                
+                /* Done with this block */
+                break;
+
+            /* Check for pages that are invisible to us */
+            case LoaderFirmwarePermanent:
+            case LoaderSpecialMemory:
+            case LoaderBBTMemory:
+
+                /* And skip them */
+                break;
+
+            default:
+
+                /* Map these pages with the KSEG0 mapping that adds 0x80000000 */
+                PointerPte = MiAddressToPte(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT));
+                Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+                while (PageCount--)
+                {
+                    /* Check if the page is really unused */
+                    PointerPde = MiAddressToPde(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT));
+                    if (!Pfn1->u3.e2.ReferenceCount)
+                    {
+                        /* Mark it as being in-use */
+                        Pfn1->u4.PteFrame = PFN_FROM_PTE(PointerPde);
+                        Pfn1->PteAddress = PointerPte;
+                        Pfn1->u2.ShareCount++;
+                        Pfn1->u3.e2.ReferenceCount = 1;
+                        Pfn1->u3.e1.PageLocation = ActiveAndValid;
+                        Pfn1->u3.e1.CacheAttribute = MiNonCached;
+                        
+                        /* Check for RAM disk page */
+                        if (MdBlock->MemoryType == LoaderXIPRom)
+                        {
+                            /* Make it a pseudo-I/O ROM mapping */
+                            Pfn1->u1.Flink = 0;
+                            Pfn1->u2.ShareCount = 0;
+                            Pfn1->u3.e2.ReferenceCount = 0;
+                            Pfn1->u3.e1.PageLocation = 0;
+                            Pfn1->u3.e1.Rom = 1;
+                            Pfn1->u4.InPageError = 0;
+                            Pfn1->u3.e1.PrototypePte = 1;
+                        }
+                    }
+                    
+                    /* Advance page structures */
+                    Pfn1++;
+                    PageFrameIndex++;
+                    PointerPte++;
+                }
+                break;
+        }
+
+        /* Next descriptor entry */
+        NextEntry = MdBlock->ListEntry.Flink;
+    }
 }
 
 VOID
 NTAPI
 MiBuildPfnDatabaseSelf(VOID)
 {
-    /* FIXME: TODO */
+    PMMPTE PointerPte, LastPte;
+    PMMPFN Pfn1;
+    
+    /* Loop the PFN database page */
+    PointerPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage));
+    LastPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(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->u2.ShareCount = 1;
+            Pfn1->u3.e2.ReferenceCount = 1;
+        }
+        
+        /* Next */
+        PointerPte++;
+    }
 }
 
 VOID
@@ -744,6 +903,69 @@
     
     /* Finally add the pages for the PFN database itself */ 
     MiBuildPfnDatabaseSelf();
+}
+
+VOID
+NTAPI
+MmDumpArmPfnDatabase(VOID)
+{
+    ULONG i;
+    PMMPFN Pfn1;
+    PCHAR Consumer = "Unknown";
+    KIRQL OldIrql;
+    ULONG ActivePages = 0, FreePages = 0, OtherPages = 0;
+    
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    //
+    // Loop the PFN database
+    //
+    for (i = 0; i <= MmHighestPhysicalPage; i++)
+    {
+        Pfn1 = MI_PFN_TO_PFNENTRY(i);
+        if (!Pfn1) continue;
+        
+        //
+        // Get the page location
+        //
+        switch (Pfn1->u3.e1.PageLocation)
+        {
+            case ActiveAndValid:
+                
+                Consumer = "Active and Valid";
+                ActivePages++;
+                break;
+                
+            case FreePageList:
+                
+                Consumer = "Free Page List";
+                FreePages++;
+                break;
+                
+            default:
+                
+                Consumer = "Other (ASSERT!)";
+                OtherPages++;
+                break;
+        }
+                
+        //
+        // Pretty-print the page
+        //
+        DbgPrint("0x%08p:\t%20s\t(%02d.%02d) [%08p-%08p])\n",
+                 i << PAGE_SHIFT,
+                 Consumer,
+                 Pfn1->u3.e2.ReferenceCount,
+                 Pfn1->u2.ShareCount,
+                 Pfn1->PteAddress,
+                 Pfn1->u4.PteFrame);
+    }
+    
+    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);
+    
+    KeLowerIrql(OldIrql);
 }
 
 PFN_NUMBER




More information about the Ros-diffs mailing list