[ros-diffs] [ros-arm-bringup] 34857: - Major cleanup, refactoring, and bugfixing of ARM Mm code in preparation for user-mode support. - Sync the code a lot closer to its x86 counterpart, still more work to be done. - Very soon, it should be possible to share upward of 50% of the new ARM code with the x86 version of React as well and unify the implementations.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Sun Jul 27 21:52:42 CEST 2008


Author: ros-arm-bringup
Date: Sun Jul 27 14:52:41 2008
New Revision: 34857

URL: http://svn.reactos.org/svn/reactos?rev=34857&view=rev
Log:
- Major cleanup, refactoring, and bugfixing of ARM Mm code in preparation for user-mode support.
- Sync the code a lot closer to its x86 counterpart, still more work to be done.
- Very soon, it should be possible to share upward of 50% of the new ARM code with the x86 version of React as well and unify the implementations.

Modified:
    trunk/reactos/ntoskrnl/include/internal/arm/mm.h
    trunk/reactos/ntoskrnl/mm/arm/stubs.c

Modified: trunk/reactos/ntoskrnl/include/internal/arm/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/arm/mm.h?rev=34857&r1=34856&r2=34857&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/arm/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/mm.h [iso-8859-1] Sun Jul 27 14:52:41 2008
@@ -147,4 +147,23 @@
     ManagerDomain
 } ARM_DOMAIN;
 
+//
+// Take 0x80812345 and extract:
+// PTE_BASE[0x808][0x12]
+//
+#define MiGetPteAddress(x)         \
+    (PMMPTE)(PTE_BASE + \
+             (((ULONG)(x) >> 20) << 12) + \
+             ((((ULONG)(x) >> 12) & 0xFF) << 2))
+
+#define MiGetPdeAddress(x)         \
+    (PMMPTE)(PDE_BASE + \
+             (((ULONG)(x) >> 20) << 2))
+
+#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
+
+#define PTE_BASE    0xC0000000
+#define PDE_BASE    0xC1000000
+#define HYPER_SPACE ((PVOID)0xC1100000)
+
 #endif

Modified: trunk/reactos/ntoskrnl/mm/arm/stubs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/arm/stubs.c?rev=34857&r1=34856&r2=34857&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] Sun Jul 27 14:52:41 2008
@@ -14,37 +14,255 @@
 
 /* GLOBALS ********************************************************************/
 
-#undef UNIMPLEMENTED
-#define UNIMPLEMENTED \
-{ \
-    DPRINT1("[ARM Mm Bringup]: %s is unimplemented!\n", __FUNCTION__); \
-    while (TRUE); \
-}
-
-//
-// Take 0x80812345 and extract:
-// PTE_BASE[0x808][0x12]
-//
-#define MiGetPteAddress(x)         \
-    (PMMPTE)(PTE_BASE + (((ULONG)(x) >> 20) << 12) + ((((ULONG)(x) >> 12) & 0xFF) << 2))
-
-#define MiGetPdeAddress(x)         \
-    (PMMPTE)(PDE_BASE + (((ULONG)(x) >> 20) << 2))
-
-#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
-
-#define PTE_BASE    0xC0000000
-#define PDE_BASE    0xC1000000
-#define HYPER_SPACE ((PVOID)0xC1100000)
-
 ULONG MmGlobalKernelPageDirectory[1024];
 MMPTE MiArmTemplatePte, MiArmTemplatePde;
 
-VOID
-KiFlushSingleTb(IN BOOLEAN Invalid,
-                IN PVOID Virtual);
-
-/* FUNCTIONS ******************************************************************/
+/* PRIVATE FUNCTIONS **********************************************************/
+
+BOOLEAN
+NTAPI
+MiUnmapPageTable(IN PMMPTE PointerPde)
+{
+    //
+    // Check if this address belongs to the kernel
+    //
+    if (((ULONG_PTR)PointerPde > PDE_BASE) ||
+        ((ULONG_PTR)PointerPde < (PDE_BASE + 1024*1024)))
+    {
+        //
+        // Nothing to do
+        //
+        return TRUE;
+    }
+    
+    //
+    // FIXME-USER: Shouldn't get here yet
+    //
+    ASSERT(FALSE);
+    return FALSE;
+}
+
+VOID
+NTAPI
+MiFlushTlb(IN PMMPTE PointerPte,
+           IN PVOID Address)
+{
+    //
+    // Make sure the PTE is valid, and unmap the pagetable if user-mode
+    //
+    if (((PointerPte) && (MiUnmapPageTable(PointerPte))) ||
+        (Address >= MmSystemRangeStart))
+    {
+        //
+        // Invalidate this page
+        //
+        KeArmInvalidateTlbEntry(Address);
+    }
+}
+
+PMMPTE
+NTAPI
+MiGetPageTableForProcess(IN PEPROCESS Process,
+                         IN PVOID Address,
+                         IN BOOLEAN Create)
+{
+    ULONG PdeOffset;
+    PMMPTE PointerPde;
+    MMPTE Pte;
+    NTSTATUS Status;
+    PFN_NUMBER Pfn;
+    
+    //
+    // Check if this is a user-mode, non-kernel or non-current address
+    //
+    if ((Address < MmSystemRangeStart) &&
+        (Process) &&
+        (Process != PsGetCurrentProcess()))
+    {
+        //
+        // FIXME-USER: No user-mode memory support
+        //
+        ASSERT(FALSE);
+    }
+    
+    //
+    // Get the PDE
+    //
+    PointerPde = MiGetPdeAddress(Address);
+    if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
+    {
+        //
+        // Invalid PDE, is this a kernel address?
+        //
+        if (Address >= MmSystemRangeStart)
+        {            
+            //
+            // Does it exist in the kernel page directory?
+            //
+            PdeOffset = MiGetPdeOffset(Address);
+            if (MmGlobalKernelPageDirectory[PdeOffset] == 0)
+            {
+                //
+                // It doesn't. Is this a create operation? If not, fail
+                //
+                if (Create == FALSE) return NULL;
+                
+                //
+                // THIS WHOLE PATH IS TODO
+                //
+                ASSERT(FALSE);
+                
+                //
+                // Allocate a non paged pool page for the PDE
+                //
+                Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+                if (!NT_SUCCESS(Status)) return NULL;
+                
+                //
+                // Make the entry valid
+                //
+                Pte.u.Hard.AsUlong = 0xDEADBEEF;
+                
+                //
+                // Save it
+                //
+                MmGlobalKernelPageDirectory[PdeOffset] = Pte.u.Hard.AsUlong;
+            }
+            
+            //
+            // Now set the actual PDE
+            //
+            PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset];
+        }
+        else
+        {
+            //
+            // Is this a create operation? If not, fail
+            //
+            if (Create == FALSE) return NULL;
+            
+            //
+            // THIS WHOLE PATH IS TODO
+            //
+            ASSERT(FALSE);
+         
+            //
+            // Allocate a non paged pool page for the PDE
+            //
+            Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+            if (!NT_SUCCESS(Status)) return NULL;
+            
+            //
+            // Make the entry valid
+            //
+            Pte.u.Hard.AsUlong = 0xDEADBEEF;
+            
+            //
+            // Set it
+            //
+            *PointerPde = Pte;
+        }
+    }
+    
+    //
+    // Return the PTE
+    //
+    return MiGetPteAddress(Address);
+}
+
+MMPTE
+NTAPI
+MiGetPageEntryForProcess(IN PEPROCESS Process,
+                         IN PVOID Address)
+{
+    PMMPTE PointerPte;
+    MMPTE Pte;
+    Pte.u.Hard.AsUlong = 0;
+    
+    //
+    // Get the PTE
+    //
+    PointerPte = MiGetPageTableForProcess(Process, Address, FALSE);
+    if (PointerPte)
+    {
+        //
+        // Capture the PTE value and unmap the page table
+        //
+        Pte = *PointerPte;
+        MiUnmapPageTable(PointerPte);
+    }
+
+    //
+    // Return the PTE value
+    //
+    return Pte;
+}
+
+VOID
+NTAPI
+MmDeletePageTable(IN PEPROCESS Process,
+                  IN PVOID Address)
+{
+    PMMPTE PointerPde;
+    
+    //
+    // Not valid for kernel addresses
+    //
+    DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address);
+    ASSERT(Address < MmSystemRangeStart);
+    
+    //
+    // Check if this is for a different process
+    //
+    if ((Process) && (Process != PsGetCurrentProcess()))
+    {
+        //
+        // FIXME-USER: Need to attach to the process
+        //
+        ASSERT(FALSE);
+    }
+    
+    //
+    // Get the PDE
+    //
+    PointerPde = MiGetPdeAddress(Address);
+    
+    //
+    // On ARM, we use a section mapping for the original low-memory mapping
+    //
+    if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
+    {
+        //
+        // Make sure it's valid
+        //
+        ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
+    }
+    
+    //
+    // Clear the PDE
+    //
+    PointerPde->u.Hard.AsUlong = 0;
+    ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
+    
+    //
+    // Invalidate the TLB entry
+    //
+    MiFlushTlb(PointerPde, MiAddressToPte(Address));
+}
+
+BOOLEAN
+NTAPI
+MmCreateProcessAddressSpace(IN ULONG MinWs,
+                            IN PEPROCESS Process,
+                            IN PLARGE_INTEGER DirectoryTableBase)
+{
+    //
+    // FIXME-USER: Need to create address space
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+    return 0;
+}
 
 VOID
 NTAPI
@@ -63,9 +281,10 @@
 Mmi386ReleaseMmInfo(IN PEPROCESS Process)
 {
     //
-    // TODO
+    // FIXME-USER: Need to delete address space
     //
     UNIMPLEMENTED;
+    while (TRUE);
     return 0;
 }
 
@@ -92,121 +311,13 @@
 }
 
 PULONG
+NTAPI
 MmGetPageDirectory(VOID)
 {
     //
     // Return the TTB
     //
     return (PULONG)KeArmTranslationTableRegisterGet().AsUlong;
-}
-
-
-BOOLEAN
-NTAPI
-MmCreateProcessAddressSpace(IN ULONG MinWs,
-                            IN PEPROCESS Process,
-                            IN PLARGE_INTEGER DirectoryTableBase)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
-    return 0;
-}
-
-VOID
-NTAPI
-MmDeletePageTable(IN PEPROCESS Process,
-                  IN PVOID Address)
-{
-    PMMPTE PointerPde;
-    
-    //
-    // Not valid for kernel addresses
-    //
-    DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address);
-    ASSERT(Address < MmSystemRangeStart);
-    
-    //
-    // Check if this is for a different process
-    //
-    if ((Process) && (Process != PsGetCurrentProcess()))
-    {
-        //
-        // TODO
-        //
-        UNIMPLEMENTED;
-        return;
-    }
-       
-    //
-    // Get the PDE
-    //
-    PointerPde = MiGetPdeAddress(Address);
-
-    //
-    // On ARM, we use a section mapping for the original low-memory mapping
-    //
-    if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
-    {
-        //
-        // Make sure it's valid
-        //
-        ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
-    }
-    
-    //
-    // Clear the PDE
-    //
-    PointerPde->u.Hard.AsUlong = 0;
-    ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
-    
-    //
-    // Invalidate the TLB entry
-    //
-    KiFlushSingleTb(TRUE, Address);
-}
-
-PFN_TYPE
-NTAPI
-MmGetPfnForProcess(IN PEPROCESS Process,
-                   IN PVOID Address)
-{
-    PMMPTE Pte;
-    
-    //
-    // Check if this is for a different process
-    //
-    if ((Process) && (Process != PsGetCurrentProcess()))
-    {
-        //
-        // TODO
-        //
-        UNIMPLEMENTED;
-        return 0;
-    }
-    
-    //
-    // Get the PDE
-    //
-    Pte = MiGetPdeAddress(Address);
-    if (Pte->u.Hard.L1.Fault.Type != FaultPte)
-    {
-        //
-        // Get the PTE
-        //
-        Pte = MiGetPteAddress(Address);
-    }
-    
-    //
-    // If PTE is invalid, return 0
-    //
-    if (Pte->u.Hard.L2.Fault.Type == FaultPte) return 0;
-    
-    //
-    // Return PFN
-    //
-    return Pte->u.Hard.L2.Small.BaseAddress;
 }
 
 VOID
@@ -220,186 +331,7 @@
     // TODO
     //
     UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-MmRawDeleteVirtualMapping(IN PVOID Address)
-{
-    PMMPTE PointerPte, PointerPde;
-    
-    //
-    // Get the PDE
-    //
-    PointerPde = MiGetPdeAddress(Address);
-    if (PointerPde->u.Hard.L1.Fault.Type == FaultPte) return;
-
-    //
-    // Get the PTE
-    //
-    PointerPte = MiGetPteAddress(Address);
-    ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
-    
-    //
-    // Destroy the PTE
-    //
-    PointerPte->u.Hard.AsUlong = 0;
-    ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
-    
-    //
-    // Flush the TLB
-    //
-    KiFlushSingleTb(TRUE, Address);
-}
-
-VOID
-NTAPI
-MmDeleteVirtualMapping(IN PEPROCESS Process,
-                       IN PVOID Address,
-                       IN BOOLEAN FreePage,
-                       OUT PBOOLEAN WasDirty,
-                       OUT PPFN_TYPE Page)
-{
-    PMMPTE PointerPte, PointerPde;
-    MMPTE Pte;
-    
-    //
-    // Check if this is for a different process
-    //
-    if ((Process) && (Process != PsGetCurrentProcess()))
-    {
-        //
-        // TODO
-        //
-        UNIMPLEMENTED;
-        return;
-    }
-    
-    //
-    // Get the PDE
-    //
-    PointerPde = MiGetPdeAddress(Address);
-    if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
-    {
-        //
-        // Invalid PDE
-        //
-        if (WasDirty) *WasDirty = FALSE;
-        if (Page) *Page = 0;
-        return;
-    }
-    
-    //
-    // Get the PTE
-    //
-    PointerPte = MiGetPteAddress(Address);
-    if (PointerPte->u.Hard.L1.Fault.Type == FaultPte)
-    {
-        //
-        // Invalid PTE
-        //
-        if (WasDirty) *WasDirty = FALSE;
-        if (Page) *Page = 0;
-        return;
-    }
-        
-    //
-    // Save the PTE
-    //
-    Pte = *PointerPte;
-    ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
-    
-    //
-    // Destroy the PTE
-    //
-    PointerPte->u.Hard.AsUlong = 0;
-    ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
-
-    //
-    // Flush the TLB
-    //
-    KiFlushSingleTb(TRUE, Address);
-    
-    //
-    // Check if the PTE was valid
-    //
-    if (Pte.u.Hard.L2.Fault.Type != FaultPte)
-    {
-        //
-        // Mark the page as unmapped
-        //
-        MmMarkPageUnmapped(Pte.u.Hard.L2.Small.BaseAddress);
-    }
-    else
-    {
-        //
-        // Make it sane
-        //
-        Pte.u.Hard.L2.Small.BaseAddress = 0;
-    }
-    
-    //
-    // Check if this was our page, and valid
-    //
-    if ((FreePage) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
-    {
-        //
-        // Release it
-        //
-        MmReleasePageMemoryConsumer(MC_NPPOOL, Pte.u.Hard.L2.Small.BaseAddress);
-    }
-    
-    //
-    // Return if the page was dirty
-    //
-    if (WasDirty) *WasDirty = TRUE; // LIE!!!
-    if (Page) *Page = Pte.u.Hard.L2.Small.BaseAddress;
-}
-
-VOID
-NTAPI
-MmDeletePageFileMapping(IN PEPROCESS Process,
-                        IN PVOID Address,
-                        IN SWAPENTRY *SwapEntry)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
-}
-
-BOOLEAN
-NTAPI
-MmIsDirtyPage(IN PEPROCESS Process,
-              IN PVOID Address)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
-    return 0;
-}
-
-VOID
-NTAPI
-MmSetCleanPage(IN PEPROCESS Process,
-               IN PVOID Address)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-MmSetDirtyPage(IN PEPROCESS Process,
-               IN PVOID Address)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
+    while (TRUE);
 }
 
 VOID
@@ -411,80 +343,7 @@
     // TODO
     //
     UNIMPLEMENTED;
-}
-
-BOOLEAN
-NTAPI
-MmIsPagePresent(IN PEPROCESS Process,
-                IN PVOID Address)
-{
-    PMMPTE Pte;
-    
-    //
-    // Check if this is for a different process
-    //
-    if ((Process) && (Process != PsGetCurrentProcess()))
-    {
-        //
-        // TODO
-        //
-        UNIMPLEMENTED;
-        return 0;
-    }
-
-    //
-    // Get the PDE
-    //
-    Pte = MiGetPdeAddress(Address);
-    if (Pte->u.Hard.L1.Fault.Type != FaultPte)
-    {
-        //
-        // Get the PTE
-        //
-        Pte = MiGetPteAddress(Address);
-    }
-    
-    //
-    // Return whether or not it's valid
-    //
-    return (Pte->u.Hard.L1.Fault.Type != FaultPte);
-}
-
-BOOLEAN
-NTAPI
-MmIsPageSwapEntry(IN PEPROCESS Process,
-                  IN PVOID Address)
-{
-    PMMPTE Pte;
-    
-    //
-    // Check if this is for a different process
-    //
-    if ((Process) && (Process != PsGetCurrentProcess()))
-    {
-        //
-        // TODO
-        //
-        UNIMPLEMENTED;
-        return 0;
-    }
-    
-    //
-    // Get the PDE
-    //
-    Pte = MiGetPdeAddress(Address);
-    if (Pte->u.Hard.L1.Fault.Type != FaultPte)
-    {
-        //
-        // Get the PTE
-        //
-        Pte = MiGetPteAddress(Address);
-    }
-    
-    //
-    // Return whether or not it's valid
-    //
-    return ((Pte->u.Hard.L2.Fault.Type == FaultPte) && (Pte->u.Hard.AsUlong));
+    while (TRUE);
 }
 
 NTSTATUS
@@ -501,13 +360,13 @@
     PFN_NUMBER Pfn;
     DPRINT("[KMAP]: %p %d\n", Address, PageCount);
     //ASSERT(Address >= MmSystemRangeStart);
-
+    
     //
     // Get our templates
     //
     TempPte = MiArmTemplatePte;
     TempPde = MiArmTemplatePde;
-
+    
     //
     // Check if we have PDEs for this region
     //
@@ -547,7 +406,7 @@
             // Write the PFN of the PDE
             //
             TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
-
+            
             //
             // Write the PTE
             //
@@ -573,7 +432,7 @@
         // Mark it as mapped
         //
         if (MarkAsMapped) MmMarkPageMapped(*Pages);
-
+        
         //
         // Set the PFN
         //
@@ -597,20 +456,6 @@
     //
     return STATUS_SUCCESS;
 }
-
-NTSTATUS
-NTAPI
-MmCreatePageFileMapping(IN PEPROCESS Process,
-                        IN PVOID Address,
-                        IN SWAPENTRY SwapEntry)
-{
-    //
-    // TODO
-    //
-    UNIMPLEMENTED;
-    return 0;
-}
-
 
 NTSTATUS
 NTAPI
@@ -653,9 +498,9 @@
     }
     
     //
-    // TODO
-    //
-    UNIMPLEMENTED;
+    // FIXME-USER: Support user-mode mappings
+    //
+    ASSERT(FALSE);
     return 0;
 }
 
@@ -668,7 +513,7 @@
                        IN ULONG PageCount)
 {
     ULONG i;
-
+    
     //
     // Loop each page
     //
@@ -690,76 +535,114 @@
                                         PageCount);
 }
 
-ULONG
-NTAPI
-MmGetPageProtect(IN PEPROCESS Process,
-                 IN PVOID Address)
-{
-    //
-    // We don't enforce any protection on the pages -- they are all RWX
-    //
-    return PAGE_READWRITE;
-}
-
-VOID
-NTAPI
-MmSetPageProtect(IN PEPROCESS Process,
-                 IN PVOID Address,
-                 IN ULONG Protection)
-{
-    //
-    // We don't enforce any protection on the pages -- they are all RWX
-    //
-    return;
-}
-
-/*
- * @implemented
- */
-PHYSICAL_ADDRESS
-NTAPI
-MmGetPhysicalAddress(IN PVOID Address)
-{
-    PHYSICAL_ADDRESS PhysicalAddress = {{0}};
+VOID
+NTAPI
+MmRawDeleteVirtualMapping(IN PVOID Address)
+{
     PMMPTE PointerPte;
-
-    //
-    // Early boot PCR check
-    //
-    if (Address == PCR)
-    {
-        //
-        // ARM Hack while we still use a section PTE
-        //
-        PointerPte = MiGetPdeAddress(PCR);
-        ASSERT(PointerPte->u.Hard.L1.Section.Type == SectionPte);
-        PhysicalAddress.QuadPart = PointerPte->u.Hard.L1.Section.BaseAddress;
-        PhysicalAddress.QuadPart <<= CPT_SHIFT;
-        PhysicalAddress.LowPart += BYTE_OFFSET(Address);
-        return PhysicalAddress;
-    }
     
     //
     // Get the PTE
     //
-    PointerPte = MiGetPteAddress(Address);
+    PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE);
+    if ((PointerPte) && (PointerPte->u.Hard.L2.Fault.Type != FaultPte))
+    {
+        //
+        // Destroy it
+        //
+        PointerPte->u.Hard.AsUlong = 0;
+    
+        //
+        // Flush the TLB
+        //
+        MiFlushTlb(PointerPte, Address);
+    }
+}
+
+VOID
+NTAPI
+MmDeleteVirtualMapping(IN PEPROCESS Process,
+                       IN PVOID Address,
+                       IN BOOLEAN FreePage,
+                       OUT PBOOLEAN WasDirty,
+                       OUT PPFN_TYPE Page)
+{
+    PMMPTE PointerPte;
+    MMPTE Pte;
+    
+    //
+    // Get the PTE
+    //
+    PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE);
+    if (!PointerPte)
+    {
+        //
+        // Invalid PDE
+        //
+        if (WasDirty) *WasDirty = FALSE;
+        if (Page) *Page = 0;
+        return;
+    }
+            
+    //
+    // Save the PTE
+    //
+    Pte = *PointerPte;
     if (PointerPte->u.Hard.L1.Fault.Type == FaultPte)
     {
         //
-        // Invalid address
-        //
-        DPRINT1("Address invalid: %p\n", Address);
-        return PhysicalAddress;
-    }
-
-    //
-    // Return the information
-    //
-    ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
-    PhysicalAddress.QuadPart = PointerPte->u.Hard.L2.Small.BaseAddress;
-    PhysicalAddress.QuadPart <<= PAGE_SHIFT;
-    PhysicalAddress.LowPart += BYTE_OFFSET(Address);
-    return PhysicalAddress;
+        // Invalid PTE
+        //
+        if (WasDirty) *WasDirty = FALSE;
+        if (Page) *Page = 0;
+        return;
+    }
+    
+    //
+    // Destroy the PTE
+    //
+    PointerPte->u.Hard.AsUlong = 0;
+    ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
+
+    //
+    // Flush the TLB
+    //
+    MiFlushTlb(PointerPte, Address);
+    
+    //
+    // Check if the PTE was valid
+    //
+    if (Pte.u.Hard.L2.Fault.Type != FaultPte)
+    {
+        //
+        // Mark the page as unmapped
+        //
+        MmMarkPageUnmapped(Pte.u.Hard.L2.Small.BaseAddress);
+    }
+    else
+    {
+        //
+        // Make it sane
+        //
+        Pte.u.Hard.L2.Small.BaseAddress = 0;
+    }
+    
+    //
+    // Check if this was our page, and valid
+    //
+    if ((FreePage) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
+    {
+        //
+        // Release it
+        //
+        MmReleasePageMemoryConsumer(MC_NPPOOL, Pte.u.Hard.L2.Small.BaseAddress);
+    }
+    
+    //
+    // Return if the page was dirty
+    //
+    if (WasDirty) *WasDirty = TRUE; // LIE!!!
+    if (Page) *Page = Pte.u.Hard.L2.Small.BaseAddress;
 }
 
 PVOID
@@ -769,7 +652,7 @@
     PMMPTE PointerPte, FirstPte, LastPte;
     MMPTE TempPte;
     PVOID Address;
-
+    
     //
     // Loop hyperspace PTEs (1MB)
     //
@@ -807,12 +690,12 @@
     ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
     ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
     *PointerPte = TempPte;
-
+    
     //
     // Return the address
     //
     Address = HYPER_SPACE + ((PointerPte - FirstPte) * PAGE_SIZE);
-    KiFlushSingleTb(FALSE, Address);
+    KeArmInvalidateTlbEntry(Address);
     DPRINT("[HMAP]: %p %lx\n", Address, Page);
     return Address;
 }
@@ -845,8 +728,153 @@
     //
     // Flush the TLB entry and return the PFN
     //
-    KiFlushSingleTb(TRUE, Address);
+    KeArmInvalidateTlbEntry(Address);
     return Pfn;
+}
+
+VOID
+NTAPI
+MmDeletePageFileMapping(IN PEPROCESS Process,
+                        IN PVOID Address,
+                        IN SWAPENTRY *SwapEntry)
+{
+    //
+    // TODO
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+}
+
+NTSTATUS
+NTAPI
+MmCreatePageFileMapping(IN PEPROCESS Process,
+                        IN PVOID Address,
+                        IN SWAPENTRY SwapEntry)
+{
+    //
+    // TODO
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+    return 0;
+}
+
+PFN_TYPE
+NTAPI
+MmGetPfnForProcess(IN PEPROCESS Process,
+                   IN PVOID Address)
+{
+    MMPTE Pte;
+    
+    //
+    // Get the PTE
+    //
+    Pte = MiGetPageEntryForProcess(Process, Address);
+    if (Pte.u.Hard.L2.Fault.Type == FaultPte) return 0;
+    
+    //
+    // Return PFN
+    //
+    return Pte.u.Hard.L2.Small.BaseAddress;
+}
+
+ULONG
+NTAPI
+MiGetUserPageDirectoryCount(VOID)
+{
+    //
+    // Return the index
+    //
+    return MiGetPdeOffset(MmSystemRangeStart);
+}
+
+BOOLEAN
+NTAPI
+MmIsDirtyPage(IN PEPROCESS Process,
+              IN PVOID Address)
+{
+    //
+    // TODO
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+    return 0;
+}
+
+VOID
+NTAPI
+MmSetCleanPage(IN PEPROCESS Process,
+               IN PVOID Address)
+{
+    //
+    // TODO
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+}
+
+VOID
+NTAPI
+MmSetDirtyPage(IN PEPROCESS Process,
+               IN PVOID Address)
+{
+    //
+    // TODO
+    //
+    UNIMPLEMENTED;
+    while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+MmIsPagePresent(IN PEPROCESS Process,
+                IN PVOID Address)
+{
+    //
+    // Fault PTEs are 0, which is FALSE (non-present)
+    //
+    return MiGetPageEntryForProcess(Process, Address).u.Hard.L2.Fault.Type;
+}
+
+BOOLEAN
+NTAPI
+MmIsPageSwapEntry(IN PEPROCESS Process,
+                  IN PVOID Address)
+{
+    MMPTE Pte;
+    
+    //
+    // Get the PTE
+    //
+    Pte = MiGetPageEntryForProcess(Process, Address);
+    
+    //
+    // Make sure it's valid, but faulting
+    //
+    return (Pte.u.Hard.L2.Fault.Type == FaultPte) && (Pte.u.Hard.AsUlong);
+}
+
+ULONG
+NTAPI
+MmGetPageProtect(IN PEPROCESS Process,
+                 IN PVOID Address)
+{
+    //
+    // We don't enforce any protection on the pages -- they are all RWX
+    //
+    return PAGE_READWRITE;
+}
+
+VOID
+NTAPI
+MmSetPageProtect(IN PEPROCESS Process,
+                 IN PVOID Address,
+                 IN ULONG Protection)
+{
+    //
+    // We don't enforce any protection on the pages -- they are all RWX
+    //
+    return;
 }
 
 VOID
@@ -862,7 +890,7 @@
     //
     MiArmTemplatePte = *MiGetPteAddress(0x80000000);
     MiArmTemplatePde = *MiGetPdeAddress(0x80000000);
-
+    
     //
     // Loop the 2GB of address space which belong to the kernel
     //
@@ -884,16 +912,6 @@
     }
 }
 
-ULONG
-NTAPI
-MiGetUserPageDirectoryCount(VOID)
-{
-    //
-    // Return the index
-    //
-    return MiGetPdeOffset(MmSystemRangeStart);
-}
-
 VOID
 NTAPI
 MiInitPageDirectoryMap(VOID)
@@ -902,7 +920,7 @@
     PHYSICAL_ADDRESS BoundaryAddressMultiple;
     PVOID BaseAddress;
     NTSTATUS Status;
-
+    
     //
     // Create memory area for the PTE area
     //
@@ -918,7 +936,7 @@
                                 0,
                                 BoundaryAddressMultiple);
     ASSERT(NT_SUCCESS(Status));
-
+    
     //
     // Create memory area for the PDE area
     //
@@ -949,3 +967,60 @@
                                 BoundaryAddressMultiple);
     ASSERT(NT_SUCCESS(Status));
 }
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @implemented
+ */
+PHYSICAL_ADDRESS
+NTAPI
+MmGetPhysicalAddress(IN PVOID Address)
+{
+    PHYSICAL_ADDRESS PhysicalAddress;
+    MMPTE Pte;
+
+    //
+    // Early boot PCR check
+    //
+    if (Address == PCR)
+    {
+        //
+        // ARM Hack while we still use a section PTE
+        //
+        PMMPTE PointerPte;
+        PointerPte = MiGetPdeAddress(PCR);
+        ASSERT(PointerPte->u.Hard.L1.Section.Type == SectionPte);
+        PhysicalAddress.QuadPart = PointerPte->u.Hard.L1.Section.BaseAddress;
+        PhysicalAddress.QuadPart <<= CPT_SHIFT;
+        PhysicalAddress.LowPart += BYTE_OFFSET(Address);
+        return PhysicalAddress;
+    }
+    
+    //
+    // Get the PTE
+    //
+    Pte = MiGetPageEntryForProcess(NULL, Address);
+    if ((Pte.u.Hard.AsUlong) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
+    {
+        //
+        // Return the information
+        //
+        ASSERT(Pte.u.Hard.L2.Small.Type == SmallPte);
+        PhysicalAddress.QuadPart = Pte.u.Hard.L2.Small.BaseAddress;
+        PhysicalAddress.QuadPart <<= PAGE_SHIFT;
+        PhysicalAddress.LowPart += BYTE_OFFSET(Address);
+    }
+    else
+    {
+        //
+        // Invalid or unmapped
+        //
+        PhysicalAddress.QuadPart = 0;
+    }
+    
+    //
+    // Return the physical address
+    //
+    return PhysicalAddress;
+}



More information about the Ros-diffs mailing list