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