9c7fb35e950d2495ce3894e7abcec4ab73670570
[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
209 PVOID MmAllocPage(SWAPENTRY SavedSwapEntry);
210 VOID MmDereferencePage(PVOID PhysicalAddress);
211 VOID MmReferencePage(PVOID PhysicalAddress);
212 VOID MmDeletePageTable(struct _EPROCESS* Process,
213 PVOID Address);
214 NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
215 struct _EPROCESS* Dest);
216 NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
217 NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
218 VOID
219 MmDeleteVirtualMapping(struct _EPROCESS* Process,
220 PVOID Address,
221 BOOL FreePage,
222 BOOL* WasDirty,
223 ULONG* PhysicalPage);
224
225 #define MM_PAGE_CLEAN (0)
226 #define MM_PAGE_DIRTY (1)
227
228 VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
229 PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
230 VOID MiShutdownMemoryManager(VOID);
231 ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
232 PVOID Address);
233 NTSTATUS STDCALL
234 MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
235 VOID MmInitPagingFile(VOID);
236
237 /* FIXME: it should be in ddk/mmfuncs.h */
238 NTSTATUS
239 STDCALL
240 MmCreateSection (
241 OUT PSECTION_OBJECT * SectionObject,
242 IN ACCESS_MASK DesiredAccess,
243 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
244 IN PLARGE_INTEGER MaximumSize,
245 IN ULONG SectionPageProtection,
246 IN ULONG AllocationAttributes,
247 IN HANDLE FileHandle OPTIONAL,
248 IN PFILE_OBJECT File OPTIONAL
249 );
250
251 NTSTATUS MmPageFault(ULONG Cs,
252 PULONG Eip,
253 PULONG Eax,
254 ULONG Cr2,
255 ULONG ErrorCode);
256
257 NTSTATUS
258 MmAccessFault(KPROCESSOR_MODE Mode,
259 ULONG Address,
260 BOOLEAN FromMdl);
261 NTSTATUS
262 MmNotPresentFault(KPROCESSOR_MODE Mode,
263 ULONG Address,
264 BOOLEAN FromMdl);
265 NTSTATUS
266 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
267 MEMORY_AREA* MemoryArea,
268 PVOID Address,
269 BOOLEAN Locked);
270 NTSTATUS
271 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
272 MEMORY_AREA* MemoryArea,
273 PVOID Address,
274 BOOLEAN Locked);
275 NTSTATUS MmWaitForPage(PVOID Page);
276 VOID MmClearWaitPage(PVOID Page);
277 VOID MmSetWaitPage(PVOID Page);
278 BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
279 BOOLEAN MmIsPageTablePresent(PVOID PAddress);
280 ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
281 MEMORY_AREA* MemoryArea,
282 PVOID Address,
283 PBOOLEAN Ul);
284 ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
285 PMEMORY_AREA MemoryArea,
286 PVOID Address,
287 PBOOLEAN Ul);
288 MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
289 PVOID Address,
290 ULONG Length);
291
292 VOID ExUnmapPage(PVOID Addr);
293 PVOID ExAllocatePage(VOID);
294
295 VOID MmLockWorkingSet(struct _EPROCESS* Process);
296 VOID MmUnlockWorkingSet(struct _EPROCESS* Process);
297 VOID MmInitializeWorkingSet(struct _EPROCESS* Process,
298 PMADDRESS_SPACE AddressSpace);
299 ULONG MmTrimWorkingSet(struct _EPROCESS* Process,
300 ULONG ReduceHint);
301 VOID MmRemovePageFromWorkingSet(struct _EPROCESS* Process,
302 PVOID Address);
303 VOID MmAddPageToWorkingSet(struct _EPROCESS* Process,
304 PVOID Address);
305
306 VOID MmInitPagingFile(VOID);
307 BOOLEAN MmReserveSwapPages(ULONG Nr);
308 VOID MmDereserveSwapPages(ULONG Nr);
309 SWAPENTRY MmAllocSwapPage(VOID);
310 VOID MmFreeSwapPage(SWAPENTRY Entry);
311
312 VOID MmInit1(ULONG FirstKernelPhysAddress,
313 ULONG LastKernelPhysAddress,
314 ULONG LastKernelAddress);
315 VOID MmInit2(VOID);
316 VOID MmInit3(VOID);
317 NTSTATUS MmInitPagerThread(VOID);
318
319 VOID MmInitKernelMap(PVOID BaseAddress);
320
321 VOID MmWaitForFreePages(VOID);
322 PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry);
323 PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry);
324 NTSTATUS MmCreatePageTable(PVOID PAddress);
325
326 typedef struct
327 {
328 ULONG NrTotalPages;
329 ULONG NrSystemPages;
330 ULONG NrReservedPages;
331 ULONG NrUserPages;
332 ULONG NrFreePages;
333 ULONG NrDirtyPages;
334 ULONG NrLockedPages;
335 ULONG PagingRequestsInLastMinute;
336 ULONG PagingRequestsInLastFiveMinutes;
337 ULONG PagingRequestsInLastFifteenMinutes;
338 } MM_STATS;
339
340 extern MM_STATS MmStats;
341
342 NTSTATUS
343 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
344 PMEMORY_AREA MArea,
345 PVOID Address);
346 NTSTATUS
347 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
348 PMEMORY_AREA MArea,
349 PVOID Address);
350 PVOID
351 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
352 NTSTATUS
353 MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
354 NTSTATUS
355 MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
356 VOID
357 MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
358 ULONG
359 MmGetFlagsPage(PVOID PhysicalAddress);
360 VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
361 SWAPENTRY SavedSwapEntry);
362 SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
363 VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
364 VOID MmLockPage(PVOID PhysicalPage);
365 VOID MmUnlockPage(PVOID PhysicalPage);
366
367 NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
368 NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
369 NTSTATUS
370 MmCreatePhysicalMemorySection(VOID);
371 PVOID
372 MmGetContinuousPages(ULONG NumberOfBytes,
373 PHYSICAL_ADDRESS HighestAcceptableAddress,
374 ULONG Alignment);
375
376 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
377
378 NTSTATUS
379 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
380 MEMORY_AREA* MemoryArea,
381 PVOID Address,
382 BOOLEAN Locked);
383 ULONG
384 MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
385 PVOID
386 ExAllocatePageWithPhysPage(ULONG PhysPage);
387 ULONG
388 MmGetReferenceCountPage(PVOID PhysicalAddress);
389 BOOLEAN
390 MmIsUsablePage(PVOID PhysicalAddress);
391
392 #define MM_PAGEOP_PAGEIN (1)
393 #define MM_PAGEOP_PAGEOUT (2)
394 #define MM_PAGEOP_PAGESYNCH (3)
395 #define MM_PAGEOP_ACCESSFAULT (4)
396
397 typedef struct _MM_PAGEOP
398 {
399 /* Type of operation. */
400 ULONG OpType;
401 /* Number of threads interested in this operation. */
402 ULONG ReferenceCount;
403 /* Event that will be set when the operation is completed. */
404 KEVENT CompletionEvent;
405 /* Status of the operation once it is completed. */
406 NTSTATUS Status;
407 /* TRUE if the operation was abandoned. */
408 BOOLEAN Abandoned;
409 /* The memory area to be affected by the operation. */
410 PMEMORY_AREA MArea;
411 ULONG Hash;
412 struct _MM_PAGEOP* Next;
413 struct _ETHREAD* Thread;
414 /*
415 * These fields are used to identify the operation if it is against a
416 * virtual memory area.
417 */
418 ULONG Pid;
419 PVOID Address;
420 /*
421 * These fields are used to identify the operation if it is against a
422 * section mapping.
423 */
424 PMM_SECTION_SEGMENT Segment;
425 ULONG Offset;
426 } MM_PAGEOP, *PMM_PAGEOP;
427
428 VOID
429 MmReleasePageOp(PMM_PAGEOP PageOp);
430
431 PMM_PAGEOP
432 MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
433 PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
434
435 VOID
436 MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
437 VOID
438 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
439 VOID
440 MmMarkPageMapped(PVOID PhysicalAddress);
441 VOID
442 MmMarkPageUnmapped(PVOID PhysicalAddress);
443 VOID
444 MmFreeSectionSegments(PFILE_OBJECT FileObject);
445
446 typedef struct _MM_IMAGE_SECTION_OBJECT
447 {
448 ULONG NrSegments;
449 MM_SECTION_SEGMENT Segments[0];
450 } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
451
452 VOID
453 MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
454 NTSTATUS
455 MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
456 NTSTATUS
457 MiZeroPage(ULONG PhysPage);
458 BOOLEAN
459 MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
460 SWAPENTRY
461 MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
462
463 #define STATUS_MM_RESTART_OPERATION (0xD0000001)
464
465 NTSTATUS
466 MmCreateVirtualMappingForKernel(PVOID Address,
467 ULONG flProtect,
468 ULONG PhysicalAddress);
469
470 #endif