Fixed memory manager bugs
[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/mmhal.h>
10
11 /* TYPES *********************************************************************/
12
13 struct _EPROCESS;
14 typedef ULONG SWAPENTRY;
15
16 enum
17 {
18 MEMORY_AREA_INVALID,
19 MEMORY_AREA_SECTION_VIEW_COMMIT,
20 MEMORY_AREA_CONTINUOUS_MEMORY,
21 MEMORY_AREA_NO_CACHE,
22 MEMORY_AREA_IO_MAPPING,
23 MEMORY_AREA_SYSTEM,
24 MEMORY_AREA_MDL_MAPPING,
25 MEMORY_AREA_VIRTUAL_MEMORY,
26 MEMORY_AREA_SECTION_VIEW_RESERVE,
27 MEMORY_AREA_CACHE_SEGMENT,
28 MEMORY_AREA_SHARED_DATA,
29 };
30
31 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
32 ((x) / (4*1024*1024))
33 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
34 ((((x)) % (4*1024*1024)) / (4*1024))
35
36 #define NR_SECTION_PAGE_TABLES (1024)
37 #define NR_SECTION_PAGE_ENTRIES (1024)
38
39 #define SPE_PAGEIN_PENDING (0x1)
40 #define SPE_MPW_PENDING (0x2)
41 #define SPE_PAGEOUT_PENDING (0x4)
42 #define SPE_DIRTY (0x8)
43 #define SPE_IN_PAGEFILE (0x10)
44
45 typedef struct
46 {
47 ULONG Pages[NR_SECTION_PAGE_ENTRIES];
48 } SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
49
50 typedef struct
51 {
52 PSECTION_PAGE_TABLE PageTables[NR_SECTION_PAGE_TABLES];
53 } SECTION_PAGE_DIRECTORY, *PSECTION_PAGE_DIRECTORY;
54
55 typedef struct
56 {
57 CSHORT Type;
58 CSHORT Size;
59 LARGE_INTEGER MaximumSize;
60 ULONG SectionPageProtection;
61 ULONG AllocateAttributes;
62 PFILE_OBJECT FileObject;
63 LIST_ENTRY ViewListHead;
64 KSPIN_LOCK ViewListLock;
65 KMUTEX Lock;
66 SECTION_PAGE_DIRECTORY PageDirectory;
67 } SECTION_OBJECT, *PSECTION_OBJECT;
68
69 typedef struct
70 {
71 ULONG Type;
72 PVOID BaseAddress;
73 ULONG Length;
74 ULONG Attributes;
75 LIST_ENTRY Entry;
76 ULONG LockCount;
77 struct _EPROCESS* Process;
78 union
79 {
80 struct
81 {
82 SECTION_OBJECT* Section;
83 ULONG ViewOffset;
84 LIST_ENTRY ViewListEntry;
85 } SectionData;
86 struct
87 {
88 LIST_ENTRY SegmentListHead;
89 } VirtualMemoryData;
90 } Data;
91 } MEMORY_AREA, *PMEMORY_AREA;
92
93 #define WSET_ADDRESSES_IN_PAGE (1020)
94
95 typedef struct _MWORKING_SET
96 {
97 PVOID Address[WSET_ADDRESSES_IN_PAGE];
98 struct _MWORKING_SET* Next;
99 } MWORKING_SET, *PMWORKING_SET;
100
101 typedef struct _MADDRESS_SPACE
102 {
103 LIST_ENTRY MAreaListHead;
104 KMUTEX Lock;
105 ULONG LowestAddress;
106 struct _EPROCESS* Process;
107 ULONG WorkingSetSize;
108 ULONG WorkingSetLruFirst;
109 ULONG WorkingSetLruLast;
110 ULONG WorkingSetPagesAllocated;
111 PUSHORT PageTableRefCountTable;
112 ULONG PageTableRefCountTableSize;
113 } MADDRESS_SPACE, *PMADDRESS_SPACE;
114
115 /* FUNCTIONS */
116
117 VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
118 VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
119 VOID MmInitializeKernelAddressSpace(VOID);
120 PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
121 PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
122 NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
123 PMADDRESS_SPACE AddressSpace);
124 NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
125 PVOID STDCALL MmAllocateSection (IN ULONG Length);
126 NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
127 PMADDRESS_SPACE AddressSpace,
128 ULONG Type,
129 PVOID* BaseAddress,
130 ULONG Length,
131 ULONG Attributes,
132 MEMORY_AREA** Result);
133 MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
134 PVOID Address);
135 NTSTATUS MmInitMemoryAreas(VOID);
136 VOID ExInitNonPagedPool(ULONG BaseAddress);
137 NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
138 PVOID BaseAddress,
139 ULONG Length,
140 BOOLEAN FreePages);
141 VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
142 NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
143 NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
144 NTSTATUS MmInitSectionImplementation(VOID);
145
146 #define MM_LOWEST_USER_ADDRESS (4096)
147
148 PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
149 PMADDRESS_SPACE AddressSpace,
150 PMEMORY_AREA OriginalMemoryArea,
151 PVOID BaseAddress,
152 ULONG Length,
153 ULONG NewType,
154 ULONG NewAttributes);
155 PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
156 PVOID LastPhysKernelAddress,
157 ULONG MemorySizeInPages,
158 ULONG LastKernelBase);
159
160 PVOID MmAllocPage(SWAPENTRY SavedSwapEntry);
161 VOID MmDereferencePage(PVOID PhysicalAddress);
162 VOID MmReferencePage(PVOID PhysicalAddress);
163 VOID MmDeletePageTable(struct _EPROCESS* Process,
164 PVOID Address);
165 NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
166 struct _EPROCESS* Dest);
167 NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
168 NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
169 VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
170 PVOID Address,
171 BOOL FreePage);
172
173 VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
174 PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
175 VOID MiShutdownMemoryManager(VOID);
176 ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
177 PVOID Address);
178 NTSTATUS STDCALL MmUnmapViewOfSection(struct _EPROCESS* Process,
179 PMEMORY_AREA MemoryArea);
180 NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes);
181 NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes);
182 VOID MmInitPagingFile(VOID);
183
184 /* FIXME: it should be in ddk/mmfuncs.h */
185 NTSTATUS
186 STDCALL
187 MmCreateSection (
188 OUT PSECTION_OBJECT * SectionObject,
189 IN ACCESS_MASK DesiredAccess,
190 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
191 IN PLARGE_INTEGER MaximumSize,
192 IN ULONG SectionPageProtection,
193 IN ULONG AllocationAttributes,
194 IN HANDLE FileHandle OPTIONAL,
195 IN PFILE_OBJECT File OPTIONAL
196 );
197
198 NTSTATUS MmPageFault(ULONG Cs,
199 PULONG Eip,
200 PULONG Eax,
201 ULONG Cr2,
202 ULONG ErrorCode);
203
204 NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
205 ULONG Address);
206 NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
207 ULONG Address);
208 NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
209 MEMORY_AREA* MemoryArea,
210 PVOID Address);
211 NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
212 MEMORY_AREA* MemoryArea,
213 PVOID Address);
214 NTSTATUS MmWaitForPage(PVOID Page);
215 VOID MmClearWaitPage(PVOID Page);
216 VOID MmSetWaitPage(PVOID Page);
217 BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
218 BOOLEAN MmIsPageTablePresent(PVOID PAddress);
219 ULONG MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
220 MEMORY_AREA* MemoryArea,
221 PVOID Address,
222 PBOOLEAN Ul);
223 ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
224 PMEMORY_AREA MemoryArea,
225 PVOID Address,
226 PBOOLEAN Ul);
227 MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
228 PVOID Address,
229 ULONG Length);
230
231 VOID ExUnmapPage(PVOID Addr);
232 PVOID ExAllocatePage(VOID);
233
234 VOID MmLockWorkingSet(struct _EPROCESS* Process);
235 VOID MmUnlockWorkingSet(struct _EPROCESS* Process);
236 VOID MmInitializeWorkingSet(struct _EPROCESS* Process,
237 PMADDRESS_SPACE AddressSpace);
238 ULONG MmTrimWorkingSet(struct _EPROCESS* Process,
239 ULONG ReduceHint);
240 VOID MmRemovePageFromWorkingSet(struct _EPROCESS* Process,
241 PVOID Address);
242 BOOLEAN MmAddPageToWorkingSet(struct _EPROCESS* Process,
243 PVOID Address);
244
245 VOID MmInitPagingFile(VOID);
246 VOID MmReserveSwapPages(ULONG Nr);
247 VOID MmDereserveSwapPages(ULONG Nr);
248 SWAPENTRY MmAllocSwapPage(VOID);
249 VOID MmFreeSwapPage(SWAPENTRY Entry);
250
251 VOID MmInit1(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress);
252 VOID MmInit2(VOID);
253 VOID MmInit3(VOID);
254 NTSTATUS MmInitPagerThread(VOID);
255
256 VOID MmInitKernelMap(PVOID BaseAddress);
257 unsigned int alloc_pool_region(unsigned int nr_pages);
258
259 VOID MmWaitForFreePages(VOID);
260 PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry);
261 PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry);
262 NTSTATUS MmCreatePageTable(PVOID PAddress);
263
264 typedef struct
265 {
266 ULONG NrTotalPages;
267 ULONG NrSystemPages;
268 ULONG NrReservedPages;
269 ULONG NrUserPages;
270 ULONG NrFreePages;
271 ULONG NrDirtyPages;
272 ULONG NrLockedPages;
273 ULONG PagingRequestsInLastMinute;
274 ULONG PagingRequestsInLastFiveMinutes;
275 ULONG PagingRequestsInLastFifteenMinutes;
276 } MM_STATS;
277
278 extern MM_STATS MmStats;
279
280 NTSTATUS MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
281 PMEMORY_AREA MArea,
282 PVOID Address);
283 NTSTATUS MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
284 PMEMORY_AREA MArea,
285 PVOID Address);
286 PVOID MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
287 NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
288 NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
289 VOID MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
290 ULONG MmGetFlagsPage(PVOID PhysicalAddress);
291 VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
292 SWAPENTRY SavedSwapEntry);
293 SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
294 VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
295 VOID MmLockPage(PVOID PhysicalPage);
296 VOID MmUnlockPage(PVOID PhysicalPage);
297
298 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
299
300 #endif