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