[NDK] Add IMAGE_FILE_MACHINE_NATIVE
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / miarm.h
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/miarm.h
5 * PURPOSE: ARM Memory Manager Header
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 #ifndef _M_AMD64
10
11 #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
12 #define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
13 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
14 #define MI_MAX_INIT_NONPAGED_POOL_SIZE (128 * _1MB)
15 #define MI_MAX_NONPAGED_POOL_SIZE (128 * _1MB)
16 #define MI_MAX_FREE_PAGE_LISTS 4
17
18 #define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
19
20 #define MI_SESSION_VIEW_SIZE (20 * _1MB)
21 #define MI_SESSION_POOL_SIZE (16 * _1MB)
22 #define MI_SESSION_IMAGE_SIZE (8 * _1MB)
23 #define MI_SESSION_WORKING_SET_SIZE (4 * _1MB)
24 #define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
25 MI_SESSION_POOL_SIZE + \
26 MI_SESSION_IMAGE_SIZE + \
27 MI_SESSION_WORKING_SET_SIZE)
28
29 #define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
30
31 #define MI_SYSTEM_CACHE_WS_START (PVOID)0xC0C00000
32 #define MI_PAGED_POOL_START (PVOID)0xE1000000
33 #define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
34 #define MI_DEBUG_MAPPING (PVOID)0xFFBFF000
35
36 #define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(NULL)
37
38 #define MI_MIN_SECONDARY_COLORS 8
39 #define MI_SECONDARY_COLORS 64
40 #define MI_MAX_SECONDARY_COLORS 1024
41
42 #define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
43 #define MI_ALLOCATION_FRAGMENT (64 * _1KB)
44 #define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
45
46 #define MM_HIGHEST_VAD_ADDRESS \
47 (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
48 #define MI_LOWEST_VAD_ADDRESS (PVOID)MM_LOWEST_USER_ADDRESS
49
50 #endif /* !_M_AMD64 */
51
52 /* Make the code cleaner with some definitions for size multiples */
53 #define _1KB (1024u)
54 #define _1MB (1024 * _1KB)
55 #define _1GB (1024 * _1MB)
56
57 /* Everyone loves 64K */
58 #define _64K (64 * _1KB)
59
60 /* Area mapped by a PDE */
61 #define PDE_MAPPED_VA (PTE_COUNT * PAGE_SIZE)
62
63 /* Size of a page table */
64 #define PT_SIZE (PTE_COUNT * sizeof(MMPTE))
65
66 /* Size of a page directory */
67 #define PD_SIZE (PDE_COUNT * sizeof(MMPDE))
68
69 /* Size of all page directories for a process */
70 #define SYSTEM_PD_SIZE (PD_COUNT * PD_SIZE)
71
72 /* Architecture specific count of PDEs in a directory, and count of PTEs in a PT */
73 #ifdef _M_IX86
74 #define PD_COUNT 1
75 #define PDE_COUNT 1024
76 #define PTE_COUNT 1024
77 C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
78 #elif _M_ARM
79 #define PD_COUNT 1
80 #define PDE_COUNT 4096
81 #define PTE_COUNT 256
82 #else
83 #define PD_COUNT PPE_PER_PAGE
84 #define PDE_COUNT PDE_PER_PAGE
85 #define PTE_COUNT PTE_PER_PAGE
86 #endif
87
88 //
89 // Protection Bits part of the internal memory manager Protection Mask
90 // Taken from http://www.reactos.org/wiki/Techwiki:Memory_management_in_the_Windows_XP_kernel
91 // and public assertions.
92 //
93 #define MM_ZERO_ACCESS 0
94 #define MM_READONLY 1
95 #define MM_EXECUTE 2
96 #define MM_EXECUTE_READ 3
97 #define MM_READWRITE 4
98 #define MM_WRITECOPY 5
99 #define MM_EXECUTE_READWRITE 6
100 #define MM_EXECUTE_WRITECOPY 7
101 #define MM_NOCACHE 8
102 #define MM_DECOMMIT 0x10
103 #define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE)
104 #define MM_INVALID_PROTECTION 0xFFFFFFFF
105
106 //
107 // Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits
108 // The Memory Manager's definition define the attributes that must be preserved
109 // and these PTE definitions describe the attributes in the hardware sense. This
110 // helps deal with hardware differences between the actual boolean expression of
111 // the argument.
112 //
113 // For example, in the logical attributes, we want to express read-only as a flag
114 // but on x86, it is writability that must be set. On the other hand, on x86, just
115 // like in the kernel, it is disabling the caches that requires a special flag,
116 // while on certain architectures such as ARM, it is enabling the cache which
117 // requires a flag.
118 //
119 #if defined(_M_IX86) || defined(_M_AMD64)
120 //
121 // Access Flags
122 //
123 #define PTE_READONLY 0 // Doesn't exist on x86
124 #define PTE_EXECUTE 0 // Not worrying about NX yet
125 #define PTE_EXECUTE_READ 0 // Not worrying about NX yet
126 #define PTE_READWRITE 0x2
127 #define PTE_WRITECOPY 0x200
128 #define PTE_EXECUTE_READWRITE 0x2 // Not worrying about NX yet
129 #define PTE_EXECUTE_WRITECOPY 0x200
130 #define PTE_PROTOTYPE 0x400
131 //
132 // Cache flags
133 //
134 #define PTE_ENABLE_CACHE 0
135 #define PTE_DISABLE_CACHE 0x10
136 #define PTE_WRITECOMBINED_CACHE 0x10
137 #elif defined(_M_ARM)
138 #define PTE_READONLY 0x200
139 #define PTE_EXECUTE 0 // Not worrying about NX yet
140 #define PTE_EXECUTE_READ 0 // Not worrying about NX yet
141 #define PTE_READWRITE 0 // Doesn't exist on ARM
142 #define PTE_WRITECOPY 0 // Doesn't exist on ARM
143 #define PTE_EXECUTE_READWRITE 0 // Not worrying about NX yet
144 #define PTE_EXECUTE_WRITECOPY 0 // Not worrying about NX yet
145 #define PTE_PROTOTYPE 0x400 // Using the Shared bit
146 //
147 // Cache flags
148 //
149 #define PTE_ENABLE_CACHE 0
150 #define PTE_DISABLE_CACHE 0x10
151 #define PTE_WRITECOMBINED_CACHE 0x10
152 #else
153 #error Define these please!
154 #endif
155
156 extern const ULONG MmProtectToPteMask[32];
157 extern const ULONG MmProtectToValue[32];
158
159 //
160 // Assertions for session images, addresses, and PTEs
161 //
162 #define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
163 (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
164
165 #define MI_IS_SESSION_ADDRESS(Address) \
166 (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
167
168 #define MI_IS_SESSION_PTE(Pte) \
169 ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
170
171 #define MI_IS_PAGE_TABLE_ADDRESS(Address) \
172 (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)PTE_TOP))
173
174 #define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address) \
175 (((Address) >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && ((Address) <= (PVOID)PTE_TOP))
176
177 #define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address) \
178 (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)MmHyperSpaceEnd))
179
180 //
181 // Corresponds to MMPTE_SOFTWARE.Protection
182 //
183 #ifdef _M_IX86
184 #define MM_PTE_SOFTWARE_PROTECTION_BITS 5
185 #elif _M_ARM
186 #define MM_PTE_SOFTWARE_PROTECTION_BITS 6
187 #elif _M_AMD64
188 #define MM_PTE_SOFTWARE_PROTECTION_BITS 5
189 #else
190 #error Define these please!
191 #endif
192
193 //
194 // Creates a software PTE with the given protection
195 //
196 #define MI_MAKE_SOFTWARE_PTE(p, x) ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))
197
198 //
199 // Marks a PTE as deleted
200 //
201 #define MI_SET_PFN_DELETED(x) ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1))
202 #define MI_IS_PFN_DELETED(x) ((ULONG_PTR)((x)->PteAddress) & 1)
203
204 //
205 // Special values for LoadedImports
206 //
207 #define MM_SYSLDR_NO_IMPORTS (PVOID)0xFFFFFFFE
208 #define MM_SYSLDR_BOOT_LOADED (PVOID)0xFFFFFFFF
209 #define MM_SYSLDR_SINGLE_ENTRY 0x1
210
211 #if defined(_M_IX86) || defined(_M_ARM)
212 //
213 // PFN List Sentinel
214 //
215 #define LIST_HEAD 0xFFFFFFFF
216
217 //
218 // Because GCC cannot automatically downcast 0xFFFFFFFF to lesser-width bits,
219 // we need a manual definition suited to the number of bits in the PteFrame.
220 // This is used as a LIST_HEAD for the colored list
221 //
222 #define COLORED_LIST_HEAD ((1 << 25) - 1) // 0x1FFFFFF
223 #elif defined(_M_AMD64)
224 #define LIST_HEAD 0xFFFFFFFFFFFFFFFFLL
225 #define COLORED_LIST_HEAD ((1 << 57) - 1) // 0x1FFFFFFFFFFFFFFLL
226 #else
227 #error Define these please!
228 #endif
229
230 //
231 // Special IRQL value (found in assertions)
232 //
233 #define MM_NOIRQL (KIRQL)0xFFFFFFFF
234
235 //
236 // Returns the color of a page
237 //
238 #define MI_GET_PAGE_COLOR(x) ((x) & MmSecondaryColorMask)
239 #define MI_GET_NEXT_COLOR(x) (MI_GET_PAGE_COLOR(++MmSystemPageColor))
240 #define MI_GET_NEXT_PROCESS_COLOR(x) (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
241
242 #ifndef _M_AMD64
243 //
244 // Decodes a Prototype PTE into the underlying PTE
245 //
246 #define MiProtoPteToPte(x) \
247 (PMMPTE)((ULONG_PTR)MmPagedPoolStart + \
248 (((x)->u.Proto.ProtoAddressHigh << 7) | (x)->u.Proto.ProtoAddressLow))
249 #endif
250
251 //
252 // Prototype PTEs that don't yet have a pagefile association
253 //
254 #define MI_PTE_LOOKUP_NEEDED 0xFFFFF
255
256 //
257 // System views are binned into 64K chunks
258 //
259 #define MI_SYSTEM_VIEW_BUCKET_SIZE _64K
260
261 //
262 // FIXFIX: These should go in ex.h after the pool merge
263 //
264 #ifdef _M_AMD64
265 #define POOL_BLOCK_SIZE 16
266 #else
267 #define POOL_BLOCK_SIZE 8
268 #endif
269 #define POOL_LISTS_PER_PAGE (PAGE_SIZE / POOL_BLOCK_SIZE)
270 #define BASE_POOL_TYPE_MASK 1
271 #define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE))
272
273 typedef struct _POOL_DESCRIPTOR
274 {
275 POOL_TYPE PoolType;
276 ULONG PoolIndex;
277 ULONG RunningAllocs;
278 ULONG RunningDeAllocs;
279 ULONG TotalPages;
280 ULONG TotalBigPages;
281 ULONG Threshold;
282 PVOID LockAddress;
283 PVOID PendingFrees;
284 LONG PendingFreeDepth;
285 SIZE_T TotalBytes;
286 SIZE_T Spare0;
287 LIST_ENTRY ListHeads[POOL_LISTS_PER_PAGE];
288 } POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
289
290 typedef struct _POOL_HEADER
291 {
292 union
293 {
294 struct
295 {
296 #ifdef _M_AMD64
297 ULONG PreviousSize:8;
298 ULONG PoolIndex:8;
299 ULONG BlockSize:8;
300 ULONG PoolType:8;
301 #else
302 USHORT PreviousSize:9;
303 USHORT PoolIndex:7;
304 USHORT BlockSize:9;
305 USHORT PoolType:7;
306 #endif
307 };
308 ULONG Ulong1;
309 };
310 #ifdef _M_AMD64
311 ULONG PoolTag;
312 #endif
313 union
314 {
315 #ifdef _M_AMD64
316 PEPROCESS ProcessBilled;
317 #else
318 ULONG PoolTag;
319 #endif
320 struct
321 {
322 USHORT AllocatorBackTraceIndex;
323 USHORT PoolTagHash;
324 };
325 };
326 } POOL_HEADER, *PPOOL_HEADER;
327
328 C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE);
329 C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY));
330
331 extern ULONG ExpNumberOfPagedPools;
332 extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
333 extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
334 extern PVOID PoolTrackTable;
335
336 //
337 // END FIXFIX
338 //
339
340 typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY
341 {
342 LIST_ENTRY Links;
343 UNICODE_STRING BaseName;
344 } MI_LARGE_PAGE_DRIVER_ENTRY, *PMI_LARGE_PAGE_DRIVER_ENTRY;
345
346 typedef enum _MMSYSTEM_PTE_POOL_TYPE
347 {
348 SystemPteSpace,
349 NonPagedPoolExpansion,
350 MaximumPtePoolTypes
351 } MMSYSTEM_PTE_POOL_TYPE;
352
353 typedef enum _MI_PFN_CACHE_ATTRIBUTE
354 {
355 MiNonCached,
356 MiCached,
357 MiWriteCombined,
358 MiNotMapped
359 } MI_PFN_CACHE_ATTRIBUTE, *PMI_PFN_CACHE_ATTRIBUTE;
360
361 typedef struct _PHYSICAL_MEMORY_RUN
362 {
363 ULONG BasePage;
364 ULONG PageCount;
365 } PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
366
367 typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
368 {
369 ULONG NumberOfRuns;
370 ULONG NumberOfPages;
371 PHYSICAL_MEMORY_RUN Run[1];
372 } PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
373
374 typedef struct _MMCOLOR_TABLES
375 {
376 PFN_NUMBER Flink;
377 PVOID Blink;
378 PFN_NUMBER Count;
379 } MMCOLOR_TABLES, *PMMCOLOR_TABLES;
380
381 typedef struct _MI_LARGE_PAGE_RANGES
382 {
383 PFN_NUMBER StartFrame;
384 PFN_NUMBER LastFrame;
385 } MI_LARGE_PAGE_RANGES, *PMI_LARGE_PAGE_RANGES;
386
387 typedef struct _MMVIEW
388 {
389 ULONG_PTR Entry;
390 PCONTROL_AREA ControlArea;
391 } MMVIEW, *PMMVIEW;
392
393 typedef struct _MMSESSION
394 {
395 KGUARDED_MUTEX SystemSpaceViewLock;
396 PKGUARDED_MUTEX SystemSpaceViewLockPointer;
397 PCHAR SystemSpaceViewStart;
398 PMMVIEW SystemSpaceViewTable;
399 ULONG SystemSpaceHashSize;
400 ULONG SystemSpaceHashEntries;
401 ULONG SystemSpaceHashKey;
402 ULONG BitmapFailures;
403 PRTL_BITMAP SystemSpaceBitMap;
404 } MMSESSION, *PMMSESSION;
405
406 extern MMPTE HyperTemplatePte;
407 extern MMPDE ValidKernelPde;
408 extern MMPTE ValidKernelPte;
409 extern MMPDE DemandZeroPde;
410 extern MMPTE DemandZeroPte;
411 extern MMPTE PrototypePte;
412 extern BOOLEAN MmLargeSystemCache;
413 extern BOOLEAN MmZeroPageFile;
414 extern BOOLEAN MmProtectFreedNonPagedPool;
415 extern BOOLEAN MmTrackLockedPages;
416 extern BOOLEAN MmTrackPtes;
417 extern BOOLEAN MmDynamicPfn;
418 extern BOOLEAN MmMirroring;
419 extern BOOLEAN MmMakeLowMemory;
420 extern BOOLEAN MmEnforceWriteProtection;
421 extern SIZE_T MmAllocationFragment;
422 extern ULONG MmConsumedPoolPercentage;
423 extern ULONG MmVerifyDriverBufferType;
424 extern ULONG MmVerifyDriverLevel;
425 extern WCHAR MmVerifyDriverBuffer[512];
426 extern WCHAR MmLargePageDriverBuffer[512];
427 extern LIST_ENTRY MiLargePageDriverList;
428 extern BOOLEAN MiLargePageAllDrivers;
429 extern ULONG MmVerifyDriverBufferLength;
430 extern ULONG MmLargePageDriverBufferLength;
431 extern SIZE_T MmSizeOfNonPagedPoolInBytes;
432 extern SIZE_T MmMaximumNonPagedPoolInBytes;
433 extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
434 extern PFN_NUMBER MmSizeOfPagedPoolInPages;
435 extern PVOID MmNonPagedSystemStart;
436 extern PVOID MmNonPagedPoolStart;
437 extern PVOID MmNonPagedPoolExpansionStart;
438 extern PVOID MmNonPagedPoolEnd;
439 extern SIZE_T MmSizeOfPagedPoolInBytes;
440 extern PVOID MmPagedPoolStart;
441 extern PVOID MmPagedPoolEnd;
442 extern PVOID MmSessionBase;
443 extern SIZE_T MmSessionSize;
444 extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
445 extern PMMPTE MiFirstReservedZeroingPte;
446 extern MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType];
447 extern PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
448 extern SIZE_T MmBootImageSize;
449 extern PMMPTE MmSystemPtesStart[MaximumPtePoolTypes];
450 extern PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes];
451 extern PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
452 extern MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
453 extern ULONG_PTR MxPfnAllocation;
454 extern MM_PAGED_POOL_INFO MmPagedPoolInfo;
455 extern RTL_BITMAP MiPfnBitMap;
456 extern KGUARDED_MUTEX MmPagedPoolMutex;
457 extern PVOID MmPagedPoolStart;
458 extern PVOID MmPagedPoolEnd;
459 extern PVOID MmNonPagedSystemStart;
460 extern PVOID MiSystemViewStart;
461 extern SIZE_T MmSystemViewSize;
462 extern PVOID MmSessionBase;
463 extern PVOID MiSessionSpaceEnd;
464 extern PMMPTE MiSessionImagePteStart;
465 extern PMMPTE MiSessionImagePteEnd;
466 extern PMMPTE MiSessionBasePte;
467 extern PMMPTE MiSessionLastPte;
468 extern SIZE_T MmSizeOfPagedPoolInBytes;
469 extern PMMPDE MmSystemPagePtes;
470 extern PVOID MmSystemCacheStart;
471 extern PVOID MmSystemCacheEnd;
472 extern MMSUPPORT MmSystemCacheWs;
473 extern SIZE_T MmAllocatedNonPagedPool;
474 extern ULONG_PTR MmSubsectionBase;
475 extern ULONG MmSpecialPoolTag;
476 extern PVOID MmHyperSpaceEnd;
477 extern PMMWSL MmSystemCacheWorkingSetList;
478 extern SIZE_T MmMinimumNonPagedPoolSize;
479 extern ULONG MmMinAdditionNonPagedPoolPerMb;
480 extern SIZE_T MmDefaultMaximumNonPagedPool;
481 extern ULONG MmMaxAdditionNonPagedPoolPerMb;
482 extern ULONG MmSecondaryColors;
483 extern ULONG MmSecondaryColorMask;
484 extern ULONG_PTR MmNumberOfSystemPtes;
485 extern ULONG MmMaximumNonPagedPoolPercent;
486 extern ULONG MmLargeStackSize;
487 extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
488 extern ULONG MmProductType;
489 extern MM_SYSTEMSIZE MmSystemSize;
490 extern PKEVENT MiLowMemoryEvent;
491 extern PKEVENT MiHighMemoryEvent;
492 extern PKEVENT MiLowPagedPoolEvent;
493 extern PKEVENT MiHighPagedPoolEvent;
494 extern PKEVENT MiLowNonPagedPoolEvent;
495 extern PKEVENT MiHighNonPagedPoolEvent;
496 extern PFN_NUMBER MmLowMemoryThreshold;
497 extern PFN_NUMBER MmHighMemoryThreshold;
498 extern PFN_NUMBER MiLowPagedPoolThreshold;
499 extern PFN_NUMBER MiHighPagedPoolThreshold;
500 extern PFN_NUMBER MiLowNonPagedPoolThreshold;
501 extern PFN_NUMBER MiHighNonPagedPoolThreshold;
502 extern PFN_NUMBER MmMinimumFreePages;
503 extern PFN_NUMBER MmPlentyFreePages;
504 extern PFN_NUMBER MiExpansionPoolPagesInitialCharge;
505 extern PFN_NUMBER MmResidentAvailablePages;
506 extern PFN_NUMBER MmResidentAvailableAtInit;
507 extern ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes];
508 extern PFN_NUMBER MmTotalSystemDriverPages;
509 extern PVOID MiSessionImageStart;
510 extern PVOID MiSessionImageEnd;
511 extern PMMPTE MiHighestUserPte;
512 extern PMMPDE MiHighestUserPde;
513 extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
514 extern PMMPTE MmSharedUserDataPte;
515 extern LIST_ENTRY MmProcessList;
516 extern BOOLEAN MmZeroingPageThreadActive;
517 extern KEVENT MmZeroingPageEvent;
518 extern ULONG MmSystemPageColor;
519 extern ULONG MmProcessColorSeed;
520 extern PMMWSL MmWorkingSetList;
521
522 //
523 // Figures out the hardware bits for a PTE
524 //
525 ULONG
526 FORCEINLINE
527 MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
528 {
529 MMPTE TempPte;
530
531 /* Start fresh */
532 TempPte.u.Long = 0;
533
534 /* Make it valid and accessed */
535 TempPte.u.Hard.Valid = TRUE;
536 MI_MAKE_ACCESSED_PAGE(&TempPte);
537
538 /* Is this for user-mode? */
539 if ((PointerPte <= (PVOID)MiHighestUserPte) ||
540 ((PointerPte >= (PVOID)MiAddressToPde(NULL)) &&
541 (PointerPte <= (PVOID)MiHighestUserPde)))
542 {
543 /* Set the owner bit */
544 MI_MAKE_OWNER_PAGE(&TempPte);
545 }
546
547 /* FIXME: We should also set the global bit */
548
549 /* Return the protection */
550 return TempPte.u.Long;
551 }
552
553 //
554 // Creates a valid kernel PTE with the given protection
555 //
556 FORCEINLINE
557 VOID
558 MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte,
559 IN PMMPTE MappingPte,
560 IN ULONG ProtectionMask,
561 IN PFN_NUMBER PageFrameNumber)
562 {
563 /* Only valid for kernel, non-session PTEs */
564 ASSERT(MappingPte > MiHighestUserPte);
565 ASSERT(!MI_IS_SESSION_PTE(MappingPte));
566 ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
567
568 /* Start fresh */
569 *NewPte = ValidKernelPte;
570
571 /* Set the protection and page */
572 NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
573 NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
574 }
575
576 //
577 // Creates a valid PTE with the given protection
578 //
579 FORCEINLINE
580 VOID
581 MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte,
582 IN PMMPTE MappingPte,
583 IN ULONG ProtectionMask,
584 IN PFN_NUMBER PageFrameNumber)
585 {
586 /* Set the protection and page */
587 NewPte->u.Long = MiDetermineUserGlobalPteMask(MappingPte);
588 NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
589 NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
590 }
591
592 //
593 // Creates a valid user PTE with the given protection
594 //
595 FORCEINLINE
596 VOID
597 MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte,
598 IN PMMPTE MappingPte,
599 IN ULONG ProtectionMask,
600 IN PFN_NUMBER PageFrameNumber)
601 {
602 /* Only valid for kernel, non-session PTEs */
603 ASSERT(MappingPte <= MiHighestUserPte);
604
605 /* Start fresh */
606 *NewPte = ValidKernelPte;
607
608 /* Set the protection and page */
609 NewPte->u.Hard.Owner = TRUE;
610 NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
611 NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
612 }
613
614 #ifndef _M_AMD64
615 //
616 // Builds a Prototype PTE for the address of the PTE
617 //
618 FORCEINLINE
619 VOID
620 MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte,
621 IN PMMPTE PointerPte)
622 {
623 ULONG_PTR Offset;
624
625 /* Mark this as a prototype */
626 NewPte->u.Long = 0;
627 NewPte->u.Proto.Prototype = 1;
628
629 /*
630 * Prototype PTEs are only valid in paged pool by design, this little trick
631 * lets us only use 28 bits for the adress of the PTE
632 */
633 Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
634
635 /* 7 bits go in the "low", and the other 21 bits go in the "high" */
636 NewPte->u.Proto.ProtoAddressLow = Offset & 0x7F;
637 NewPte->u.Proto.ProtoAddressHigh = (Offset & 0xFFFFFF80) >> 7;
638 ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
639 }
640 #endif
641
642 //
643 // Returns if the page is physically resident (ie: a large page)
644 // FIXFIX: CISC/x86 only?
645 //
646 FORCEINLINE
647 BOOLEAN
648 MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
649 {
650 PMMPDE PointerPde;
651
652 /* Large pages are never paged out, always physically resident */
653 PointerPde = MiAddressToPde(Address);
654 return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
655 }
656
657 //
658 // Writes a valid PTE
659 //
660 VOID
661 FORCEINLINE
662 MI_WRITE_VALID_PTE(IN PMMPTE PointerPte,
663 IN MMPTE TempPte)
664 {
665 /* Write the valid PTE */
666 ASSERT(PointerPte->u.Hard.Valid == 0);
667 ASSERT(TempPte.u.Hard.Valid == 1);
668 *PointerPte = TempPte;
669 }
670
671 //
672 // Writes an invalid PTE
673 //
674 VOID
675 FORCEINLINE
676 MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte,
677 IN MMPTE InvalidPte)
678 {
679 /* Write the invalid PTE */
680 ASSERT(InvalidPte.u.Hard.Valid == 0);
681 *PointerPte = InvalidPte;
682 }
683
684 //
685 // Writes a valid PDE
686 //
687 VOID
688 FORCEINLINE
689 MI_WRITE_VALID_PDE(IN PMMPDE PointerPde,
690 IN MMPDE TempPde)
691 {
692 /* Write the valid PDE */
693 ASSERT(PointerPde->u.Hard.Valid == 0);
694 ASSERT(TempPde.u.Hard.Valid == 1);
695 *PointerPde = TempPde;
696 }
697
698 //
699 // Writes an invalid PDE
700 //
701 VOID
702 FORCEINLINE
703 MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde,
704 IN MMPDE InvalidPde)
705 {
706 /* Write the invalid PDE */
707 ASSERT(InvalidPde.u.Hard.Valid == 0);
708 *PointerPde = InvalidPde;
709 }
710
711 //
712 // Checks if the thread already owns a working set
713 //
714 FORCEINLINE
715 BOOLEAN
716 MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread)
717 {
718 /* If any of these are held, return TRUE */
719 return ((Thread->OwnsProcessWorkingSetExclusive) ||
720 (Thread->OwnsProcessWorkingSetShared) ||
721 (Thread->OwnsSystemWorkingSetExclusive) ||
722 (Thread->OwnsSystemWorkingSetShared) ||
723 (Thread->OwnsSessionWorkingSetExclusive) ||
724 (Thread->OwnsSessionWorkingSetShared));
725 }
726
727 //
728 // Checks if the process owns the working set lock
729 //
730 FORCEINLINE
731 BOOLEAN
732 MI_WS_OWNER(IN PEPROCESS Process)
733 {
734 /* Check if this process is the owner, and that the thread owns the WS */
735 return ((KeGetCurrentThread()->ApcState.Process == &Process->Pcb) &&
736 ((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) ||
737 (PsGetCurrentThread()->OwnsProcessWorkingSetShared)));
738 }
739
740 //
741 // Locks the working set for the given process
742 //
743 FORCEINLINE
744 VOID
745 MiLockProcessWorkingSet(IN PEPROCESS Process,
746 IN PETHREAD Thread)
747 {
748 /* Shouldn't already be owning the process working set */
749 ASSERT(Thread->OwnsProcessWorkingSetShared == FALSE);
750 ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE);
751
752 /* Block APCs, make sure that still nothing is already held */
753 KeEnterGuardedRegion();
754 ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
755
756 /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */
757
758 /* FIXME: This also can't be checked because Vm is used by MAREAs) */
759 //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0);
760
761 /* Okay, now we can own it exclusively */
762 ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE);
763 Thread->OwnsProcessWorkingSetExclusive = TRUE;
764 }
765
766 //
767 // Unlocks the working set for the given process
768 //
769 FORCEINLINE
770 VOID
771 MiUnlockProcessWorkingSet(IN PEPROCESS Process,
772 IN PETHREAD Thread)
773 {
774 /* Make sure this process really is owner, and it was a safe acquisition */
775 ASSERT(MI_WS_OWNER(Process));
776 /* This can't be checked because Vm is used by MAREAs) */
777 //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0);
778
779 /* The thread doesn't own it anymore */
780 ASSERT(Thread->OwnsProcessWorkingSetExclusive == TRUE);
781 Thread->OwnsProcessWorkingSetExclusive = FALSE;
782
783 /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
784
785 /* Unblock APCs */
786 KeLeaveGuardedRegion();
787 }
788
789 //
790 // Locks the working set
791 //
792 FORCEINLINE
793 VOID
794 MiLockWorkingSet(IN PETHREAD Thread,
795 IN PMMSUPPORT WorkingSet)
796 {
797 /* Block APCs */
798 KeEnterGuardedRegion();
799
800 /* Working set should be in global memory */
801 ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
802
803 /* Thread shouldn't already be owning something */
804 ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
805
806 /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */
807
808 /* Which working set is this? */
809 if (WorkingSet == &MmSystemCacheWs)
810 {
811 /* Own the system working set */
812 ASSERT((Thread->OwnsSystemWorkingSetExclusive == FALSE) &&
813 (Thread->OwnsSystemWorkingSetShared == FALSE));
814 Thread->OwnsSystemWorkingSetExclusive = TRUE;
815 }
816 else if (WorkingSet->Flags.SessionSpace)
817 {
818 /* We don't implement this yet */
819 UNIMPLEMENTED;
820 while (TRUE);
821 }
822 else
823 {
824 /* Own the process working set */
825 ASSERT((Thread->OwnsProcessWorkingSetExclusive == FALSE) &&
826 (Thread->OwnsProcessWorkingSetShared == FALSE));
827 Thread->OwnsProcessWorkingSetExclusive = TRUE;
828 }
829 }
830
831 //
832 // Unlocks the working set
833 //
834 FORCEINLINE
835 VOID
836 MiUnlockWorkingSet(IN PETHREAD Thread,
837 IN PMMSUPPORT WorkingSet)
838 {
839 /* Working set should be in global memory */
840 ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
841
842 /* Which working set is this? */
843 if (WorkingSet == &MmSystemCacheWs)
844 {
845 /* Release the system working set */
846 ASSERT((Thread->OwnsSystemWorkingSetExclusive == TRUE) ||
847 (Thread->OwnsSystemWorkingSetShared == TRUE));
848 Thread->OwnsSystemWorkingSetExclusive = FALSE;
849 }
850 else if (WorkingSet->Flags.SessionSpace)
851 {
852 /* We don't implement this yet */
853 UNIMPLEMENTED;
854 while (TRUE);
855 }
856 else
857 {
858 /* Release the process working set */
859 ASSERT((Thread->OwnsProcessWorkingSetExclusive) ||
860 (Thread->OwnsProcessWorkingSetShared));
861 Thread->OwnsProcessWorkingSetExclusive = FALSE;
862 }
863
864 /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
865
866 /* Unblock APCs */
867 KeLeaveGuardedRegion();
868 }
869
870 //
871 // Returns the ProtoPTE inside a VAD for the given VPN
872 //
873 FORCEINLINE
874 PMMPTE
875 MI_GET_PROTOTYPE_PTE_FOR_VPN(IN PMMVAD Vad,
876 IN ULONG_PTR Vpn)
877 {
878 PMMPTE ProtoPte;
879
880 /* Find the offset within the VAD's prototype PTEs */
881 ProtoPte = Vad->FirstPrototypePte + (Vpn - Vad->StartingVpn);
882 ASSERT(ProtoPte <= Vad->LastContiguousPte);
883 return ProtoPte;
884 }
885
886 //
887 // Returns the PFN Database entry for the given page number
888 // Warning: This is not necessarily a valid PFN database entry!
889 //
890 FORCEINLINE
891 PMMPFN
892 MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
893 {
894 /* Get the entry */
895 return &MmPfnDatabase[Pfn];
896 };
897
898 BOOLEAN
899 NTAPI
900 MmArmInitSystem(
901 IN ULONG Phase,
902 IN PLOADER_PARAMETER_BLOCK LoaderBlock
903 );
904
905 NTSTATUS
906 NTAPI
907 MiInitMachineDependent(
908 IN PLOADER_PARAMETER_BLOCK LoaderBlock
909 );
910
911 VOID
912 NTAPI
913 MiComputeColorInformation(
914 VOID
915 );
916
917 VOID
918 NTAPI
919 MiMapPfnDatabase(
920 IN PLOADER_PARAMETER_BLOCK LoaderBlock
921 );
922
923 VOID
924 NTAPI
925 MiInitializeColorTables(
926 VOID
927 );
928
929 VOID
930 NTAPI
931 MiInitializePfnDatabase(
932 IN PLOADER_PARAMETER_BLOCK LoaderBlock
933 );
934
935 BOOLEAN
936 NTAPI
937 MiInitializeMemoryEvents(
938 VOID
939 );
940
941 PFN_NUMBER
942 NTAPI
943 MxGetNextPage(
944 IN PFN_NUMBER PageCount
945 );
946
947 PPHYSICAL_MEMORY_DESCRIPTOR
948 NTAPI
949 MmInitializeMemoryLimits(
950 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
951 IN PBOOLEAN IncludeType
952 );
953
954 PFN_NUMBER
955 NTAPI
956 MiPagesInLoaderBlock(
957 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
958 IN PBOOLEAN IncludeType
959 );
960
961 VOID
962 FASTCALL
963 MiSyncARM3WithROS(
964 IN PVOID AddressStart,
965 IN PVOID AddressEnd
966 );
967
968 NTSTATUS
969 NTAPI
970 MmArmAccessFault(
971 IN BOOLEAN StoreInstruction,
972 IN PVOID Address,
973 IN KPROCESSOR_MODE Mode,
974 IN PVOID TrapInformation
975 );
976
977 NTSTATUS
978 FASTCALL
979 MiCheckPdeForPagedPool(
980 IN PVOID Address
981 );
982
983 VOID
984 NTAPI
985 MiInitializeNonPagedPool(
986 VOID
987 );
988
989 VOID
990 NTAPI
991 MiInitializeNonPagedPoolThresholds(
992 VOID
993 );
994
995 VOID
996 NTAPI
997 MiInitializePoolEvents(
998 VOID
999 );
1000
1001 VOID //
1002 NTAPI //
1003 InitializePool( //
1004 IN POOL_TYPE PoolType,// FIXFIX: This should go in ex.h after the pool merge
1005 IN ULONG Threshold //
1006 ); //
1007
1008 VOID
1009 NTAPI
1010 MiInitializeSystemPtes(
1011 IN PMMPTE StartingPte,
1012 IN ULONG NumberOfPtes,
1013 IN MMSYSTEM_PTE_POOL_TYPE PoolType
1014 );
1015
1016 PMMPTE
1017 NTAPI
1018 MiReserveSystemPtes(
1019 IN ULONG NumberOfPtes,
1020 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
1021 );
1022
1023 VOID
1024 NTAPI
1025 MiReleaseSystemPtes(
1026 IN PMMPTE StartingPte,
1027 IN ULONG NumberOfPtes,
1028 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
1029 );
1030
1031
1032 PFN_NUMBER
1033 NTAPI
1034 MiFindContiguousPages(
1035 IN PFN_NUMBER LowestPfn,
1036 IN PFN_NUMBER HighestPfn,
1037 IN PFN_NUMBER BoundaryPfn,
1038 IN PFN_NUMBER SizeInPages,
1039 IN MEMORY_CACHING_TYPE CacheType
1040 );
1041
1042 PVOID
1043 NTAPI
1044 MiCheckForContiguousMemory(
1045 IN PVOID BaseAddress,
1046 IN PFN_NUMBER BaseAddressPages,
1047 IN PFN_NUMBER SizeInPages,
1048 IN PFN_NUMBER LowestPfn,
1049 IN PFN_NUMBER HighestPfn,
1050 IN PFN_NUMBER BoundaryPfn,
1051 IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute
1052 );
1053
1054 PMDL
1055 NTAPI
1056 MiAllocatePagesForMdl(
1057 IN PHYSICAL_ADDRESS LowAddress,
1058 IN PHYSICAL_ADDRESS HighAddress,
1059 IN PHYSICAL_ADDRESS SkipBytes,
1060 IN SIZE_T TotalBytes,
1061 IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute,
1062 IN ULONG Flags
1063 );
1064
1065 PVOID
1066 NTAPI
1067 MiMapLockedPagesInUserSpace(
1068 IN PMDL Mdl,
1069 IN PVOID BaseVa,
1070 IN MEMORY_CACHING_TYPE CacheType,
1071 IN PVOID BaseAddress
1072 );
1073
1074 VOID
1075 NTAPI
1076 MiUnmapLockedPagesInUserSpace(
1077 IN PVOID BaseAddress,
1078 IN PMDL Mdl
1079 );
1080
1081 VOID
1082 NTAPI
1083 MiInsertPageInList(
1084 IN PMMPFNLIST ListHead,
1085 IN PFN_NUMBER PageFrameIndex
1086 );
1087
1088 VOID
1089 NTAPI
1090 MiUnlinkFreeOrZeroedPage(
1091 IN PMMPFN Entry
1092 );
1093
1094 PFN_NUMBER
1095 NTAPI
1096 MiAllocatePfn(
1097 IN PMMPTE PointerPte,
1098 IN ULONG Protection
1099 );
1100
1101 VOID
1102 NTAPI
1103 MiInitializePfn(
1104 IN PFN_NUMBER PageFrameIndex,
1105 IN PMMPTE PointerPte,
1106 IN BOOLEAN Modified
1107 );
1108
1109 VOID
1110 NTAPI
1111 MiInitializePfnForOtherProcess(
1112 IN PFN_NUMBER PageFrameIndex,
1113 IN PMMPTE PointerPte,
1114 IN PFN_NUMBER PteFrame
1115 );
1116
1117 VOID
1118 NTAPI
1119 MiDecrementShareCount(
1120 IN PMMPFN Pfn1,
1121 IN PFN_NUMBER PageFrameIndex
1122 );
1123
1124 VOID
1125 NTAPI
1126 MiDecrementReferenceCount(
1127 IN PMMPFN Pfn1,
1128 IN PFN_NUMBER PageFrameIndex
1129 );
1130
1131 PFN_NUMBER
1132 NTAPI
1133 MiRemoveAnyPage(
1134 IN ULONG Color
1135 );
1136
1137 PFN_NUMBER
1138 NTAPI
1139 MiRemoveZeroPage(
1140 IN ULONG Color
1141 );
1142
1143 VOID
1144 NTAPI
1145 MiZeroPhysicalPage(
1146 IN PFN_NUMBER PageFrameIndex
1147 );
1148
1149 VOID
1150 NTAPI
1151 MiInsertPageInFreeList(
1152 IN PFN_NUMBER PageFrameIndex
1153 );
1154
1155 PFN_NUMBER
1156 NTAPI
1157 MiDeleteSystemPageableVm(
1158 IN PMMPTE PointerPte,
1159 IN PFN_NUMBER PageCount,
1160 IN ULONG Flags,
1161 OUT PPFN_NUMBER ValidPages
1162 );
1163
1164 PLDR_DATA_TABLE_ENTRY
1165 NTAPI
1166 MiLookupDataTableEntry(
1167 IN PVOID Address
1168 );
1169
1170 VOID
1171 NTAPI
1172 MiInitializeDriverLargePageList(
1173 VOID
1174 );
1175
1176 VOID
1177 NTAPI
1178 MiInitializeLargePageSupport(
1179 VOID
1180 );
1181
1182 VOID
1183 NTAPI
1184 MiSyncCachedRanges(
1185 VOID
1186 );
1187
1188 BOOLEAN
1189 NTAPI
1190 MiIsPfnInUse(
1191 IN PMMPFN Pfn1
1192 );
1193
1194 PMMVAD
1195 NTAPI
1196 MiLocateAddress(
1197 IN PVOID VirtualAddress
1198 );
1199
1200 PMMADDRESS_NODE
1201 NTAPI
1202 MiCheckForConflictingNode(
1203 IN ULONG_PTR StartVpn,
1204 IN ULONG_PTR EndVpn,
1205 IN PMM_AVL_TABLE Table
1206 );
1207
1208 TABLE_SEARCH_RESULT
1209 NTAPI
1210 MiFindEmptyAddressRangeDownTree(
1211 IN SIZE_T Length,
1212 IN ULONG_PTR BoundaryAddress,
1213 IN ULONG_PTR Alignment,
1214 IN PMM_AVL_TABLE Table,
1215 OUT PULONG_PTR Base,
1216 OUT PMMADDRESS_NODE *Parent
1217 );
1218
1219 NTSTATUS
1220 NTAPI
1221 MiFindEmptyAddressRangeInTree(
1222 IN SIZE_T Length,
1223 IN ULONG_PTR Alignment,
1224 IN PMM_AVL_TABLE Table,
1225 OUT PMMADDRESS_NODE *PreviousVad,
1226 OUT PULONG_PTR Base
1227 );
1228
1229 VOID
1230 NTAPI
1231 MiInsertVad(
1232 IN PMMVAD Vad,
1233 IN PEPROCESS Process
1234 );
1235
1236 VOID
1237 NTAPI
1238 MiInsertNode(
1239 IN PMM_AVL_TABLE Table,
1240 IN PMMADDRESS_NODE NewNode,
1241 PMMADDRESS_NODE Parent,
1242 TABLE_SEARCH_RESULT Result
1243 );
1244
1245 VOID
1246 NTAPI
1247 MiRemoveNode(
1248 IN PMMADDRESS_NODE Node,
1249 IN PMM_AVL_TABLE Table
1250 );
1251
1252 PMMADDRESS_NODE
1253 NTAPI
1254 MiGetPreviousNode(
1255 IN PMMADDRESS_NODE Node
1256 );
1257
1258 PMMADDRESS_NODE
1259 NTAPI
1260 MiGetNextNode(
1261 IN PMMADDRESS_NODE Node
1262 );
1263
1264 BOOLEAN
1265 NTAPI
1266 MiInitializeSystemSpaceMap(
1267 IN PVOID InputSession OPTIONAL
1268 );
1269
1270 ULONG
1271 NTAPI
1272 MiMakeProtectionMask(
1273 IN ULONG Protect
1274 );
1275
1276 VOID
1277 NTAPI
1278 MiDeleteVirtualAddresses(
1279 IN ULONG_PTR Va,
1280 IN ULONG_PTR EndingAddress,
1281 IN PMMVAD Vad
1282 );
1283
1284 ULONG
1285 NTAPI
1286 MiMakeSystemAddressValid(
1287 IN PVOID PageTableVirtualAddress,
1288 IN PEPROCESS CurrentProcess
1289 );
1290
1291 ULONG
1292 NTAPI
1293 MiMakeSystemAddressValidPfn(
1294 IN PVOID VirtualAddress,
1295 IN KIRQL OldIrql
1296 );
1297
1298 VOID
1299 NTAPI
1300 MiRemoveMappedView(
1301 IN PEPROCESS CurrentProcess,
1302 IN PMMVAD Vad
1303 );
1304
1305 PSUBSECTION
1306 NTAPI
1307 MiLocateSubsection(
1308 IN PMMVAD Vad,
1309 IN ULONG_PTR Vpn
1310 );
1311
1312 //
1313 // MiRemoveZeroPage will use inline code to zero out the page manually if only
1314 // free pages are available. In some scenarios, we don't/can't run that piece of
1315 // code and would rather only have a real zero page. If we can't have a zero page,
1316 // then we'd like to have our own code to grab a free page and zero it out, by
1317 // using MiRemoveAnyPage. This macro implements this.
1318 //
1319 PFN_NUMBER
1320 FORCEINLINE
1321 MiRemoveZeroPageSafe(IN ULONG Color)
1322 {
1323 if (MmFreePagesByColor[ZeroedPageList][Color].Flink != LIST_HEAD) return MiRemoveZeroPage(Color);
1324 return 0;
1325 }
1326
1327 //
1328 // New ARM3<->RosMM PAGE Architecture
1329 //
1330 #define MI_GET_ROS_DATA(x) ((PMMROSPFN)(x->RosMmData))
1331 #define MI_IS_ROS_PFN(x) (((x)->u4.AweAllocation == TRUE) && (MI_GET_ROS_DATA(x) != NULL))
1332 #define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
1333 typedef struct _MMROSPFN
1334 {
1335 PMM_RMAP_ENTRY RmapListHead;
1336 SWAPENTRY SwapEntry;
1337 } MMROSPFN, *PMMROSPFN;
1338
1339 #define RosMmData AweReferenceCount
1340
1341 /* EOF */