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