[NTOS]: When expanding paged pool, use MiRemoveAnyPage, not MmAllocPage.
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / miarm.h
index a6e87fe..efcc053 100644 (file)
@@ -42,7 +42,7 @@
 #define _1KB (1024)
 #define _1MB (1024 * _1KB)
 
-/* Are mapped by a PDE */
+/* Area mapped by a PDE */
 #define PDE_MAPPED_VA   (PTE_COUNT * PAGE_SIZE)
 
 /* Size of a PDE directory, and size of a page table */
 #define MM_DECOMMIT            0x10 
 #define MM_NOACCESS            (MM_DECOMMIT | MM_NOCACHE)
 
+//
+// Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits
+// The Memory Manager's definition define the attributes that must be preserved
+// and these PTE definitions describe the attributes in the hardware sense. This
+// helps deal with hardware differences between the actual boolean expression of
+// the argument.
+//
+// For example, in the logical attributes, we want to express read-only as a flag
+// but on x86, it is writability that must be set. On the other hand, on x86, just
+// like in the kernel, it is disabling the caches that requires a special flag, 
+// while on certain architectures such as ARM, it is enabling the cache which
+// requires a flag.
+//
+#if defined(_M_IX86) || defined(_M_AMD64)
+//
+// Access Flags
+//
+#define PTE_READONLY            0
+#define PTE_EXECUTE             0 // Not worrying about NX yet
+#define PTE_EXECUTE_READ        0 // Not worrying about NX yet
+#define PTE_READWRITE           0x2
+#define PTE_WRITECOPY           0x200
+#define PTE_EXECUTE_READWRITE   0x0
+#define PTE_EXECUTE_WRITECOPY   0x200
+//
+// Cache flags
+//
+#define PTE_ENABLE_CACHE        0
+#define PTE_DISABLE_CACHE       0x10
+#define PTE_WRITECOMBINED_CACHE 0x10
+#elif defined(_M_ARM)
+#else
+#error Define these please!
+#endif
+static const
+ULONG
+MmProtectToPteMask[32] =
+{
+    //
+    // These are the base MM_ protection flags
+    //
+    0,
+    PTE_READONLY            | PTE_ENABLE_CACHE,
+    PTE_EXECUTE             | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_READ        | PTE_ENABLE_CACHE,
+    PTE_READWRITE           | PTE_ENABLE_CACHE,
+    PTE_WRITECOPY           | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_READWRITE   | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_WRITECOPY   | PTE_ENABLE_CACHE,
+    //
+    // These OR in the MM_NOCACHE flag
+    //
+    0,
+    PTE_READONLY            | PTE_DISABLE_CACHE,
+    PTE_EXECUTE             | PTE_DISABLE_CACHE,
+    PTE_EXECUTE_READ        | PTE_DISABLE_CACHE,
+    PTE_READWRITE           | PTE_DISABLE_CACHE,
+    PTE_WRITECOPY           | PTE_DISABLE_CACHE,
+    PTE_EXECUTE_READWRITE   | PTE_DISABLE_CACHE,
+    PTE_EXECUTE_WRITECOPY   | PTE_DISABLE_CACHE,
+    //
+    // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
+    //
+    0,
+    PTE_READONLY            | PTE_ENABLE_CACHE,
+    PTE_EXECUTE             | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_READ        | PTE_ENABLE_CACHE,
+    PTE_READWRITE           | PTE_ENABLE_CACHE,
+    PTE_WRITECOPY           | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_READWRITE   | PTE_ENABLE_CACHE,
+    PTE_EXECUTE_WRITECOPY   | PTE_ENABLE_CACHE,
+    //
+    // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
+    //
+    0,
+    PTE_READONLY            | PTE_WRITECOMBINED_CACHE,
+    PTE_EXECUTE             | PTE_WRITECOMBINED_CACHE,
+    PTE_EXECUTE_READ        | PTE_WRITECOMBINED_CACHE,
+    PTE_READWRITE           | PTE_WRITECOMBINED_CACHE,
+    PTE_WRITECOPY           | PTE_WRITECOMBINED_CACHE,
+    PTE_EXECUTE_READWRITE   | PTE_WRITECOMBINED_CACHE,
+    PTE_EXECUTE_WRITECOPY   | PTE_WRITECOMBINED_CACHE,
+};
+//
+// Assertions for session images, addresses, and PTEs
+//
+#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
+    (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
+    
+#define MI_IS_SESSION_ADDRESS(Address) \
+    (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
+        
+#define MI_IS_SESSION_PTE(Pte) \
+    ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
+
 //
 // Corresponds to MMPTE_SOFTWARE.Protection
 //
 //
 // Creates a software PTE with the given protection
 //
-#define MI_MAKE_SOFTWARE_PTE(x)          ((x) << MM_PTE_SOFTWARE_PROTECTION_BITS)
+#define MI_MAKE_SOFTWARE_PTE(p, x)          ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))
+
+//
+// Marks a PTE as deleted
+//
+#define MI_SET_PFN_DELETED(x)               ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1))
+#define MI_IS_PFN_DELETED(x)                ((ULONG_PTR)((x)->PteAddress) & 1)
 
 //
 // Special values for LoadedImports
 //
 #define LIST_HEAD 0xFFFFFFFF
 
+//
+// Special IRQL value (found in assertions)
+//
+#define MM_NOIRQL (KIRQL)0xFFFFFFFF
+    
 //
 // FIXFIX: These should go in ex.h after the pool merge
 //
@@ -284,6 +391,10 @@ extern PVOID MiSystemViewStart;
 extern ULONG MmSystemViewSize;
 extern PVOID MmSessionBase;
 extern PVOID MiSessionSpaceEnd;
+extern PMMPTE MiSessionImagePteStart;
+extern PMMPTE MiSessionImagePteEnd;
+extern PMMPTE MiSessionBasePte;
+extern PMMPTE MiSessionLastPte;
 extern ULONG MmSizeOfPagedPoolInBytes;
 extern PMMPTE MmSystemPagePtes;
 extern PVOID MmSystemCacheStart;
@@ -327,16 +438,40 @@ extern ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes];
 extern PFN_NUMBER MmTotalSystemDriverPages;
 extern PVOID MiSessionImageStart;
 extern PVOID MiSessionImageEnd;
+extern PMMPTE MiHighestUserPte;
+extern PMMPDE MiHighestUserPde;
+extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
 
 #define MI_PFN_TO_PFNENTRY(x)     (&MmPfnDatabase[1][x])
 #define MI_PFNENTRY_TO_PFN(x)     (x - MmPfnDatabase[1])
 
-#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
-    (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
+//
+// Creates a valid kernel PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte,
+                     IN PMMPTE MappingPte,
+                     IN ULONG ProtectionMask,
+                     IN PFN_NUMBER PageFrameNumber)
+{
+    /* Only valid for kernel, non-session PTEs */
+    ASSERT(MappingPte > MiHighestUserPte);
+    ASSERT(!MI_IS_SESSION_PTE(MappingPte));
+    ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
+    
+    /* Start fresh */
+    *NewPte = ValidKernelPte;
+    
+    /* Set the protection and page */
+    NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+    NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+}
 
-#define MI_IS_SESSION_ADDRESS(Address) \
-    (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
-        
+//
+// Returns if the page is physically resident (ie: a large page)
+// FIXFIX: CISC/x86 only?
+//
 FORCEINLINE
 BOOLEAN
 MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
@@ -563,6 +698,29 @@ MiAllocatePfn(
     IN ULONG Protection
 );
 
+VOID
+NTAPI
+MiInitializePfn(
+    IN PFN_NUMBER PageFrameIndex,
+    IN PMMPTE PointerPte,
+    IN BOOLEAN Modified
+);
+
+VOID
+NTAPI
+MiInitializePfnForOtherProcess(
+    IN PFN_NUMBER PageFrameIndex,
+    IN PMMPTE PointerPte,
+    IN PFN_NUMBER PteFrame
+);
+
+VOID
+NTAPI
+MiDecrementShareCount(
+    IN PMMPFN Pfn1,
+    IN PFN_NUMBER PageFrameIndex
+);
+
 PFN_NUMBER
 NTAPI
 MiRemoveAnyPage(
@@ -599,4 +757,10 @@ MiSyncCachedRanges(
     VOID
 );
 
+BOOLEAN
+NTAPI
+MiIsPfnInUse(
+    IN PMMPFN Pfn1
+);
+
 /* EOF */