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