[NTOS]: Define portable MI_MAKE_ACCESSED_PAGE macro.
[reactos.git] / reactos / ntoskrnl / include / internal / arm / mm.h
index d049a39..83b0d48 100644 (file)
@@ -1,17 +1,12 @@
-#ifndef __NTOSKRNL_INCLUDE_INTERNAL_ARM_MM_H
-#define __NTOSKRNL_INCLUDE_INTERNAL_ARM_MM_H
+#pragma once
 
-//
-// Number of bits corresponding to the area that a PDE entry represents (1MB)
-//
 #define PDE_SHIFT 20
-#define PDE_SIZE  (1 << PDE_SHIFT)
 
 //
 // Number of bits corresponding to the area that a coarse page table entry represents (4KB)
 //
 #define PTE_SHIFT 12
-//#define PAGE_SIZE (1 << PTE_SHIFT) // FIXME: This conflicts with ndk/arm/mmtypes.h which does #define PAGE_SIZE 0x1000 -- use PTE_SIZE here instead?
+#define PTE_SIZE (1 << PTE_SHIFT)
 
 //
 // Number of bits corresponding to the area that a coarse page table occupies (1KB)
 #define CPT_SHIFT 10
 #define CPT_SIZE  (1 << CPT_SHIFT)
 
-typedef union _ARM_PTE
+//
+// Base Addresses
+//
+#define PTE_BASE    0xC0000000
+#define PTE_TOP     0xC03FFFFF
+#define PDE_BASE    0xC0400000
+#define PDE_TOP     0xC04FFFFF
+#define HYPER_SPACE 0xC0500000
+
+#if 0
+typedef struct _HARDWARE_PDE_ARMV6
 {
-    union
-    {
-        struct
-        {
-            ULONG Type:2;
-            ULONG Unused:30;
-        } Fault;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Ignored:2;
-            ULONG Reserved:1;
-            ULONG Domain:4;
-            ULONG Ignored1:1;
-            ULONG BaseAddress:22;
-        } Coarse;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Buffered:1;
-            ULONG Cached:1;
-            ULONG Reserved:1;
-            ULONG Domain:4;
-            ULONG Ignored:1;
-            ULONG Access:2;
-            ULONG Ignored1:8;
-            ULONG BaseAddress:12;
-        } Section;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Reserved:3;
-            ULONG Domain:4;
-            ULONG Ignored:3;
-            ULONG BaseAddress:20;
-        } Fine;
-    } L1;
-    union
-    {
-        struct
-        {
-            ULONG Type:2;
-            ULONG Unused:30;
-        } Fault;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Buffered:1;
-            ULONG Cached:1;
-            ULONG Access0:2;
-            ULONG Access1:2;
-            ULONG Access2:2;
-            ULONG Access3:2;
-            ULONG Ignored:4;
-            ULONG BaseAddress:16;
-        } Large;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Buffered:1;
-            ULONG Cached:1;
-            ULONG Access0:2;
-            ULONG Access1:2;
-            ULONG Access2:2;
-            ULONG Access3:2;
-            ULONG BaseAddress:20;
-        } Small;
-        struct
-        {
-            ULONG Type:2;
-            ULONG Buffered:1;
-            ULONG Cached:1;
-            ULONG Access0:2;
-            ULONG Ignored:4;
-            ULONG BaseAddress:22;
-        } Tiny; 
-    } L2;
-    ULONG AsUlong;
-} ARM_PTE, *PARM_PTE;
-
-typedef struct _ARM_TRANSLATION_TABLE
+    ULONG Valid:1;     // Only for small pages
+    ULONG LargePage:1; // Note, if large then Valid = 0
+    ULONG Buffered:1;
+    ULONG Cached:1;
+    ULONG NoExecute:1;
+    ULONG Domain:4;
+    ULONG Ecc:1;
+    ULONG PageFrameNumber:22;
+} HARDWARE_PDE_ARMV6, *PHARDWARE_PDE_ARMV6;
+
+typedef struct _HARDWARE_LARGE_PTE_ARMV6
 {
-    ARM_PTE Pte[4096];
-} ARM_TRANSLATION_TABLE, *PARM_TRANSLATION_TABLE;
-
-typedef struct _ARM_COARSE_PAGE_TABLE
+    ULONG Valid:1;     // Only for small pages
+    ULONG LargePage:1; // Note, if large then Valid = 0
+    ULONG Buffered:1;
+    ULONG Cached:1;
+    ULONG NoExecute:1;
+    ULONG Domain:4;
+    ULONG Ecc:1;
+    ULONG Accessed:1;
+    ULONG Owner:1;
+    ULONG CacheAttributes:3;
+    ULONG ReadOnly:1;
+    ULONG Shared:1;
+    ULONG NonGlobal:1;
+    ULONG SuperLagePage:1;
+    ULONG Reserved:1;
+    ULONG PageFrameNumber:12;
+} HARDWARE_LARGE_PTE_ARMV6, *PHARDWARE_LARGE_PTE_ARMV6;
+
+typedef struct _HARDWARE_PTE_ARMV6
 {
-    ARM_PTE Pte[256];
-    ULONG Padding[768];
-} ARM_COARSE_PAGE_TABLE, *PARM_COARSE_PAGE_TABLE;
+    ULONG NoExecute:1;
+    ULONG Valid:1;
+    ULONG Buffered:1;
+    ULONG Cached:1;
+    ULONG Accessed:1;
+    ULONG Owner:1;
+    ULONG CacheAttributes:3;
+    ULONG ReadOnly:1;
+    ULONG Shared:1;
+    ULONG NonGlobal:1;
+    ULONG PageFrameNumber:20;
+} HARDWARE_PTE_ARMV6, *PHARDWARE_PTE_ARMV6;
+
+C_ASSERT(sizeof(HARDWARE_PDE_ARMV6) == sizeof(ULONG));
+C_ASSERT(sizeof(HARDWARE_LARGE_PTE_ARMV6) == sizeof(ULONG));
+C_ASSERT(sizeof(HARDWARE_PTE_ARMV6) == sizeof(ULONG));
+#endif
 
-typedef enum _ARM_L1_PTE_TYPE
+/* For FreeLDR */
+typedef struct _PAGE_TABLE_ARM
 {
-    FaultPte,
-    CoarsePte,
-    SectionPte,
-    FinePte
-} ARM_L1_PTE_TYPE;
+    HARDWARE_PTE_ARMV6 Pte[1024];
+} PAGE_TABLE_ARM, *PPAGE_TABLE_ARM;
 
-typedef enum _ARM_L2_PTE_TYPE
+typedef struct _PAGE_DIRECTORY_ARM
 {
-    LargePte = 1,
-    SmallPte,
-    TinyPte
-} ARM_L2_PTE_TYPE;
+    union 
+    {
+        HARDWARE_PDE_ARMV6 Pde[4096];
+        HARDWARE_LARGE_PTE_ARMV6 Pte[4096];
+    };
+} PAGE_DIRECTORY_ARM, *PPAGE_DIRECTORY_ARM;
 
-typedef enum _ARM_PTE_ACCESS
-{
-    FaultAccess,
-    SupervisorAccess,
-    SharedAccess,
-    UserAccess
-} ARM_PTE_ACCESS;
+C_ASSERT(sizeof(PAGE_TABLE_ARM) == PAGE_SIZE);
+C_ASSERT(sizeof(PAGE_DIRECTORY_ARM) == (4 * PAGE_SIZE));
 
 typedef enum _ARM_DOMAIN
 {
@@ -143,26 +102,55 @@ typedef enum _ARM_DOMAIN
     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 0xC1100000
-
 struct _EPROCESS;
 PULONG MmGetPageDirectory(VOID);
 
-#endif
+#define MI_MAKE_LOCAL_PAGE(x)      ((x)->u.Hard.NonGlobal = 1)
+#define MI_MAKE_DIRTY_PAGE(x)      
+#define MI_MAKE_ACCESSED_PAGE(x)      
+#define MI_MAKE_OWNER_PAGE(x)      ((x)->u.Hard.Owner = 1)
+#define MI_MAKE_WRITE_PAGE(x)      ((x)->u.Hard.ReadOnly = 0)
+#define MI_PAGE_DISABLE_CACHE(x)   ((x)->u.Hard.Cached = 0)
+#define MI_PAGE_WRITE_THROUGH(x)   ((x)->u.Hard.Buffered = 0)
+#define MI_PAGE_WRITE_COMBINED(x)  ((x)->u.Hard.Buffered = 1)
+#define MI_IS_PAGE_WRITEABLE(x)    ((x)->u.Hard.ReadOnly == 0)
+#define MI_IS_PAGE_COPY_ON_WRITE(x)FALSE
+#define MI_IS_PAGE_DIRTY(x)        TRUE
+
+/* Easy accessing PFN in PTE */
+#define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
+
+#define NR_SECTION_PAGE_TABLES              1024
+#define NR_SECTION_PAGE_ENTRIES             256
+
+/* See PDR definition */
+#define MI_HYPERSPACE_PTES                  (256 - 1)
+#define MI_ZERO_PTES                        (32)
+#define MI_MAPPING_RANGE_START              ((ULONG)HYPER_SPACE)
+#define MI_MAPPING_RANGE_END                (MI_MAPPING_RANGE_START + \
+                                             MI_HYPERSPACE_PTES * PAGE_SIZE)
+#define MI_ZERO_PTE                         (PMMPTE)(MI_MAPPING_RANGE_END + \
+                                             PAGE_SIZE)
+
+/* Retrives the PDE entry for the given VA */
+#define MiGetPdeAddress(x) ((PMMPDE)(PDE_BASE + (((ULONG)(x) >> 20) << 2)))
+#define MiAddressToPde(x)  MiGetPdeAddress(x)
+    
+/* Retrieves the PTE entry for the given VA */
+#define MiGetPteAddress(x) ((PMMPTE)(PTE_BASE + (((ULONG)(x) >> 12) << 2)))
+#define MiAddressToPte(x)  MiGetPteAddress(x)
+
+/* Retrives the PDE offset for the given VA */
+#define MiGetPdeOffset(x) (((ULONG)(x)) >> 20)
+
+/* Convert a PTE into a corresponding address */
+#define MiPteToAddress(x) ((PVOID)((ULONG)(x) << 10))
+#define MiPdeToAddress(x) ((PVOID)((ULONG)(x) << 18))
+
+#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
+    ((x) / (4*1024*1024))
+
+#define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
+    ((((x)) % (4*1024*1024)) / (4*1024))
+    
+#define MM_CACHE_LINE_SIZE 64