00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 Copyright (c) 1993 IBM Corporation 00005 00006 Module Name: 00007 00008 mippc.h 00009 00010 Abstract: 00011 00012 This module contains the private data structures and procedure 00013 prototypes for the hardware dependent portion of the 00014 memory management system. 00015 00016 It is specifically tailored for PowerPC. 00017 00018 Author: 00019 00020 Lou Perazzoli (loup) 9-Jan-1991 00021 00022 Modified for PowerPC by Mark Mergen ([email protected]) 6-Oct-1993 00023 00024 Revision History: 00025 00026 --*/ 00027 00028 /*++ 00029 00030 Virtual Memory Layout for PowerPC is: 00031 00032 +------------------------------------+ 00033 00000000 | | 00034 | | 00035 | | 00036 | User Mode Addresses | 00037 | | 00038 | All pages within this range | 00039 | are potentially accessable while | 00040 | the CPU is in USER mode. | 00041 | | 00042 | | 00043 +------------------------------------+ 00044 7fff0000 | 64k No Access Area | 00045 +------------------------------------+ 00046 80000000 | | KSEG0 00047 | OsLoader loads critical parts | 00048 | of boot code and data in | 00049 | this region. Mapped by BAT0. | 00050 | Kernel mode access only. | 00051 | | 00052 +------------------------------------+ 00053 8xxx0000 | | KSEG1 KSEG2 00054 | OsLoader loads remaining boot | 00055 | code and data here. Mapped | 00056 | by segment register 8. | 00057 | Kernel mode access only. | 00058 | | 00059 +------------------------------------+ 00060 8yyy0000 | | 00061 | | 00062 | Unused NO ACCESS | 00063 | | 00064 | | 00065 +------------------------------------+ 00066 90000000 | System Cache Working Set | 00067 90400000 | System Cache | 00068 | | 00069 | | 00070 | | 00071 AE000000 | Kernel mode access only. | 00072 +------------------------------------+ 00073 C0000000 | Page Table Pages mapped through | 00074 | this 4mb region | 00075 | Kernel mode access only. | 00076 | | 00077 +------------------------------------+ 00078 C0400000 | HyperSpace - working set lists | 00079 | and per process memory mangement | 00080 | structures mapped in this 4mb | 00081 | region. | 00082 | Kernel mode access only. | 00083 +------------------------------------+ 00084 C0800000 | NO ACCESS AREA | 00085 | | 00086 +------------------------------------+ 00087 D0000000 | System mapped views | 00088 | Kernel mode access only. | 00089 | | 00090 +------------------------------------+ 00091 D3000000 | Start of paged system area | 00092 | Kernel mode access only. | 00093 | | 00094 | | 00095 | | 00096 +------------------------------------+ 00097 E0000000 | | 00098 | Kernel mode access only. | 00099 | | 00100 | | 00101 EFBFFFFF | NonPaged System area | 00102 +------------------------------------+ 00103 EFC00000 | Last 4mb reserved for HAL usage | 00104 +------------------------------------+ 00105 F0000000 | Unused, No access. | 00106 | | 00107 FFFFD000 | Per Processor PCR | 00108 FFFFE000 | Shared PCR2 | 00109 FFFFF000 | Debugger Page for physical memory | 00110 +------------------------------------+ 00111 00112 Segment Register usage 00113 00114 0 - 7 User mode addresses, switched at Process Switch time 00115 8 Constant, shared amongst processors and processes. 00116 No change on switch to user mode but always invalid for 00117 user mode. Very low part of this range is KSEG0, mapped 00118 by a BAT register. 00119 9 - A Constant, Shared amongst processors and processes, 00120 invalidated while in user mode. 00121 C Per process kernel data. invalidated while in user mode. 00122 D Constant, Shared amongst processors and processes, 00123 invalidated while in user mode. 00124 E Constant, shared amongst processors and processes. 00125 No change on switch to user mode but always invalid for 00126 user mode. 00127 F Per processor. Kernel mode access only. 00128 00129 --*/ 00130 00131 // 00132 // PAGE_SIZE for PowerPC is 4k, virtual page is 20 bits with a PAGE_SHIFT 00133 // byte offset. 00134 // 00135 00136 #define MM_VIRTUAL_PAGE_SHIFT 20 00137 00138 // 00139 // Address space layout definitions. 00140 // 00141 00142 //#define PDE_BASE ((ULONG)0xC0300000) 00143 00144 //#define PTE_BASE ((ULONG)0xC0000000) 00145 00146 #define MM_SYSTEM_SPACE_START (0xD0000000) 00147 00148 // 00149 // N.B. This should ONLY be used for copying PDEs. 00150 // Segment 15 is only used for PCR pages, 00151 // hardwired PDE for the debuggers, and 00152 // crash dump. 00153 // 00154 00155 #define MM_SYSTEM_SPACE_END (0xFFFFFFFF) 00156 00157 #define MM_HAL_RESERVED (0xFFC00000) 00158 00159 #define PDE_TOP 0xC03FFFFF 00160 00161 #define HYPER_SPACE ((PVOID)0xC0400000) 00162 00163 #define HYPER_SPACE_END 0xC07fffff 00164 00165 // 00166 // Define the start and maximum size for the system cache. 00167 // Maximum size 476MB. 00168 // 00169 00170 #define MM_SYSTEM_CACHE_AND_POOL_DISJOINT 1 00171 00172 #define MM_SYSTEM_CACHE_WORKING_SET (0x90000000) 00173 00174 #define MM_SYSTEM_CACHE_START (0x90400000) 00175 00176 #define MM_SYSTEM_CACHE_END (0xAE000000) 00177 00178 #define MM_MAXIMUM_SYSTEM_CACHE_SIZE \ 00179 (((ULONG)MM_SYSTEM_CACHE_END - (ULONG)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT) 00180 00181 // 00182 // Tell MM that boot code and data is pageable. 00183 // 00184 00185 #define MM_BOOT_CODE_PAGEABLE 1 00186 00187 #define MM_BOOT_CODE_START (0x80000000) 00188 #define MM_BOOT_CODE_END (0x90000000) 00189 00190 // 00191 // Define MM_SYSTEM_CACHE_AND_POOL_DISJOINT so that MmCreateProcessAddressSpace 00192 // knows that it has to do two RtlCopyMemorys to copy the PDEs for the cache 00193 // and the rest of system space. 00194 // 00195 00196 #define MM_SYSTEM_CACHE_AND_POOL_DISJOINT 1 00197 00198 00199 // 00200 // Define area for mapping views into system space. 00201 // 00202 00203 #define MM_SYSTEM_VIEW_START (0xD0000000) 00204 00205 #define MM_SYSTEM_VIEW_SIZE (48*1024*1024) 00206 00207 #define MM_PAGED_POOL_START ((PVOID)(0xD3000000)) 00208 00209 #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(0xE0000000)) 00210 00211 #define MmProtopte_Base ((ULONG)0xD3000000) 00212 00213 #define MM_NONPAGED_POOL_END ((PVOID)(0xEFC00000)) 00214 00215 #define NON_PAGED_SYSTEM_END ((ULONG)0xEFFFFFF0) //quadword aligned. 00216 00217 // 00218 // Define absolute minumum and maximum count for system ptes. 00219 // 00220 00221 #define MM_MINIMUM_SYSTEM_PTES 9000 00222 00223 #define MM_MAXIMUM_SYSTEM_PTES 35000 00224 00225 #define MM_DEFAULT_SYSTEM_PTES 15000 00226 00227 // 00228 // Pool limits 00229 // 00230 00231 // 00232 // The maximim amount of nonpaged pool that can be initially created. 00233 // 00234 00235 #define MM_MAX_INITIAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) 00236 00237 // 00238 // The total amount of nonpaged pool (initial pool + expansion + system PTEs). 00239 // 00240 00241 #define MM_MAX_ADDITIONAL_NONPAGED_POOL ((ULONG)(192*1024*1024)) 00242 00243 // 00244 // The maximum amount of paged pool that can be created. 00245 // 00246 00247 #define MM_MAX_PAGED_POOL ((ULONG)(176*1024*1024)) 00248 00249 #define MM_MAX_TOTAL_POOL (((ULONG)MM_NONPAGED_POOL_END) - ((ULONG)(MM_PAGED_POOL_START))) 00250 00251 00252 // 00253 // Structure layout defintions. 00254 // 00255 00256 #define PAGE_DIRECTORY_MASK ((ULONG)0x003FFFFF) 00257 00258 #define MM_VA_MAPPED_BY_PDE (0x400000) 00259 00260 // N.B. this is probably a real address, for what purpose? 00261 #define LOWEST_IO_ADDRESS (0x80000000) 00262 00263 #define PTE_SHIFT (2) 00264 00265 // 00266 // The number of bits in a physical address. 00267 // 00268 00269 #define PHYSICAL_ADDRESS_BITS (32) 00270 00271 #define MM_PROTO_PTE_ALIGNMENT ((ULONG)MM_MAXIMUM_NUMBER_OF_COLORS * (ULONG)PAGE_SIZE) 00272 00273 // 00274 // Maximum number of paging files. 00275 // 00276 00277 #define MAX_PAGE_FILES 16 00278 00279 // 00280 // Hyper space definitions. 00281 // 00282 00283 #define FIRST_MAPPING_PTE ((ULONG)0xC0400000) 00284 00285 #define NUMBER_OF_MAPPING_PTES 255 00286 00287 #define LAST_MAPPING_PTE \ 00288 ((ULONG)((ULONG)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE))) 00289 00290 #define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG)LAST_MAPPING_PTE + PAGE_SIZE)) 00291 00292 #define ZEROING_PAGE_PTE ((PMMPTE)((ULONG)IMAGE_MAPPING_PTE + PAGE_SIZE)) 00293 00294 #define WORKING_SET_LIST ((PVOID)((ULONG)ZEROING_PAGE_PTE + PAGE_SIZE)) 00295 00296 #define MM_MAXIMUM_WORKING_SET \ 00297 ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb 00298 00299 #define MM_WORKING_SET_END ((ULONG)0xC07FF000) 00300 00301 // 00302 // Define masks for fields within the PTE. 00303 // 00304 00305 #define MM_PTE_PROTOTYPE_MASK 0x1 00306 #define MM_PTE_VALID_MASK 0x4 00307 #define MM_PTE_CACHE_DISABLE_MASK 0x28 // CacheInhibit | Guard 00308 #define MM_PTE_TRANSITION_MASK 0x2 00309 #define MM_PTE_WRITE_MASK 0x200 00310 #define MM_PTE_COPY_ON_WRITE_MASK 0x400 00311 00312 // 00313 // Bit fields to or into PTE to make a PTE valid based on the 00314 // protection field of the invalid PTE. 00315 // 00316 00317 #define MM_PTE_NOACCESS 0x0 // not expressable on PowerPC 00318 #define MM_PTE_READONLY 0x3 00319 #define MM_PTE_READWRITE (0x3 | MM_PTE_WRITE_MASK) 00320 #define MM_PTE_WRITECOPY (0x3 | MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) 00321 #define MM_PTE_EXECUTE 0x3 // read-only on PowerPC 00322 #define MM_PTE_EXECUTE_READ 0x3 00323 #define MM_PTE_EXECUTE_READWRITE (0x3 | MM_PTE_WRITE_MASK) 00324 #define MM_PTE_EXECUTE_WRITECOPY (0x3 | MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) 00325 #define MM_PTE_NOCACHE (MM_PTE_CACHE_DISABLE_MASK) 00326 #define MM_PTE_GUARD 0x0 // not expressable on PowerPC 00327 #define MM_PTE_CACHE 0x0 00328 00329 #define MM_PROTECT_FIELD_SHIFT 3 00330 00331 // 00332 // Zero PTE 00333 // 00334 00335 #define MM_ZERO_PTE 0 00336 00337 // 00338 // Zero Kernel PTE 00339 // 00340 00341 #define MM_ZERO_KERNEL_PTE 0 00342 00343 00344 // 00345 // A demand zero PTE with a protection of PAGE_READWRITE. 00346 // 00347 00348 #define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00349 00350 // 00351 // A demand zero PTE with a protection of PAGE_READWRITE for system space. 00352 // 00353 00354 #define MM_KERNEL_DEMAND_ZERO_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00355 00356 // 00357 // A no access PTE for system space. 00358 // 00359 00360 #define MM_KERNEL_NOACCESS_PTE (MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) 00361 00362 // 00363 // Dirty bit definitions for clean and dirty. 00364 // 00365 00366 #define MM_PTE_CLEAN 3 00367 #define MM_PTE_DIRTY 0 00368 00369 00370 // 00371 // Kernel stack alignment requirements. 00372 // 00373 00374 #define MM_STACK_ALIGNMENT 0x0 00375 #define MM_STACK_OFFSET 0x0 00376 00377 // 00378 // System process definitions 00379 // 00380 00381 #define PDE_PER_PAGE ((ULONG)1024) 00382 00383 #define PTE_PER_PAGE ((ULONG)1024) 00384 00385 // 00386 // Number of page table pages for user addresses. 00387 // 00388 00389 #define MM_USER_PAGE_TABLE_PAGES (512) 00390 00391 // 00392 // Indicate the number of page colors required. 00393 // 00394 00395 #define MM_NUMBER_OF_COLORS 2 00396 #define MM_MAXIMUM_NUMBER_OF_COLORS 2 00397 00398 // 00399 // Mask for obtaining color from a physical page number. 00400 // 00401 00402 #define MM_COLOR_MASK 1 00403 00404 // 00405 // Define secondary color stride. 00406 // 00407 00408 #define MM_COLOR_STRIDE 3 00409 00410 // 00411 // Boundary for aligned pages of like color upon. 00412 // 00413 00414 #define MM_COLOR_ALIGNMENT 0x2000 00415 00416 // 00417 // Mask for isolating color from virtual address. 00418 // 00419 00420 #define MM_COLOR_MASK_VIRTUAL 0x1000 00421 00422 // 00423 // Define 256K worth of secondary colors. 00424 // 00425 00426 #define MM_SECONDARY_COLORS_DEFAULT ((256*1024) >> PAGE_SHIFT) 00427 00428 #define MM_SECONDARY_COLORS_MIN (2) 00429 00430 #define MM_SECONDARY_COLORS_MAX (2048) 00431 00432 // 00433 // Mask for isolating secondary color from physical page number; 00434 // 00435 00436 extern ULONG MmSecondaryColorMask; 00437 00438 // 00439 // Define macro to initialize directory table base. 00440 // 00441 00442 #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase,pfn) \ 00443 *((PULONG)(dirbase)) = ((pfn) << PAGE_SHIFT) 00444 00445 00446 //++ 00447 //VOID 00448 //MI_MAKE_VALID_PTE ( 00449 // OUT OUTPTE, 00450 // IN FRAME, 00451 // IN PMASK, 00452 // IN OWNER 00453 // ); 00454 // 00455 // Routine Description: 00456 // 00457 // This macro makes a valid PTE from a page frame number, protection mask, 00458 // and owner. 00459 // 00460 // Argments 00461 // 00462 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00463 // 00464 // FRAME - Supplies the page frame number for the PTE. 00465 // 00466 // PMASK - Supplies the protection to set in the transition PTE. 00467 // 00468 // PPTE - Supplies a pointer to the PTE which is being made valid. 00469 // For prototype PTEs NULL should be specified. 00470 // 00471 // Return Value: 00472 // 00473 // None. 00474 // 00475 //-- 00476 00477 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 00478 { \ 00479 (OUTPTE).u.Long = ((FRAME << 12) | \ 00480 (MmProtectToPteMask[PMASK]) | \ 00481 MM_PTE_VALID_MASK); \ 00482 if (((OUTPTE).u.Hard.Write == 1) && \ 00483 (((PMMPTE)PPTE) >= MiGetPteAddress(MM_LOWEST_NONPAGED_SYSTEM_START)))\ 00484 { \ 00485 (OUTPTE).u.Hard.Dirty = MM_PTE_DIRTY; \ 00486 } \ 00487 } 00488 00489 00490 //++ 00491 //VOID 00492 //MI_MAKE_VALID_PTE_TRANSITION ( 00493 // IN OUT OUTPTE 00494 // IN PROTECT 00495 // ); 00496 // 00497 // Routine Description: 00498 // 00499 // This macro takes a valid pte and turns it into a transition PTE. 00500 // 00501 // Argments 00502 // 00503 // OUTPTE - Supplies the current valid PTE. This PTE is then 00504 // modified to become a transition PTE. 00505 // 00506 // PROTECT - Supplies the protection to set in the transition PTE. 00507 // 00508 // Return Value: 00509 // 00510 // None. 00511 // 00512 //-- 00513 00514 #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \ 00515 (OUTPTE).u.Trans.Transition = 1; \ 00516 (OUTPTE).u.Trans.Valid = 0; \ 00517 (OUTPTE).u.Trans.Prototype = 0; \ 00518 (OUTPTE).u.Trans.Protection = PROTECT; 00519 00520 00521 //++ 00522 //VOID 00523 //MI_MAKE_TRANSITION_PTE ( 00524 // OUT OUTPTE, 00525 // IN PAGE, 00526 // IN PROTECT, 00527 // IN PPTE 00528 // ); 00529 // 00530 // Routine Description: 00531 // 00532 // This macro takes a valid pte and turns it into a transition PTE. 00533 // 00534 // Argments 00535 // 00536 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00537 // 00538 // PAGE - Supplies the page frame number for the PTE. 00539 // 00540 // PROTECT - Supplies the protection to set in the transition PTE. 00541 // 00542 // PPTE - Supplies a pointer to the PTE, this is used to determine 00543 // the owner of the PTE. 00544 // 00545 // Return Value: 00546 // 00547 // None. 00548 // 00549 //-- 00550 00551 #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \ 00552 (OUTPTE).u.Long = 0; \ 00553 (OUTPTE).u.Trans.PageFrameNumber = PAGE; \ 00554 (OUTPTE).u.Trans.Transition = 1; \ 00555 (OUTPTE).u.Trans.Protection = PROTECT; 00556 00557 00558 //++ 00559 //VOID 00560 //MI_MAKE_TRANSITION_PTE_VALID ( 00561 // OUT OUTPTE, 00562 // IN PPTE 00563 // ); 00564 // 00565 // Routine Description: 00566 // 00567 // This macro takes a transition pte and makes it a valid PTE. 00568 // 00569 // Argments 00570 // 00571 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00572 // 00573 // PPTE - Supplies a pointer to the transition PTE. 00574 // 00575 // Return Value: 00576 // 00577 // None. 00578 // 00579 //-- 00580 00581 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 00582 (OUTPTE).u.Long = (((PPTE)->u.Long & 0xFFFFF000) | \ 00583 (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) | \ 00584 MM_PTE_VALID_MASK); 00585 00586 //++ 00587 //VOID 00588 //MI_SET_PTE_DIRTY ( 00589 // IN MMPTE PTE 00590 // ); 00591 // 00592 // Routine Description: 00593 // 00594 // This macro sets the dirty bit(s) in the specified PTE. 00595 // 00596 // Argments 00597 // 00598 // PTE - Supplies the PTE to set dirty. 00599 // 00600 // Return Value: 00601 // 00602 // None. 00603 // 00604 //-- 00605 00606 #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Hard.Dirty = MM_PTE_DIRTY 00607 00608 00609 //++ 00610 //VOID 00611 //MI_SET_PTE_CLEAN ( 00612 // IN MMPTE PTE 00613 // ); 00614 // 00615 // Routine Description: 00616 // 00617 // This macro clears the dirty bit(s) in the specified PTE. 00618 // 00619 // Argments 00620 // 00621 // PTE - Supplies the PTE to set clear. 00622 // 00623 // Return Value: 00624 // 00625 // None. 00626 // 00627 //-- 00628 00629 #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Hard.Dirty = MM_PTE_CLEAN 00630 00631 00632 00633 //++ 00634 //VOID 00635 //MI_IS_PTE_DIRTY ( 00636 // IN MMPTE PTE 00637 // ); 00638 // 00639 // Routine Description: 00640 // 00641 // This macro checks the dirty bit(s) in the specified PTE. 00642 // 00643 // Argments 00644 // 00645 // PTE - Supplies the PTE to check. 00646 // 00647 // Return Value: 00648 // 00649 // TRUE if the page is dirty (modified), FALSE otherwise. 00650 // 00651 //-- 00652 00653 #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != MM_PTE_CLEAN) 00654 00655 00656 00657 00658 //++ 00659 //VOID 00660 //MI_SET_GLOBAL_BIT_IF_SYSTEM ( 00661 // OUT OUTPTE, 00662 // IN PPTE 00663 // ); 00664 // 00665 // Routine Description: 00666 // 00667 // This macro sets the global bit if the pointer PTE is within 00668 // system space. 00669 // 00670 // Argments 00671 // 00672 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00673 // 00674 // PPTE - Supplies a pointer to the PTE becoming valid. 00675 // 00676 // Return Value: 00677 // 00678 // None. 00679 // 00680 //-- 00681 00682 #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE) 00683 00684 00685 //++ 00686 //VOID 00687 //MI_SET_GLOBAL_STATE ( 00688 // IN MMPTE PTE, 00689 // IN ULONG STATE 00690 // ); 00691 // 00692 // Routine Description: 00693 // 00694 // This macro sets the global bit in the PTE. if the pointer PTE is within 00695 // 00696 // Argments 00697 // 00698 // PTE - Supplies the PTE to set global state into. 00699 // 00700 // Return Value: 00701 // 00702 // None. 00703 // 00704 //-- 00705 00706 #define MI_SET_GLOBAL_STATE(PTE,STATE) 00707 00708 00709 00710 //++ 00711 //VOID 00712 //MI_ENABLE_CACHING ( 00713 // IN MMPTE PTE 00714 // ); 00715 // 00716 // Routine Description: 00717 // 00718 // This macro takes a valid PTE and sets the caching state to be 00719 // enabled. 00720 // 00721 // Argments 00722 // 00723 // PTE - Supplies a valid PTE. 00724 // 00725 // Return Value: 00726 // 00727 // None. 00728 // 00729 //-- 00730 00731 #define MI_ENABLE_CACHING(PTE) \ 00732 ((PTE).u.Hard.CacheDisable = (PTE).u.Hard.GuardedStorage = 0) 00733 00734 00735 //++ 00736 //VOID 00737 //MI_DISABLE_CACHING ( 00738 // IN MMPTE PTE 00739 // ); 00740 // 00741 // Routine Description: 00742 // 00743 // This macro takes a valid PTE and sets the caching state to be 00744 // disabled. 00745 // 00746 // Argments 00747 // 00748 // PTE - Supplies a valid PTE. 00749 // 00750 // Return Value: 00751 // 00752 // None. 00753 // 00754 //-- 00755 00756 #define MI_DISABLE_CACHING(PTE) \ 00757 ((PTE).u.Hard.CacheDisable = (PTE).u.Hard.GuardedStorage = 1) 00758 00759 00760 //++ 00761 //BOOLEAN 00762 //MI_IS_CACHING_DISABLED ( 00763 // IN PMMPTE PPTE 00764 // ); 00765 // 00766 // Routine Description: 00767 // 00768 // This macro takes a valid PTE and returns TRUE if caching is 00769 // disabled. 00770 // 00771 // Argments 00772 // 00773 // PPTE - Supplies a pointer to the valid PTE. 00774 // 00775 // Return Value: 00776 // 00777 // TRUE if caching is disabled, FALSE if it is enabled. 00778 // 00779 //-- 00780 00781 #define MI_IS_CACHING_DISABLED(PPTE) \ 00782 ((PPTE)->u.Hard.CacheDisable == 1) 00783 00784 00785 //++ 00786 //VOID 00787 //MI_SET_PFN_DELETED ( 00788 // IN PMMPFN PPFN 00789 // ); 00790 // 00791 // Routine Description: 00792 // 00793 // This macro takes a pointer to a PFN element and indicates that 00794 // the PFN is no longer in use. 00795 // 00796 // Argments 00797 // 00798 // PPTE - Supplies a pointer to the PFN element. 00799 // 00800 // Return Value: 00801 // 00802 // none. 00803 // 00804 //-- 00805 00806 #define MI_SET_PFN_DELETED(PPFN) ((PPFN)->PteAddress = (PMMPTE)0xFFFFFFFF) 00807 00808 00809 //++ 00810 //BOOLEAN 00811 //MI_IS_PFN_DELETED ( 00812 // IN PMMPFN PPFN 00813 // ); 00814 // 00815 // Routine Description: 00816 // 00817 // This macro takes a pointer to a PFN element a determines if 00818 // the PFN is no longer in use. 00819 // 00820 // Argments 00821 // 00822 // PPTE - Supplies a pointer to the PFN element. 00823 // 00824 // Return Value: 00825 // 00826 // TRUE if PFN is no longer used, FALSE if it is still being used. 00827 // 00828 //-- 00829 00830 #define MI_IS_PFN_DELETED(PPFN) \ 00831 ((PPFN)->PteAddress == (PMMPTE)0xFFFFFFFF) 00832 00833 00834 //++ 00835 //VOID 00836 //MI_CHECK_PAGE_ALIGNMENT ( 00837 // IN ULONG PAGE, 00838 // IN ULONG COLOR 00839 // ); 00840 // 00841 // Routine Description: 00842 // 00843 // This macro takes a PFN element number (Page) and checks to see 00844 // if the virtual alignment for the previous address of the page 00845 // is compatable with the new address of the page. If they are 00846 // not compatable, the D cache is flushed. 00847 // 00848 // Argments 00849 // 00850 // PAGE - Supplies the PFN element. 00851 // PPTE - Supplies a pointer to the new PTE which will contain the page. 00852 // 00853 // Return Value: 00854 // 00855 // none. 00856 // 00857 //-- 00858 00859 #define MI_CHECK_PAGE_ALIGNMENT(PAGE,COLOR) \ 00860 { \ 00861 PMMPFN PPFN; \ 00862 ULONG OldColor; \ 00863 PPFN = MI_PFN_ELEMENT(PAGE); \ 00864 OldColor = PPFN->u3.e1.PageColor; \ 00865 if ((COLOR) != OldColor) { \ 00866 PPFN->u3.e1.PageColor = COLOR; \ 00867 } \ 00868 } 00869 00870 00871 //++ 00872 //VOID 00873 //MI_INITIALIZE_HYPERSPACE_MAP ( 00874 // HYPER_PAGE 00875 // ); 00876 // 00877 // Routine Description: 00878 // 00879 // This macro initializes the PTEs reserved for double mapping within 00880 // hyperspace. 00881 // 00882 // Argments 00883 // 00884 // HYPER_PAGE - Phyical page number for the page to become hyperspace. 00885 // 00886 // Return Value: 00887 // 00888 // None. 00889 // 00890 //-- 00891 00892 #define MI_INITIALIZE_HYPERSPACE_MAP(HYPER_PAGE) \ 00893 { \ 00894 PMMPTE Base; \ 00895 KIRQL OldIrql; \ 00896 Base = MiMapPageInHyperSpace (HYPER_PAGE, &OldIrql); \ 00897 Base->u.Hard.PageFrameNumber = NUMBER_OF_MAPPING_PTES; \ 00898 MiUnmapPageInHyperSpace (OldIrql); \ 00899 } 00900 00901 00902 00903 //++ 00904 //ULONG 00905 //MI_GET_PAGE_COLOR_FROM_PTE ( 00906 // IN PMMPTE PTEADDRESS 00907 // ); 00908 // 00909 // Routine Description: 00910 // 00911 // This macro determines the pages color based on the PTE address 00912 // that maps the page. 00913 // 00914 // Argments 00915 // 00916 // PTEADDRESS - Supplies the PTE address the page is (or was) mapped at. 00917 // 00918 // Return Value: 00919 // 00920 // The pages color. 00921 // 00922 //-- 00923 00924 #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \ 00925 ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ 00926 MmSecondaryColorMask) | \ 00927 ((((ULONG)(PTEADDRESS)) >> 2) & MM_COLOR_MASK)) 00928 00929 //++ 00930 //ULONG 00931 //MI_GET_PAGE_COLOR_FROM_VA ( 00932 // IN PVOID ADDRESS 00933 // ); 00934 // 00935 // Routine Description: 00936 // 00937 // This macro determines the pages color based on the PTE address 00938 // that maps the page. 00939 // 00940 // Argments 00941 // 00942 // ADDRESS - Supplies the address the page is (or was) mapped at. 00943 // 00944 // Return Value: 00945 // 00946 // The pages color. 00947 // 00948 //-- 00949 00950 #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \ 00951 ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ 00952 MmSecondaryColorMask) | \ 00953 ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) 00954 00955 00956 //++ 00957 //ULONG 00958 //MI_PAGE_COLOR_PTE_PROCESS ( 00959 // IN PCHAR COLOR, 00960 // IN PMMPTE PTE 00961 // ); 00962 // 00963 // Routine Description: 00964 // 00965 // This macro determines the pages color based on the PTE address 00966 // that maps the page. 00967 // 00968 // Argments 00969 // 00970 // 00971 // Return Value: 00972 // 00973 // The pages color. 00974 // 00975 //-- 00976 00977 #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \ 00978 ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ 00979 MmSecondaryColorMask) | \ 00980 ((((ULONG)(PTE)) >> 2) & MM_COLOR_MASK)) 00981 00982 00983 //++ 00984 //ULONG 00985 //MI_PAGE_COLOR_VA_PROCESS ( 00986 // IN PVOID ADDRESS, 00987 // IN PEPROCESS COLOR 00988 // ); 00989 // 00990 // Routine Description: 00991 // 00992 // This macro determines the pages color based on the PTE address 00993 // that maps the page. 00994 // 00995 // Argments 00996 // 00997 // ADDRESS - Supplies the address the page is (or was) mapped at. 00998 // 00999 // Return Value: 01000 // 01001 // The pages color. 01002 // 01003 //-- 01004 01005 #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \ 01006 ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ 01007 MmSecondaryColorMask) | \ 01008 ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) 01009 01010 01011 //++ 01012 //ULONG 01013 //MI_GET_NEXT_COLOR ( 01014 // IN ULONG COLOR 01015 // ); 01016 // 01017 // Routine Description: 01018 // 01019 // This macro returns the next color in the sequence. 01020 // 01021 // Argments 01022 // 01023 // COLOR - Supplies the color to return the next of. 01024 // 01025 // Return Value: 01026 // 01027 // Next color in sequence. 01028 // 01029 //-- 01030 01031 #define MI_GET_NEXT_COLOR(COLOR) ((COLOR + 1) & MM_COLOR_MASK) 01032 01033 01034 //++ 01035 //ULONG 01036 //MI_GET_PREVIOUS_COLOR ( 01037 // IN ULONG COLOR 01038 // ); 01039 // 01040 // Routine Description: 01041 // 01042 // This macro returns the previous color in the sequence. 01043 // 01044 // Argments 01045 // 01046 // COLOR - Supplies the color to return the previous of. 01047 // 01048 // Return Value: 01049 // 01050 // Previous color in sequence. 01051 // 01052 //-- 01053 01054 #define MI_GET_PREVIOUS_COLOR(COLOR) ((COLOR - 1) & MM_COLOR_MASK) 01055 01056 #define MI_GET_SECONDARY_COLOR(PAGE,PFN) \ 01057 ((((ULONG)(PAGE) & MmSecondaryColorMask)) | (PFN)->u3.e1.PageColor) 01058 01059 #define MI_GET_COLOR_FROM_SECONDARY(COLOR) ((COLOR) & MM_COLOR_MASK) 01060 01061 01062 //++ 01063 //VOID 01064 //MI_GET_MODIFIED_PAGE_BY_COLOR ( 01065 // OUT ULONG PAGE, 01066 // IN ULONG COLOR 01067 // ); 01068 // 01069 // Routine Description: 01070 // 01071 // This macro returns the first page destined for a paging 01072 // file with the desired color. It does NOT remove the page 01073 // from its list. 01074 // 01075 // Argments 01076 // 01077 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01078 // returned if there is no page of the specified color. 01079 // 01080 // COLOR - Supplies the color of page to locate. 01081 // 01082 // Return Value: 01083 // 01084 // none. 01085 // 01086 //-- 01087 01088 #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \ 01089 PAGE = MmModifiedPageListByColor[COLOR].Flink 01090 01091 01092 //++ 01093 //VOID 01094 //MI_GET_MODIFIED_PAGE_ANY_COLOR ( 01095 // OUT ULONG PAGE, 01096 // IN OUT ULONG COLOR 01097 // ); 01098 // 01099 // Routine Description: 01100 // 01101 // This macro returns the first page destined for a paging 01102 // file with the desired color. If not page of the desired 01103 // color exists, all colored lists are searched for a page. 01104 // It does NOT remove the page from its list. 01105 // 01106 // Argments 01107 // 01108 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01109 // returned if there is no page of the specified color. 01110 // 01111 // COLOR - Supplies the color of page to locate and returns the 01112 // color of the page located. 01113 // 01114 // Return Value: 01115 // 01116 // none. 01117 // 01118 //-- 01119 01120 #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \ 01121 { \ 01122 if (MmTotalPagesForPagingFile == 0) { \ 01123 PAGE = MM_EMPTY_LIST; \ 01124 } else { \ 01125 while (MmModifiedPageListByColor[COLOR].Flink == \ 01126 MM_EMPTY_LIST) { \ 01127 COLOR = MI_GET_NEXT_COLOR(COLOR); \ 01128 } \ 01129 PAGE = MmModifiedPageListByColor[COLOR].Flink; \ 01130 } \ 01131 } 01132 01133 01134 //++ 01135 //VOID 01136 //MI_MAKE_VALID_PTE_WRITE_COPY ( 01137 // IN OUT PMMPTE PTE 01138 // ); 01139 // 01140 // Routine Description: 01141 // 01142 // This macro checks to see if the PTE indicates that the 01143 // page is writable and if so it clears the write bit and 01144 // sets the copy-on-write bit. 01145 // 01146 // Argments 01147 // 01148 // PTE - Supplies the PTE to operate upon. 01149 // 01150 // Return Value: 01151 // 01152 // None. 01153 // 01154 //-- 01155 01156 #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ 01157 if ((PPTE)->u.Hard.Write == 1) { \ 01158 (PPTE)->u.Hard.CopyOnWrite = 1; \ 01159 (PPTE)->u.Hard.Dirty = MM_PTE_CLEAN; \ 01160 } 01161 01162 01163 //++ 01164 //ULONG 01165 //MI_DETERMINE_OWNER ( 01166 // IN MMPTE PPTE 01167 // ); 01168 // 01169 // Routine Description: 01170 // 01171 // This macro examines the virtual address of the PTE and determines 01172 // if the PTE resides in system space or user space. 01173 // 01174 // Argments 01175 // 01176 // PTE - Supplies the PTE to operate upon. 01177 // 01178 // Return Value: 01179 // 01180 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01181 // 01182 //-- 01183 01184 #define MI_DETERMINE_OWNER(PPTE) \ 01185 ((((PPTE) <= MiGetPteAddress(MM_HIGHEST_USER_ADDRESS)) || \ 01186 ((PPTE) >= MiGetPdeAddress(NULL) && \ 01187 ((PPTE) <= MiGetPdeAddress(MM_HIGHEST_USER_ADDRESS)))) ? 1 : 0) 01188 01189 01190 //++ 01191 //VOID 01192 //MI_SET_ACCESSED_IN_PTE ( 01193 // IN OUT MMPTE PPTE 01194 // ); 01195 // 01196 // Routine Description: 01197 // 01198 // This macro sets the ACCESSED field in the PTE. 01199 // 01200 // Argments 01201 // 01202 // PTE - Supplies the PTE to operate upon. 01203 // 01204 // Return Value: 01205 // 01206 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01207 // 01208 //-- 01209 01210 #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) 01211 01212 01213 //++ 01214 //ULONG 01215 //MI_GET_ACCESSED_IN_PTE ( 01216 // IN OUT MMPTE PPTE 01217 // ); 01218 // 01219 // Routine Description: 01220 // 01221 // This macro returns the state of the ACCESSED field in the PTE. 01222 // 01223 // Argments 01224 // 01225 // PTE - Supplies the PTE to operate upon. 01226 // 01227 // Return Value: 01228 // 01229 // The state of the ACCESSED field. 01230 // 01231 //-- 01232 01233 #define MI_GET_ACCESSED_IN_PTE(PPTE) 0 01234 01235 01236 //++ 01237 //VOID 01238 //MI_SET_OWNER_IN_PTE ( 01239 // IN PMMPTE PPTE 01240 // IN ULONG OWNER 01241 // ); 01242 // 01243 // Routine Description: 01244 // 01245 // This macro sets the owner field in the PTE. 01246 // 01247 // Argments 01248 // 01249 // PTE - Supplies the PTE to operate upon. 01250 // 01251 // Return Value: 01252 // 01253 // None. 01254 // 01255 //-- 01256 01257 #define MI_SET_OWNER_IN_PTE(PPTE,OWNER) 01258 01259 01260 //++ 01261 //ULONG 01262 //MI_GET_OWNER_IN_PTE ( 01263 // IN PMMPTE PPTE 01264 // ); 01265 // 01266 // Routine Description: 01267 // 01268 // This macro gets the owner field from the PTE. 01269 // 01270 // Argments 01271 // 01272 // PTE - Supplies the PTE to operate upon. 01273 // 01274 // Return Value: 01275 // 01276 // The state of the OWNER field. 01277 // 01278 //-- 01279 01280 #define MI_GET_OWNER_IN_PTE(PPTE) KernelMode 01281 01282 01283 // bit mask to clear out fields in a PTE to or in paging file location. 01284 01285 #define CLEAR_FOR_PAGE_FILE ((ULONG)(0x0F8)) 01286 01287 01288 //++ 01289 //VOID 01290 //MI_SET_PAGING_FILE_INFO ( 01291 // IN OUT MMPTE PPTE, 01292 // IN ULONG FILEINFO, 01293 // IN ULONG OFFSET 01294 // ); 01295 // 01296 // Routine Description: 01297 // 01298 // This macro sets into the specified PTE the supplied information 01299 // to indicate where the backing store for the page is located. 01300 // 01301 // Argments 01302 // 01303 // PTE - Supplies the PTE to operate upon. 01304 // 01305 // FILEINFO - Supplies the number of the paging file. 01306 // 01307 // OFFSET - Supplies the offset into the paging file. 01308 // 01309 // Return Value: 01310 // 01311 // None. 01312 // 01313 //-- 01314 01315 #define SET_PAGING_FILE_INFO(PTE,FILEINFO,OFFSET) \ 01316 ((((PTE).u.Long & CLEAR_FOR_PAGE_FILE) | \ 01317 (((FILEINFO) << 8) | \ 01318 (OFFSET << 12)))) 01319 01320 01321 //++ 01322 //PMMPTE 01323 //MiPteToProto ( 01324 // IN OUT MMPTE PPTE, 01325 // IN ULONG FILEINFO, 01326 // IN ULONG OFFSET 01327 // ); 01328 // 01329 // Routine Description: 01330 // 01331 // This macro returns the address of the corresponding prototype which 01332 // was encoded earlier into the supplied PTE. 01333 // 01334 // NOTE THAT AS PROTOPTE CAN RESIDE IN BOTH PAGED AND NONPAGED POOL 01335 // THIS MACRO LIMITS THE COMBINED SIZES OF TWO POOLS AND REQUIRES THEM 01336 // TO BE WITHIN THE MAX SIZE CONSTRAINTS 01337 // 01338 // MAX SIZE = 2^(2+8+20) = 2^30 = 1GB 01339 // 01340 // NOTE, that the valid bit must be zero! 01341 // 01342 // Argments 01343 // 01344 // lpte - Supplies the PTE to operate upon. 01345 // 01346 // Return Value: 01347 // 01348 // Pointer to the prototype PTE that backs this PTE. 01349 // 01350 //-- 01351 01352 #define MiPteToProto(lpte) ((PMMPTE)((((lpte)->u.Long >> 4) << 2) + \ 01353 MmProtopte_Base)) 01354 01355 01356 //++ 01357 //ULONG 01358 //MiProtoAddressForPte ( 01359 // IN PMMPTE proto_va 01360 // ); 01361 // 01362 // Routine Description: 01363 // 01364 // This macro sets into the specified PTE the supplied information 01365 // to indicate where the backing store for the page is located. 01366 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01367 // reference a prototype PTE. And set the protoPTE bit, 01368 // MM_PTE_PROTOTYPE_MASK. 01369 // 01370 // Argments 01371 // 01372 // proto_va - Supplies the address of the prototype PTE. 01373 // 01374 // Return Value: 01375 // 01376 // Mask to set into the PTE. 01377 // 01378 //-- 01379 01380 #define MiProtoAddressForPte(proto_va) \ 01381 ((ULONG)((((ULONG)proto_va - MmProtopte_Base) << 2) | MM_PTE_PROTOTYPE_MASK)) 01382 01383 01384 //++ 01385 //ULONG 01386 //MiProtoAddressForKernelPte ( 01387 // IN PMMPTE proto_va 01388 // ); 01389 // 01390 // Routine Description: 01391 // 01392 // This macro sets into the specified PTE the supplied information 01393 // to indicate where the backing store for the page is located. 01394 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01395 // reference a prototype PTE. And set the protoPTE bit, 01396 // MM_PTE_PROTOTYPE_MASK. 01397 // 01398 // This macro also sets any other information (such as global bits) 01399 // required for kernel mode PTEs. 01400 // 01401 // Argments 01402 // 01403 // proto_va - Supplies the address of the prototype PTE. 01404 // 01405 // Return Value: 01406 // 01407 // Mask to set into the PTE. 01408 // 01409 //-- 01410 01411 #define MiProtoAddressForKernelPte(proto_va) MiProtoAddressForPte(proto_va) 01412 01413 01414 //++ 01415 //PSUBSECTION 01416 //MiGetSubsectionAddress ( 01417 // IN PMMPTE lpte 01418 // ); 01419 // 01420 // Routine Description: 01421 // 01422 // This macro takes a PTE and returns the address of the subsection that 01423 // the PTE refers to. Subsections are quadword structures allocated 01424 // from nonpaged pool. 01425 // 01426 // NOTE THIS MACRO LIMITS THE SIZE OF NONPAGED POOL! 01427 // MAXIMUM NONPAGED POOL = 2^(3+1+24) = 2^28 = 256mb. 01428 // 01429 // 01430 // Argments 01431 // 01432 // lpte - Supplies the PTE to operate upon. 01433 // 01434 // Return Value: 01435 // 01436 // A pointer to the subsection referred to by the supplied PTE. 01437 // 01438 //-- 01439 01440 #define MiGetSubsectionAddress(lpte) \ 01441 ((PSUBSECTION)((ULONG)MM_NONPAGED_POOL_END - \ 01442 (((((lpte)->u.Long) >> 8) << 4) | \ 01443 ((((lpte)->u.Long) << 2) & 0x8)))) 01444 01445 01446 //++ 01447 //ULONG 01448 //MiGetSubsectionAddressForPte ( 01449 // IN PSUBSECTION VA 01450 // ); 01451 // 01452 // Routine Description: 01453 // 01454 // This macro takes the address of a subsection and encodes it for use 01455 // in a PTE. 01456 // 01457 // NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED! 01458 // 01459 // Argments 01460 // 01461 // VA - Supplies a pointer to the subsection to encode. 01462 // 01463 // Return Value: 01464 // 01465 // The mask to set into the PTE to make it reference the supplied 01466 // subsetion. 01467 // 01468 //-- 01469 01470 #define MiGetSubsectionAddressForPte(VA) \ 01471 (((((ULONG)MM_NONPAGED_POOL_END - (ULONG)VA) << 4) & (ULONG)0xffffff00) | \ 01472 ((((ULONG)MM_NONPAGED_POOL_END - (ULONG)VA) >> 2) & (ULONG)0x2)) 01473 01474 01475 //++ 01476 //PMMPTE 01477 //MiGetPdeAddress ( 01478 // IN PVOID va 01479 // ); 01480 // 01481 // Routine Description: 01482 // 01483 // MiGetPdeAddress returns the address of the PDE which maps the 01484 // given virtual address. 01485 // 01486 // Argments 01487 // 01488 // Va - Supplies the virtual address to locate the PDE for. 01489 // 01490 // Return Value: 01491 // 01492 // The address of the PDE. 01493 // 01494 //-- 01495 01496 #define MiGetPdeAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE)) 01497 01498 01499 //++ 01500 //PMMPTE 01501 //MiGetPteAddress ( 01502 // IN PVOID va 01503 // ); 01504 // 01505 // Routine Description: 01506 // 01507 // MiGetPteAddress returns the address of the PTE which maps the 01508 // given virtual address. 01509 // 01510 // Argments 01511 // 01512 // Va - Supplies the virtual address to locate the PTE for. 01513 // 01514 // Return Value: 01515 // 01516 // The address of the PTE. 01517 // 01518 //-- 01519 01520 #define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE)) 01521 01522 01523 //++ 01524 //ULONG 01525 //MiGetPdeOffset ( 01526 // IN PVOID va 01527 // ); 01528 // 01529 // Routine Description: 01530 // 01531 // MiGetPdeOffset returns the offset into a page directory 01532 // for a given virtual address. 01533 // 01534 // Argments 01535 // 01536 // Va - Supplies the virtual address to locate the offset for. 01537 // 01538 // Return Value: 01539 // 01540 // The offset into the page directory table the corresponding PDE is at. 01541 // 01542 //-- 01543 01544 #define MiGetPdeOffset(va) (((ULONG)(va)) >> 22) 01545 01546 01547 //++ 01548 //ULONG 01549 //MiGetPteOffset ( 01550 // IN PVOID va 01551 // ); 01552 // 01553 // Routine Description: 01554 // 01555 // MiGetPteOffset returns the offset into a page table page 01556 // for a given virtual address. 01557 // 01558 // Argments 01559 // 01560 // Va - Supplies the virtual address to locate the offset for. 01561 // 01562 // Return Value: 01563 // 01564 // The offset into the page table page table the corresponding PTE is at. 01565 // 01566 //-- 01567 01568 #define MiGetPteOffset(va) ((((ULONG)(va)) << 10) >> 22) 01569 01570 01571 01572 //++ 01573 //PVOID 01574 //MiGetVirtualAddressMappedByPte ( 01575 // IN PMMPTE PTE 01576 // ); 01577 // 01578 // Routine Description: 01579 // 01580 // MiGetVirtualAddressMappedByPte returns the virtual address 01581 // which is mapped by a given PTE address. 01582 // 01583 // Argments 01584 // 01585 // PTE - Supplies the PTE to get the virtual address for. 01586 // 01587 // Return Value: 01588 // 01589 // Virtual address mapped by the PTE. 01590 // 01591 //-- 01592 01593 #define MiGetVirtualAddressMappedByPte(va) ((PVOID)((ULONG)(va) << 10)) 01594 01595 01596 //++ 01597 //ULONG 01598 //GET_PAGING_FILE_NUMBER ( 01599 // IN MMPTE PTE 01600 // ); 01601 // 01602 // Routine Description: 01603 // 01604 // This macro extracts the paging file number from a PTE. 01605 // 01606 // Argments 01607 // 01608 // PTE - Supplies the PTE to operate upon. 01609 // 01610 // Return Value: 01611 // 01612 // The paging file number. 01613 // 01614 //-- 01615 01616 #define GET_PAGING_FILE_NUMBER(PTE) ((((PTE).u.Long) >> 8) & 0xF) 01617 01618 01619 //++ 01620 //ULONG 01621 //GET_PAGING_FILE_OFFSET ( 01622 // IN MMPTE PTE 01623 // ); 01624 // 01625 // Routine Description: 01626 // 01627 // This macro extracts the offset into the paging file from a PTE. 01628 // 01629 // Argments 01630 // 01631 // PTE - Supplies the PTE to operate upon. 01632 // 01633 // Return Value: 01634 // 01635 // The paging file offset. 01636 // 01637 //-- 01638 01639 #define GET_PAGING_FILE_OFFSET(PTE) ((((PTE).u.Long) >> 12) & 0x000FFFFF) 01640 01641 01642 //++ 01643 //ULONG 01644 //IS_PTE_NOT_DEMAND_ZERO ( 01645 // IN PMMPTE PPTE 01646 // ); 01647 // 01648 // Routine Description: 01649 // 01650 // This macro checks to see if a given PTE is NOT a demand zero PTE. 01651 // 01652 // Argments 01653 // 01654 // PTE - Supplies the PTE to operate upon. 01655 // 01656 // Return Value: 01657 // 01658 // Returns 0 if the PTE is demand zero, non-zero otherwise. 01659 // 01660 //-- 01661 01662 #define IS_PTE_NOT_DEMAND_ZERO(PTE) ((PTE).u.Long & (ULONG)0xFFFFF007) 01663 01664 01665 //++ 01666 //VOID 01667 //MI_MAKING_VALID_PTE_INVALID( 01668 // IN PMMPTE PPTE 01669 // ); 01670 // 01671 // Routine Description: 01672 // 01673 // Prepare to make a single valid PTE invalid. 01674 // No action is required on x86. 01675 // 01676 // Argments 01677 // 01678 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 01679 // 01680 // Return Value: 01681 // 01682 // None. 01683 // 01684 //-- 01685 01686 #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE) 01687 01688 01689 //++ 01690 //VOID 01691 //MI_MAKING_VALID_MULTIPLE_PTES_INVALID( 01692 // IN PMMPTE PPTE 01693 // ); 01694 // 01695 // Routine Description: 01696 // 01697 // Prepare to make multiple valid PTEs invalid. 01698 // No action is required on x86. 01699 // 01700 // Argments 01701 // 01702 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 01703 // 01704 // Return Value: 01705 // 01706 // None. 01707 // 01708 //-- 01709 01710 #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE) 01711 01712 01713 // 01714 // Make a writable PTE, writeable-copy PTE. This takes advantage of 01715 // the fact that the protection field in the PTE (5 bit protection) is 01716 // set up such that write is a bit. 01717 // 01718 01719 #define MI_MAKE_PROTECT_WRITE_COPY(PTE) \ 01720 if ((PTE).u.Long & 0x20) { \ 01721 ((PTE).u.Long |= 0x8); \ 01722 } 01723 01724 01725 //++ 01726 //VOID 01727 //MI_SET_PAGE_DIRTY( 01728 // IN PMMPTE PPTE, 01729 // IN PVOID VA, 01730 // IN PVOID PFNHELD 01731 // ); 01732 // 01733 // Routine Description: 01734 // 01735 // This macro sets the dirty bit (and release page file space). 01736 // 01737 // Argments 01738 // 01739 // TEMP - Supplies a temporary for usage. 01740 // 01741 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 01742 // 01743 // VA - Supplies a the virtual address of the page fault. 01744 // 01745 // PFNHELD - Supplies TRUE if the PFN lock is held. 01746 // 01747 // Return Value: 01748 // 01749 // None. 01750 // 01751 //-- 01752 01753 #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \ 01754 if ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN) { \ 01755 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 01756 } 01757 01758 01759 //++ 01760 //VOID 01761 //MI_NO_FAULT_FOUND( 01762 // IN TEMP, 01763 // IN PMMPTE PPTE, 01764 // IN PVOID VA, 01765 // IN PVOID PFNHELD 01766 // ); 01767 // 01768 // Routine Description: 01769 // 01770 // This macro handles the case when a page fault is taken and no 01771 // PTE with the valid bit clear is found. 01772 // 01773 // Argments 01774 // 01775 // TEMP - Supplies a temporary for usage. 01776 // 01777 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 01778 // 01779 // VA - Supplies a the virtual address of the page fault. 01780 // 01781 // PFNHELD - Supplies TRUE if the PFN lock is held. 01782 // 01783 // Return Value: 01784 // 01785 // None. 01786 // 01787 //-- 01788 01789 #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \ 01790 if (StoreInstruction && ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN)) { \ 01791 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 01792 } else { \ 01793 KeFillEntryTb ((PHARDWARE_PTE)PPTE, VA, FALSE); \ 01794 } 01795 // KeFillEntryTb((PHARDWARE_PTE)(MiGetPdeAddress(VA)),(PVOID)PPTE,FALSE); 01796 // 01797 // If the PTE was already valid, assume that the PTE 01798 // in the TB is stall and just reload the PTE. 01799 // 01800 01801 01802 //++ 01803 //ULONG 01804 //MI_CAPTURE_DIRTY_BIT_TO_PFN ( 01805 // IN PMMPTE PPTE, 01806 // IN PMMPFN PPFN 01807 // ); 01808 // 01809 // Routine Description: 01810 // 01811 // This macro gets captures the state of the dirty bit to the PFN 01812 // and frees any associated page file space if the PTE has been 01813 // modified element. 01814 // 01815 // NOTE - THE PFN LOCK MUST BE HELD! 01816 // 01817 // Argments 01818 // 01819 // PPTE - Supplies the PTE to operate upon. 01820 // 01821 // PPFN - Supplies a pointer to the PFN database element that corresponds 01822 // to the page mapped by the PTE. 01823 // 01824 // Return Value: 01825 // 01826 // None. 01827 // 01828 //-- 01829 01830 #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \ 01831 if (((PPFN)->u3.e1.Modified == 0) && \ 01832 ((PPTE)->u.Hard.Dirty == MM_PTE_DIRTY)) { \ 01833 (PPFN)->u3.e1.Modified = 1; \ 01834 if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \ 01835 ((PPFN)->u3.e1.WriteInProgress == 0)) { \ 01836 MiReleasePageFileSpace ((PPFN)->OriginalPte); \ 01837 (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \ 01838 } \ 01839 } 01840 01841 01842 //++ 01843 //BOOLEAN 01844 //MI_IS_PHYSICAL_ADDRESS ( 01845 // IN PVOID VA 01846 // ); 01847 // 01848 // Routine Description: 01849 // 01850 // This macro deterines if a give virtual address is really a 01851 // physical address. 01852 // 01853 // Argments 01854 // 01855 // VA - Supplies the virtual address. 01856 // 01857 // Return Value: 01858 // 01859 // FALSE if it is not a physical address, TRUE if it is. 01860 // 01861 //-- 01862 01863 #define MI_IS_PHYSICAL_ADDRESS(Va) \ 01864 (((ULONG)Va >= KSEG0_BASE) && ((ULONG)Va < KSEG2_BASE)) 01865 01866 01867 //++ 01868 //ULONG 01869 //MI_CONVERT_PHYSICAL_TO_PFN ( 01870 // IN PVOID VA 01871 // ); 01872 // 01873 // Routine Description: 01874 // 01875 // This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS) 01876 // to its corresponding physical frame number. 01877 // 01878 // Argments 01879 // 01880 // VA - Supplies a pointer to the physical address. 01881 // 01882 // Return Value: 01883 // 01884 // Returns the PFN for the page. 01885 // 01886 //-- 01887 01888 #define MI_CONVERT_PHYSICAL_TO_PFN(Va) (((ULONG)Va << 2) >> 14) 01889 01890 01891 typedef struct _MMCOLOR_TABLES { 01892 ULONG Flink; 01893 PVOID Blink; 01894 } MMCOLOR_TABLES, *PMMCOLOR_TABLES; 01895 01896 typedef struct _MMPRIMARY_COLOR_TABLES { 01897 LIST_ENTRY ListHead; 01898 } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES; 01899 01900 01901 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1 01902 extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS]; 01903 #endif 01904 01905 extern PMMCOLOR_TABLES MmFreePagesByColor[2]; 01906 01907 extern ULONG MmTotalPagesForPagingFile; 01908 01909 01910 01911 // 01912 // A valid Page Table Entry has the following definition. 01913 // 01914 01915 // N.B. defined as in comments below in ../public/sdk/inc/ntppc.h 01916 01917 // typedef struct _HARDWARE_PTE { 01918 // ULONG Dirty : 2; 01919 // ULONG Valid : 1; // software 01920 // ULONG GuardedStorage : 1; 01921 // ULONG MemoryCoherence : 1; 01922 // ULONG CacheDisable : 1; 01923 // ULONG WriteThrough : 1; 01924 // ULONG Change : 1; 01925 // ULONG Reference : 1; 01926 // ULONG Write : 1; // software 01927 // ULONG CopyOnWrite : 1; // software 01928 // ULONG rsvd1 : 1; 01929 // ULONG PageFrameNumber : 20; 01930 // } HARDWARE_PTE, *PHARDWARE_PTE; 01931 01932 01933 // 01934 // Invalid Page Table Entries have the following definitions. 01935 // 01936 01937 typedef struct _MMPTE_TRANSITION { 01938 ULONG Prototype : 1; 01939 ULONG Transition : 1; 01940 ULONG Valid : 1; 01941 ULONG Protection : 5; 01942 ULONG filler4 : 4; 01943 ULONG PageFrameNumber : 20; 01944 } MMPTE_TRANSITION; 01945 01946 typedef struct _MMPTE_SOFTWARE { 01947 ULONG Prototype : 1; 01948 ULONG Transition : 1; 01949 ULONG Valid : 1; 01950 ULONG Protection : 5; 01951 ULONG PageFileLow : 4; 01952 ULONG PageFileHigh : 20; 01953 } MMPTE_SOFTWARE; 01954 01955 typedef struct _MMPTE_PROTOTYPE { 01956 ULONG Prototype : 1; 01957 ULONG filler1 : 1; 01958 ULONG Valid : 1; 01959 ULONG ReadOnly : 1; 01960 ULONG ProtoAddressLow : 8; 01961 ULONG ProtoAddressHigh : 20; 01962 } MMPTE_PROTOTYPE; 01963 01964 typedef struct _MMPTE_SUBSECTION { 01965 ULONG Prototype : 1; 01966 ULONG SubsectionAddressLow : 1; 01967 ULONG Valid : 1; 01968 ULONG Protection : 5; 01969 ULONG SubsectionAddressHigh : 24; 01970 } MMPTE_SUBSECTION; 01971 01972 typedef struct _MMPTE_LIST { 01973 ULONG filler2 : 2; 01974 ULONG Valid : 1; 01975 ULONG OneEntry : 1; 01976 ULONG filler8 : 8; 01977 ULONG NextEntry : 20; 01978 } MMPTE_LIST; 01979 01980 01981 // 01982 // A Page Table Entry has the following definition. 01983 // 01984 01985 typedef struct _MMPTE { 01986 union { 01987 ULONG Long; 01988 HARDWARE_PTE Hard; 01989 HARDWARE_PTE Flush; 01990 MMPTE_TRANSITION Trans; 01991 MMPTE_SOFTWARE Soft; 01992 MMPTE_PROTOTYPE Proto; 01993 MMPTE_SUBSECTION Subsect; 01994 MMPTE_LIST List; 01995 } u; 01996 } MMPTE; 01997 01998 typedef MMPTE *PMMPTE; 01999