Preparations for checked/free like builds (CPRINT == DbgPrint when DBG is defined).
[reactos.git] / reactos / ntoskrnl / include / internal / mm.h
1 /*
2 * Higher level memory managment definitions
3 */
4
5 #ifndef __INCLUDE_INTERNAL_MM_H
6 #define __INCLUDE_INTERNAL_MM_H
7
8 #include <internal/ntoskrnl.h>
9 #include <internal/arch/mm.h>
10
11 /* TYPES *********************************************************************/
12
13 struct _EPROCESS;
14 typedef ULONG SWAPENTRY;
15
16 #define MEMORY_AREA_INVALID (0)
17 #define MEMORY_AREA_SECTION_VIEW_COMMIT (1)
18 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
19 #define MEMORY_AREA_NO_CACHE (3)
20 #define MEMORY_AREA_IO_MAPPING (4)
21 #define MEMORY_AREA_SYSTEM (5)
22 #define MEMORY_AREA_MDL_MAPPING (7)
23 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
24 #define MEMORY_AREA_SECTION_VIEW_RESERVE (9)
25 #define MEMORY_AREA_CACHE_SEGMENT (10)
26 #define MEMORY_AREA_SHARED_DATA (11)
27 #define MEMORY_AREA_WORKING_SET (12)
28 #define MEMORY_AREA_KERNEL_STACK (13)
29
30 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
31 ((x) / (4*1024*1024))
32 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
33 ((((x)) % (4*1024*1024)) / (4*1024))
34
35 #define NR_SECTION_PAGE_TABLES (1024)
36 #define NR_SECTION_PAGE_ENTRIES (1024)
37
38 /*
39 * Flags for section objects
40 */
41 #define SO_PHYSICAL_MEMORY (0x1)
42
43 /*
44 * Additional flags for protection attributes
45 */
46 #define PAGE_WRITETHROUGH (1024)
47 #define PAGE_SYSTEM (2048)
48 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
49 PAGE_READWRITE | \
50 PAGE_WRITECOPY | \
51 PAGE_EXECUTE | \
52 PAGE_EXECUTE_READ | \
53 PAGE_EXECUTE_READWRITE | \
54 PAGE_EXECUTE_WRITECOPY | \
55 PAGE_GUARD | \
56 PAGE_NOACCESS | \
57 PAGE_NOCACHE)
58
59 typedef struct
60 {
61 ULONG Pages[NR_SECTION_PAGE_ENTRIES];
62 } SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
63
64 typedef struct
65 {
66 PSECTION_PAGE_TABLE PageTables[NR_SECTION_PAGE_TABLES];
67 } SECTION_PAGE_DIRECTORY, *PSECTION_PAGE_DIRECTORY;
68
69 #define MM_PAGEFILE_SECTION (0x1)
70 #define MM_IMAGE_SECTION (0x2)
71
72 #define MM_SECTION_SEGMENT_BSS (0x1)
73
74 typedef struct _MM_SECTION_SEGMENT
75 {
76 ULONG FileOffset;
77 ULONG Protection;
78 ULONG Attributes;
79 ULONG Length;
80 ULONG RawLength;
81 KMUTEX Lock;
82 ULONG ReferenceCount;
83 SECTION_PAGE_DIRECTORY PageDirectory;
84 ULONG Flags;
85 PVOID VirtualAddress;
86 ULONG Characteristics;
87 } MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
88
89 typedef struct
90 {
91 CSHORT Type;
92 CSHORT Size;
93 LARGE_INTEGER MaximumSize;
94 ULONG SectionPageProtection;
95 ULONG AllocateAttributes;
96 PFILE_OBJECT FileObject;
97 LIST_ENTRY ViewListHead;
98 KSPIN_LOCK ViewListLock;
99 KMUTEX Lock;
100 ULONG Flags;
101 ULONG NrSegments;
102 PMM_SECTION_SEGMENT Segments;
103 PVOID ImageBase;
104 PVOID EntryPoint;
105 ULONG StackReserve;
106 ULONG StackCommit;
107 ULONG Subsystem;
108 ULONG MinorSubsystemVersion;
109 ULONG MajorSubsystemVersion;
110 ULONG ImageCharacteristics;
111 USHORT Machine;
112 BOOLEAN Executable;
113 } SECTION_OBJECT, *PSECTION_OBJECT;
114
115 typedef struct
116 {
117 ULONG Type;
118 PVOID BaseAddress;
119 ULONG Length;
120 ULONG Attributes;
121 LIST_ENTRY Entry;
122 ULONG LockCount;
123 struct _EPROCESS* Process;
124 union
125 {
126 struct
127 {
128 SECTION_OBJECT* Section;
129 ULONG ViewOffset;
130 LIST_ENTRY ViewListEntry;
131 PMM_SECTION_SEGMENT Segment;
132 } SectionData;
133 struct
134 {
135 LIST_ENTRY SegmentListHead;
136 } VirtualMemoryData;
137 } Data;
138 } MEMORY_AREA, *PMEMORY_AREA;
139
140 typedef struct _KCIRCULAR_QUEUE
141 {
142 ULONG First;
143 ULONG Last;
144 ULONG CurrentSize;
145 ULONG MaximumSize;
146 PVOID* Mem;
147 } KCIRCULAR_QUEUE, *PKCIRCULAR_QUEUE;
148
149 typedef struct _MADDRESS_SPACE
150 {
151 LIST_ENTRY MAreaListHead;
152 KMUTEX Lock;
153 ULONG LowestAddress;
154 struct _EPROCESS* Process;
155 PMEMORY_AREA WorkingSetArea;
156 KCIRCULAR_QUEUE WSQueue;
157 PUSHORT PageTableRefCountTable;
158 ULONG PageTableRefCountTableSize;
159 } MADDRESS_SPACE, *PMADDRESS_SPACE;
160
161 /* FUNCTIONS */
162
163 VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
164 VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
165 VOID MmInitializeKernelAddressSpace(VOID);
166 PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
167 PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
168 NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
169 PMADDRESS_SPACE AddressSpace);
170 NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
171 PVOID STDCALL MmAllocateSection (IN ULONG Length);
172 NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
173 PMADDRESS_SPACE AddressSpace,
174 ULONG Type,
175 PVOID* BaseAddress,
176 ULONG Length,
177 ULONG Attributes,
178 MEMORY_AREA** Result,
179 BOOL FixedAddress);
180 MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
181 PVOID Address);
182 NTSTATUS MmInitMemoryAreas(VOID);
183 VOID ExInitNonPagedPool(ULONG BaseAddress);
184 NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
185 PVOID BaseAddress,
186 ULONG Length,
187 VOID (*FreePage)(PVOID Context, PVOID Address,
188 ULONG PhysAddr),
189 PVOID FreePageContext);
190 VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
191 NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
192 NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
193 NTSTATUS MmInitSectionImplementation(VOID);
194
195 #define MM_LOWEST_USER_ADDRESS (4096)
196
197 PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
198 PMADDRESS_SPACE AddressSpace,
199 PMEMORY_AREA OriginalMemoryArea,
200 PVOID BaseAddress,
201 ULONG Length,
202 ULONG NewType,
203 ULONG NewAttributes);
204 PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
205 PVOID LastPhysKernelAddress,
206 ULONG MemorySizeInPages,
207 ULONG LastKernelBase,
208 PADDRESS_RANGE BIOSMemoryMap,
209 ULONG AddressRangeCount);
210
211 PVOID MmAllocPage(SWAPENTRY SavedSwapEntry);
212 VOID MmDereferencePage(PVOID PhysicalAddress);
213 VOID MmReferencePage(PVOID PhysicalAddress);
214 VOID MmDeletePageTable(struct _EPROCESS* Process,
215 PVOID Address);
216 NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
217 struct _EPROCESS* Dest);
218 NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
219 NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
220 VOID
221 MmDeleteVirtualMapping(struct _EPROCESS* Process,
222 PVOID Address,
223 BOOL FreePage,
224 BOOL* WasDirty,
225 ULONG* PhysicalPage);
226
227 #define MM_PAGE_CLEAN (0)
228 #define MM_PAGE_DIRTY (1)
229
230 VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
231 PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
232 VOID MiShutdownMemoryManager(VOID);
233 ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
234 PVOID Address);
235 NTSTATUS STDCALL
236 MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
237 VOID MmInitPagingFile(VOID);
238
239 /* FIXME: it should be in ddk/mmfuncs.h */
240 NTSTATUS
241 STDCALL
242 MmCreateSection (
243 OUT PSECTION_OBJECT * SectionObject,
244 IN ACCESS_MASK DesiredAccess,
245 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
246 IN PLARGE_INTEGER MaximumSize,
247 IN ULONG SectionPageProtection,
248 IN ULONG AllocationAttributes,
249 IN HANDLE FileHandle OPTIONAL,
250 IN PFILE_OBJECT File OPTIONAL
251 );
252
253 NTSTATUS MmPageFault(ULONG Cs,
254 PULONG Eip,
255 PULONG Eax,
256 ULONG Cr2,
257 ULONG ErrorCode);
258
259 NTSTATUS
260 MmAccessFault(KPROCESSOR_MODE Mode,
261 ULONG Address,
262 BOOLEAN FromMdl);
263 NTSTATUS
264 MmNotPresentFault(KPROCESSOR_MODE Mode,
265 ULONG Address,
266 BOOLEAN FromMdl);
267 NTSTATUS
268 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
269 MEMORY_AREA* MemoryArea,
270 PVOID Address,
271 BOOLEAN Locked);
272 NTSTATUS
273 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
274 MEMORY_AREA* MemoryArea,
275 PVOID Address,
276 BOOLEAN Locked);
277 NTSTATUS MmWaitForPage(PVOID Page);
278 VOID MmClearWaitPage(PVOID Page);
279 VOID MmSetWaitPage(PVOID Page);
280 BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
281 BOOLEAN MmIsPageTablePresent(PVOID PAddress);
282 ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
283 MEMORY_AREA* MemoryArea,
284 PVOID Address,
285 PBOOLEAN Ul);
286 ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
287 PMEMORY_AREA MemoryArea,
288 PVOID Address,
289 PBOOLEAN Ul);
290 MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
291 PVOID Address,
292 ULONG Length);
293
294 VOID ExUnmapPage(PVOID Addr);
295 PVOID ExAllocatePage(VOID);
296
297 VOID MmLockWorkingSet(struct _EPROCESS* Process);
298 VOID MmUnlockWorkingSet(struct _EPROCESS* Process);
299 VOID MmInitializeWorkingSet(struct _EPROCESS* Process,
300 PMADDRESS_SPACE AddressSpace);
301 ULONG MmTrimWorkingSet(struct _EPROCESS* Process,
302 ULONG ReduceHint);
303 VOID MmRemovePageFromWorkingSet(struct _EPROCESS* Process,
304 PVOID Address);
305 VOID MmAddPageToWorkingSet(struct _EPROCESS* Process,
306 PVOID Address);
307
308 VOID MmInitPagingFile(VOID);
309 BOOLEAN MmReserveSwapPages(ULONG Nr);
310 VOID MmDereserveSwapPages(ULONG Nr);
311 SWAPENTRY MmAllocSwapPage(VOID);
312 VOID MmFreeSwapPage(SWAPENTRY Entry);
313
314 VOID MmInit1(ULONG FirstKernelPhysAddress,
315 ULONG LastKernelPhysAddress,
316 ULONG LastKernelAddress,
317 PADDRESS_RANGE BIOSMemoryMap,
318 ULONG AddressRangeCount);
319 VOID MmInit2(VOID);
320 VOID MmInit3(VOID);
321 NTSTATUS MmInitPagerThread(VOID);
322
323 VOID MmInitKernelMap(PVOID BaseAddress);
324
325 VOID MmWaitForFreePages(VOID);
326 PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry);
327 PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry);
328 NTSTATUS MmCreatePageTable(PVOID PAddress);
329
330 typedef struct
331 {
332 ULONG NrTotalPages;
333 ULONG NrSystemPages;
334 ULONG NrReservedPages;
335 ULONG NrUserPages;
336 ULONG NrFreePages;
337 ULONG NrDirtyPages;
338 ULONG NrLockedPages;
339 ULONG PagingRequestsInLastMinute;
340 ULONG PagingRequestsInLastFiveMinutes;
341 ULONG PagingRequestsInLastFifteenMinutes;
342 } MM_STATS;
343
344 extern MM_STATS MmStats;
345
346 NTSTATUS
347 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
348 PMEMORY_AREA MArea,
349 PVOID Address);
350 NTSTATUS
351 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
352 PMEMORY_AREA MArea,
353 PVOID Address);
354 PVOID
355 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
356 NTSTATUS
357 MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
358 NTSTATUS
359 MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
360 VOID
361 MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
362 ULONG
363 MmGetFlagsPage(PVOID PhysicalAddress);
364 VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
365 SWAPENTRY SavedSwapEntry);
366 SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
367 VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
368 VOID MmLockPage(PVOID PhysicalPage);
369 VOID MmUnlockPage(PVOID PhysicalPage);
370
371 NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
372 NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
373 NTSTATUS
374 MmCreatePhysicalMemorySection(VOID);
375 PVOID
376 MmGetContinuousPages(ULONG NumberOfBytes,
377 PHYSICAL_ADDRESS HighestAcceptableAddress,
378 ULONG Alignment);
379
380 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
381
382 NTSTATUS
383 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
384 MEMORY_AREA* MemoryArea,
385 PVOID Address,
386 BOOLEAN Locked);
387 ULONG
388 MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
389 PVOID
390 ExAllocatePageWithPhysPage(ULONG PhysPage);
391 ULONG
392 MmGetReferenceCountPage(PVOID PhysicalAddress);
393 BOOLEAN
394 MmIsUsablePage(PVOID PhysicalAddress);
395
396 #define MM_PAGEOP_PAGEIN (1)
397 #define MM_PAGEOP_PAGEOUT (2)
398 #define MM_PAGEOP_PAGESYNCH (3)
399 #define MM_PAGEOP_ACCESSFAULT (4)
400
401 typedef struct _MM_PAGEOP
402 {
403 /* Type of operation. */
404 ULONG OpType;
405 /* Number of threads interested in this operation. */
406 ULONG ReferenceCount;
407 /* Event that will be set when the operation is completed. */
408 KEVENT CompletionEvent;
409 /* Status of the operation once it is completed. */
410 NTSTATUS Status;
411 /* TRUE if the operation was abandoned. */
412 BOOLEAN Abandoned;
413 /* The memory area to be affected by the operation. */
414 PMEMORY_AREA MArea;
415 ULONG Hash;
416 struct _MM_PAGEOP* Next;
417 struct _ETHREAD* Thread;
418 /*
419 * These fields are used to identify the operation if it is against a
420 * virtual memory area.
421 */
422 ULONG Pid;
423 PVOID Address;
424 /*
425 * These fields are used to identify the operation if it is against a
426 * section mapping.
427 */
428 PMM_SECTION_SEGMENT Segment;
429 ULONG Offset;
430 } MM_PAGEOP, *PMM_PAGEOP;
431
432 VOID
433 MmReleasePageOp(PMM_PAGEOP PageOp);
434
435 PMM_PAGEOP
436 MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
437 PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
438
439 VOID
440 MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
441 VOID
442 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
443 VOID
444 MmMarkPageMapped(PVOID PhysicalAddress);
445 VOID
446 MmMarkPageUnmapped(PVOID PhysicalAddress);
447 VOID
448 MmFreeSectionSegments(PFILE_OBJECT FileObject);
449
450 typedef struct _MM_IMAGE_SECTION_OBJECT
451 {
452 ULONG NrSegments;
453 MM_SECTION_SEGMENT Segments[0];
454 } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
455
456 VOID
457 MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
458 NTSTATUS
459 MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
460 NTSTATUS
461 MiZeroPage(ULONG PhysPage);
462 BOOLEAN
463 MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
464 SWAPENTRY
465 MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
466
467 #define STATUS_MM_RESTART_OPERATION (0xD0000001)
468
469 NTSTATUS
470 MmCreateVirtualMappingForKernel(PVOID Address,
471 ULONG flProtect,
472 ULONG PhysicalAddress);
473
474 #endif