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