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