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