ReactOS  r75907
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 */
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 HYPER_SPACE 0xFFFFF70000000000ULL
13 #define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
14 #define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL
15 #define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL
16 //#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL
17 //#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL
18 #define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL
19 #define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL
20 #define MM_SYSTEM_SPACE_START 0xFFFFF98000000000ULL
21 #define MI_PFN_DATABASE 0xFFFFFA8000000000ULL
22 #define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME
23 #define MI_NONPAGED_POOL_END (PVOID)0xFFFFFFFFFFBFFFFFULL
24 #define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL
25 #define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START)
26 
27 /* WOW64 address definitions */
28 #define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF
29 #define MM_SYSTEM_RANGE_START_WOW64 0x80000000
30 
31 /* Misc address definitions */
32 //#define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME
33 //#define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START
34 //#define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1)
35 #define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE)
36 #define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
37 #define MI_MAPPING_RANGE_START HYPER_SPACE
38 #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE)
39 #define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE)
40 #define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE)
41 #define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE)
42 
43 /* Memory sizes */
44 #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
45 #define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
46 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
47 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST_BOOST ((256 * _1MB) >> PAGE_SHIFT)
48 #define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
49 #define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
50 #define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
51 #define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
52 #define MI_SESSION_VIEW_SIZE (20 * _1MB)
53 #define MI_SESSION_POOL_SIZE (16 * _1MB)
54 #define MI_SESSION_IMAGE_SIZE (8 * _1MB)
55 #define MI_SESSION_WORKING_SET_SIZE (4 * _1MB)
56 #define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
57  MI_SESSION_POOL_SIZE + \
58  MI_SESSION_IMAGE_SIZE + \
59  MI_SESSION_WORKING_SET_SIZE)
60 #define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
61 #define MI_ALLOCATION_FRAGMENT (64 * _1KB)
62 #define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
63 
64 /* Misc constants */
65 #define MM_PTE_SOFTWARE_PROTECTION_BITS 5
66 #define MI_MIN_SECONDARY_COLORS 8
67 #define MI_SECONDARY_COLORS 64
68 #define MI_MAX_SECONDARY_COLORS 1024
69 #define MI_NUMBER_SYSTEM_PTES 22000
70 #define MI_MAX_FREE_PAGE_LISTS 4
71 #define MI_HYPERSPACE_PTES (256 - 1)
72 #define MI_ZERO_PTES (32)
73 #define MI_MAX_ZERO_BITS 53
74 #define SESSION_POOL_LOOKASIDES 21
75 
76 /* MMPTE related defines */
77 #define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF)
78 #define MM_EMPTY_LIST ((ULONG_PTR)-1)
79 
80 
81 /* Easy accessing PFN in PTE */
82 #define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
83 #define PFN_FROM_PDE(v) ((v)->u.Hard.PageFrameNumber)
84 #define PFN_FROM_PPE(v) ((v)->u.Hard.PageFrameNumber)
85 #define PFN_FROM_PXE(v) ((v)->u.Hard.PageFrameNumber)
86 
87 /* Macros for portable PTE modification */
88 #define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1)
89 #define MI_MAKE_CLEAN_PAGE(x) ((x)->u.Hard.Dirty = 0)
90 #define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1)
91 #define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.CacheDisable = 1)
92 #define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.WriteThrough = 1)
93 #define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.WriteThrough = 0)
94 #define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1)
95 #if !defined(CONFIG_SMP)
96 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1)
97 #else
98 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
99 #endif
100 #define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
101 #define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
102 #define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
103 #if !defined(CONFIG_SMP)
104 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1)
105 #else
106 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
107 #endif
108 
109 /* On x64, these are the same */
110 #define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
111 #define ValidKernelPpe ValidKernelPde
112 
113 /* Convert an address to a corresponding PTE */
114 PMMPTE
117 {
118  ULONG64 Offset = (ULONG64)Address >> (PTI_SHIFT - 3);
119  Offset &= 0xFFFFFFFFFULL << 3;
120  return (PMMPTE)(PTE_BASE + Offset);
121 }
122 #define MiAddressToPte(x) _MiAddressToPte((PVOID)(x))
123 
124 /* Convert an address to a corresponding PDE */
125 PMMPTE
128 {
129  ULONG64 Offset = (ULONG64)Address >> (PDI_SHIFT - 3);
130  Offset &= 0x7FFFFFF << 3;
131  return (PMMPTE)(PDE_BASE + Offset);
132 }
133 #define MiAddressToPde(x) _MiAddressToPde((PVOID)(x))
134 
135 /* Convert an address to a corresponding PPE */
136 PMMPTE
139 {
140  ULONG64 Offset = (ULONG64)Address >> (PPI_SHIFT - 3);
141  Offset &= 0x3FFFF << 3;
142  return (PMMPTE)(PPE_BASE + Offset);
143 }
144 
145 /* Convert an address to a corresponding PXE */
146 PMMPTE
149 {
150  ULONG64 Offset = (ULONG64)Address >> (PXI_SHIFT - 3);
151  Offset &= PXI_MASK << 3;
152  return (PMMPTE)(PXE_BASE + Offset);
153 }
154 
155 /* Convert an address to a corresponding PTE offset/index */
156 ULONG
159 {
160  return ((((ULONG64)Address) >> PTI_SHIFT) & 0x1FF);
161 }
162 #define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name
163 
164 /* Convert an address to a corresponding PDE offset/index */
165 ULONG
168 {
169  return ((((ULONG64)Address) >> PDI_SHIFT) & 0x1FF);
170 }
171 #define MiAddressToPdeOffset(x) MiAddressToPdi(x)
172 #define MiGetPdeOffset(x) MiAddressToPdi(x)
173 
174 /* Convert an address to a corresponding PXE offset/index */
175 ULONG
178 {
179  return ((((ULONG64)Address) >> PXI_SHIFT) & 0x1FF);
180 }
181 
182 /* Convert a PTE into a corresponding address */
183 PVOID
186 {
187  /* Use signed math */
188  return (PVOID)(((LONG64)PointerPte << 25) >> 16);
189 }
190 
191 /* Convert a PDE into a corresponding address */
192 PVOID
195 {
196  /* Use signed math */
197  return (PVOID)(((LONG64)PointerPde << 34) >> 16);
198 }
199 
200 /* Convert a PPE into a corresponding address */
201 PVOID
204 {
205  /* Use signed math */
206  return (PVOID)(((LONG64)PointerPpe << 43) >> 16);
207 }
208 
209 /* Convert a PXE into a corresponding address */
210 PVOID
213 {
214  /* Use signed math */
215  return (PVOID)(((LONG64)PointerPxe << 52) >> 16);
216 }
217 
218 /* Translate between P*Es */
219 #define MiPdeToPte(_Pde) ((PMMPTE)MiPteToAddress(_Pde))
220 #define MiPteToPde(_Pte) ((PMMPDE)MiAddressToPte(_Pte))
221 #define MiPdeToPpe(_Pde) ((PMMPPE)MiAddressToPte(_Pde))
222 
223 /* Check P*E boundaries */
224 #define MiIsPteOnPdeBoundary(PointerPte) \
225  ((((ULONG_PTR)PointerPte) & (PAGE_SIZE - 1)) == 0)
226 #define MiIsPteOnPpeBoundary(PointerPte) \
227  ((((ULONG_PTR)PointerPte) & (PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
228 #define MiIsPteOnPxeBoundary(PointerPte) \
229  ((((ULONG_PTR)PointerPte) & (PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
230 
231 //
232 // Decodes a Prototype PTE into the underlying PTE
233 //
234 #define MiProtoPteToPte(x) \
235  (PMMPTE)(((LONG64)(x)->u.Long) >> 16) /* Sign extend 48 bits */
236 
237 //
238 // Decodes a Prototype PTE into the underlying PTE
239 //
240 #define MiSubsectionPteToSubsection(x) \
241  (PMMPTE)((x)->u.Subsect.SubsectionAddress >> 16)
242 
244 VOID
246  IN PVOID Segment)
247 {
248  ASSERT(FALSE);
249 }
250 
252 VOID
254  IN PMMPTE PointerPte)
255 {
256  /* Store the Address */
257  NewPte->u.Long = (ULONG64)PointerPte << 16;
258 
259  /* Mark this as a prototype PTE */
260  NewPte->u.Proto.Prototype = 1;
261 
262  ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
263 }
264 
266 BOOLEAN
268 {
270  __debugbreak();
271  return ((PointerPte->u.Long & 0xFFFFFC01) != 0);
272 }
273 
274 VOID
277 {
278  /* Nothing to do */
279 }
280 
281 BOOLEAN
284 {
285  return ((MiAddressToPxe(Address)->u.Hard.Valid) &&
286  (MiAddressToPpe(Address)->u.Hard.Valid) &&
287  (MiAddressToPde(Address)->u.Hard.Valid));
288 }
289 
DWORD *typedef PVOID
Definition: winlogon.h:52
#define IN
Definition: typedefs.h:39
PVOID ULONG Address
Definition: oprghdlr.h:14
#define PTE_BASE
Definition: mm.h:28
VOID FORCEINLINE MmInitGlobalKernelPageDirectory(VOID)
Definition: mm.h:276
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PVOID FORCEINLINE MiPpeToAddress(PMMPTE PointerPpe)
Definition: mm.h:203
#define PDE_BASE
Definition: mm.h:29
PVOID FORCEINLINE MiPxeToAddress(PMMPTE PointerPxe)
Definition: mm.h:212
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:138
ULONG FORCEINLINE MiAddressToPti(PVOID Address)
Definition: mm.h:158
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define MiAddressToPde(x)
Definition: mm.h:133
ULONG FORCEINLINE MiAddressToPxi(PVOID Address)
Definition: mm.h:177
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
uint64_t ULONG64
Definition: typedefs.h:66
#define PDI_SHIFT
FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE(IN PMMPTE NewPte, IN PVOID Segment)
Definition: mm.h:245
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
#define FORCEINLINE
Definition: ntbasedef.h:213
#define MiProtoPteToPte(x)
Definition: mm.h:234
#define PPI_SHIFT
#define PTI_SHIFT
#define ULL(a, b)
Definition: format_msg.c:27
_Inout_ PVOID Segment
Definition: exfuncs.h:893
PVOID FORCEINLINE MiPdeToAddress(PMMPTE PointerPde)
Definition: mm.h:194
int64_t LONG64
Definition: typedefs.h:67
unsigned char BOOLEAN
#define PXI_SHIFT
PMMPTE FORCEINLINE _MiAddressToPte(PVOID Address)
Definition: mm.h:116
#define PPE_BASE
ULONG FORCEINLINE MiAddressToPdi(PVOID Address)
Definition: mm.h:167
#define PXI_MASK
PMMPTE FORCEINLINE MiAddressToPxe(PVOID Address)
Definition: mm.h:148
ULONG_PTR Long
Definition: mmtypes.h:215
PMMPTE FORCEINLINE _MiAddressToPde(PVOID Address)
Definition: mm.h:127
#define PXE_BASE
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:253
union _MMPTE::@2087 u
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte)
Definition: mm.h:267
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN FORCEINLINE MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:283