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