ReactOS  0.4.14-dev-1338-g0d187f7
mm.h
Go to the documentation of this file.
1 /*
2  * kernel internal memory management definitions for amd64
3  */
4 #pragma once
5 
6 #define _MI_PAGING_LEVELS 4
7 #define _MI_HAS_NO_EXECUTE 1
8 
9 /* Memory layout base addresses (This is based on Vista!) */
10 #define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL
11 #define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL
12 #define MI_REAL_SYSTEM_RANGE_START 0xFFFF800000000000ULL
13 //#define MI_PAGE_TABLE_BASE 0xFFFFF68000000000ULL // 512 GB page tables
14 #define HYPER_SPACE 0xFFFFF70000000000ULL // 512 GB hyper space [MiVaProcessSpace]
15 #define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
16 //#define MI_SHARED_SYSTEM_PAGE 0xFFFFF78000000000ULL
17 #define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL // 512 GB - 4 KB system cache working set
18 //#define MI_LOADER_MAPPINGS 0xFFFFF80000000000ULL // 512 GB loader mappings aka KSEG0_BASE (NDK) [MiVaBootLoaded]
19 #define MM_SYSTEM_SPACE_START 0xFFFFF88000000000ULL // 128 GB system PTEs [MiVaSystemPtes]
20 #define MI_DEBUG_MAPPING (PVOID)0xFFFFF89FFFFFF000ULL // FIXME should be allocated from System PTEs
21 #define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL // 128 GB paged pool [MiVaPagedPool]
22 //#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL
23 //#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL // 512 GB session space [MiVaSessionSpace]
24 #define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL
25 #define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL
26 #define MI_SYSTEM_CACHE_START 0xFFFFF98000000000ULL // 1 TB system cache (on Vista+ this is dynamic VA space) [MiVaSystemCache,MiVaSpecialPoolPaged,MiVaSpecialPoolNonPaged]
27 #define MI_SYSTEM_CACHE_END 0xFFFFFA7FFFFFFFFFULL
28 #define MI_PFN_DATABASE 0xFFFFFA8000000000ULL // up to 5.5 TB PFN database followed by non paged pool [MiVaPfnDatabase/MiVaNonPagedPool]
29 #define MI_NONPAGED_POOL_END (PVOID)0xFFFFFFFFFFBFFFFFULL
30 //#define MM_HAL_VA_START 0xFFFFFFFFFFC00000ULL // 4 MB HAL mappings, defined in NDK [MiVaHal]
31 #define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL
32 #define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START)
33 
34 /* WOW64 address definitions */
35 #define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF
36 #define MM_SYSTEM_RANGE_START_WOW64 0x80000000
37 
38 /* The size of the virtual memory area that is mapped using a single PDE */
39 #define PDE_MAPPED_VA (PTE_PER_PAGE * PAGE_SIZE)
40 
41 /* Misc address definitions */
42 //#define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME
43 //#define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START
44 //#define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1)
45 #define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE)
46 #define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
47 #define MI_MAPPING_RANGE_START HYPER_SPACE
48 #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE)
49 #define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE)
50 #define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE)
51 #define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE)
52 
53 /* Memory sizes */
54 #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
55 #define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
56 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
57 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST_BOOST ((256 * _1MB) >> PAGE_SHIFT)
58 #define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
59 #define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
60 #define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
61 #define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
62 #define MI_SESSION_VIEW_SIZE (20 * _1MB)
63 #define MI_SESSION_POOL_SIZE (16 * _1MB)
64 #define MI_SESSION_IMAGE_SIZE (8 * _1MB)
65 #define MI_SESSION_WORKING_SET_SIZE (4 * _1MB)
66 #define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
67  MI_SESSION_POOL_SIZE + \
68  MI_SESSION_IMAGE_SIZE + \
69  MI_SESSION_WORKING_SET_SIZE)
70 #define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
71 #define MI_ALLOCATION_FRAGMENT (64 * _1KB)
72 #define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
73 
74 /* Misc constants */
75 #define MM_PTE_SOFTWARE_PROTECTION_BITS 5
76 #define MI_MIN_SECONDARY_COLORS 8
77 #define MI_SECONDARY_COLORS 64
78 #define MI_MAX_SECONDARY_COLORS 1024
79 #define MI_NUMBER_SYSTEM_PTES 22000
80 #define MI_MAX_FREE_PAGE_LISTS 4
81 #define MI_HYPERSPACE_PTES (256 - 1)
82 #define MI_ZERO_PTES (32)
83 #define MI_MAX_ZERO_BITS 53
84 #define SESSION_POOL_LOOKASIDES 21
85 
86 /* MMPTE related defines */
87 #define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF)
88 #define MM_EMPTY_LIST ((ULONG_PTR)-1)
89 
90 
91 /* Easy accessing PFN in PTE */
92 #define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
93 #define PFN_FROM_PDE(v) ((v)->u.Hard.PageFrameNumber)
94 #define PFN_FROM_PPE(v) ((v)->u.Hard.PageFrameNumber)
95 #define PFN_FROM_PXE(v) ((v)->u.Hard.PageFrameNumber)
96 
97 /* Macros for portable PTE modification */
98 #define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1)
99 #define MI_MAKE_CLEAN_PAGE(x) ((x)->u.Hard.Dirty = 0)
100 #define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1)
101 #define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.CacheDisable = 1)
102 #define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.WriteThrough = 1)
103 #define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.WriteThrough = 0)
104 #define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1)
105 #if !defined(CONFIG_SMP)
106 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1)
107 #else
108 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
109 #endif
110 #define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
111 #define MI_IS_PAGE_EXECUTABLE(x) ((x)->u.Hard.NoExecute == 0)
112 #define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
113 #define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
114 #if !defined(CONFIG_SMP)
115 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1)
116 #else
117 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
118 #endif
119 
120 /* Macros to identify the page fault reason from the error code */
121 #define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
122 #define MI_IS_WRITE_ACCESS(FaultCode) BooleanFlagOn(FaultCode, 0x2)
123 #define MI_IS_INSTRUCTION_FETCH(FaultCode) BooleanFlagOn(FaultCode, 0x10)
124 
125 /* On x64, these are the same */
126 #define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
127 #define ValidKernelPpe ValidKernelPde
128 
129 /* Convert an address to a corresponding PTE */
131 PMMPTE
133 {
134  ULONG64 Offset = (ULONG64)Address >> (PTI_SHIFT - 3);
135  Offset &= 0xFFFFFFFFFULL << 3;
136  return (PMMPTE)(PTE_BASE + Offset);
137 }
138 #define MiAddressToPte(x) _MiAddressToPte((PVOID)(x))
139 
140 /* Convert an address to a corresponding PDE */
142 PMMPTE
144 {
145  ULONG64 Offset = (ULONG64)Address >> (PDI_SHIFT - 3);
146  Offset &= 0x7FFFFFF << 3;
147  return (PMMPTE)(PDE_BASE + Offset);
148 }
149 #define MiAddressToPde(x) _MiAddressToPde((PVOID)(x))
150 
151 /* Convert an address to a corresponding PPE */
153 PMMPTE
155 {
156  ULONG64 Offset = (ULONG64)Address >> (PPI_SHIFT - 3);
157  Offset &= 0x3FFFF << 3;
158  return (PMMPTE)(PPE_BASE + Offset);
159 }
160 
161 /* Convert an address to a corresponding PXE */
163 PMMPTE
165 {
166  ULONG64 Offset = (ULONG64)Address >> (PXI_SHIFT - 3);
167  Offset &= PXI_MASK << 3;
168  return (PMMPTE)(PXE_BASE + Offset);
169 }
170 
171 /* Convert an address to a corresponding PTE offset/index */
173 ULONG
175 {
176  return ((((ULONG64)Address) >> PTI_SHIFT) & 0x1FF);
177 }
178 #define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name
179 
180 /* Convert an address to a corresponding PDE offset/index */
182 ULONG
184 {
185  return ((((ULONG64)Address) >> PDI_SHIFT) & 0x1FF);
186 }
187 #define MiAddressToPdeOffset(x) MiAddressToPdi(x)
188 #define MiGetPdeOffset(x) MiAddressToPdi(x)
189 
190 /* Convert an address to a corresponding PXE offset/index */
192 ULONG
194 {
195  return ((((ULONG64)Address) >> PXI_SHIFT) & 0x1FF);
196 }
197 
198 /* Convert a PTE into a corresponding address */
200 PVOID
202 {
203  /* Use signed math */
204  return (PVOID)(((LONG64)PointerPte << 25) >> 16);
205 }
206 
207 /* Convert a PDE into a corresponding address */
209 PVOID
211 {
212  /* Use signed math */
213  return (PVOID)(((LONG64)PointerPde << 34) >> 16);
214 }
215 
216 /* Convert a PPE into a corresponding address */
218 PVOID
220 {
221  /* Use signed math */
222  return (PVOID)(((LONG64)PointerPpe << 43) >> 16);
223 }
224 
225 /* Convert a PXE into a corresponding address */
227 PVOID
229 {
230  /* Use signed math */
231  return (PVOID)(((LONG64)PointerPxe << 52) >> 16);
232 }
233 
234 /* Translate between P*Es */
235 #define MiPdeToPte(_Pde) ((PMMPTE)MiPteToAddress(_Pde))
236 #define MiPteToPde(_Pte) ((PMMPDE)MiAddressToPte(_Pte))
237 #define MiPdeToPpe(_Pde) ((PMMPPE)MiAddressToPte(_Pde))
238 
239 /* Check P*E boundaries */
240 #define MiIsPteOnPdeBoundary(PointerPte) \
241  ((((ULONG_PTR)PointerPte) & (PAGE_SIZE - 1)) == 0)
242 #define MiIsPteOnPpeBoundary(PointerPte) \
243  ((((ULONG_PTR)PointerPte) & (PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
244 #define MiIsPteOnPxeBoundary(PointerPte) \
245  ((((ULONG_PTR)PointerPte) & (PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
246 
247 //
248 // Decodes a Prototype PTE into the underlying PTE
249 //
250 #define MiProtoPteToPte(x) \
251  (PMMPTE)(((LONG64)(x)->u.Long) >> 16) /* Sign extend 48 bits */
252 
253 //
254 // Decodes a Prototype PTE into the underlying PTE
255 //
256 #define MiSubsectionPteToSubsection(x) \
257  (PMMPTE)((x)->u.Subsect.SubsectionAddress >> 16)
258 
260 VOID
262  _Out_ PMMPTE NewPte,
264 {
265  /* Mark this as a prototype */
266  NewPte->u.Long = 0;
267  NewPte->u.Subsect.Prototype = 1;
268 
269  /* Store the lower 48 bits of the Segment address */
270  NewPte->u.Subsect.SubsectionAddress = ((ULONG_PTR)Segment & 0x0000FFFFFFFFFFFF);
271 }
272 
274 VOID
276  IN PMMPTE PointerPte)
277 {
278  /* Store the Address */
279  NewPte->u.Long = (ULONG64)PointerPte << 16;
280 
281  /* Mark this as a prototype PTE */
282  NewPte->u.Proto.Prototype = 1;
283 
284  ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
285 }
286 
288 BOOLEAN
290 {
292  __debugbreak();
293  return ((PointerPte->u.Long & 0xFFFFFC01) != 0);
294 }
295 
296 INIT_FUNCTION
298 VOID
300 {
301  /* Nothing to do */
302 }
303 
305 BOOLEAN
307 {
308  return ((MiAddressToPxe(Address)->u.Hard.Valid) &&
309  (MiAddressToPpe(Address)->u.Hard.Valid) &&
310  (MiAddressToPde(Address)->u.Hard.Valid));
311 }
312 
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
union _MMPTE::@2260 u
#define IN
Definition: typedefs.h:39
#define PTE_BASE
Definition: mm.h:153
INIT_FUNCTION FORCEINLINE VOID MmInitGlobalKernelPageDirectory(VOID)
Definition: mm.h:299
#define PDE_BASE
Definition: mm.h:160
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:154
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:306
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define MiAddressToPde(x)
Definition: mm.h:149
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PDI_SHIFT
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
#define FORCEINLINE
Definition: ntbasedef.h:221
#define MiProtoPteToPte(x)
Definition: mm.h:250
#define _Out_
Definition: no_sal2.h:323
FORCEINLINE PMMPTE _MiAddressToPde(PVOID Address)
Definition: mm.h:143
#define PPI_SHIFT
#define PTI_SHIFT
FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE(_Out_ PMMPTE NewPte, _In_ PVOID Segment)
Definition: mm.h:261
#define ULL(a, b)
Definition: format_msg.c:27
_Inout_ PVOID Segment
Definition: exfuncs.h:893
FORCEINLINE PMMPTE _MiAddressToPte(PVOID Address)
Definition: mm.h:132
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:164
int64_t LONG64
Definition: typedefs.h:67
#define PXI_SHIFT
#define PPE_BASE
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned __int64 ULONG64
Definition: imports.h:198
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:193
#define PXI_MASK
FORCEINLINE PVOID MiPxeToAddress(PMMPTE PointerPxe)
Definition: mm.h:228
ULONG_PTR Long
Definition: mmtypes.h:215
#define _In_
Definition: no_sal2.h:204
#define PXE_BASE
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:275
FORCEINLINE PVOID MiPdeToAddress(PMMPTE PointerPde)
Definition: mm.h:210
FORCEINLINE ULONG MiAddressToPdi(PVOID Address)
Definition: mm.h:183
FORCEINLINE PVOID MiPpeToAddress(PMMPTE PointerPpe)
Definition: mm.h:219
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte)
Definition: mm.h:289
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:174