Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mipae.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 mipae.h 00008 00009 Abstract: 00010 00011 This module contains the private data structures and procedure 00012 prototypes for the hardware dependent portion of the 00013 memory management system. 00014 00015 This module is specifically tailored for the Intel PAE x86, 00016 00017 Author: 00018 00019 Landy Wang (landyw) 30-Nov-1998 00020 00021 Revision History: 00022 00023 --*/ 00024 00025 #if defined(_X86PAE_) 00026 00027 /*++ 00028 00029 Virtual Memory Layout on the PAE x86 is: 00030 00031 +------------------------------------+ 00032 00000000 | | 00033 | | 00034 | | 00035 | User Mode Addresses | 00036 | | 00037 | All pages within this range | 00038 | are potentially accessible while | 00039 | the CPU is in USER mode. | 00040 | | 00041 | | 00042 +------------------------------------+ 00043 7ffff000 | 64k No Access Area | 00044 +------------------------------------+ 00045 80000000 | | 00046 | HAL loads kernel and initial | 00047 | boot drivers in first 16mb | 00048 | of this region. | 00049 | Kernel mode access only. | 00050 | | 00051 | If large pages are enabled, the | 00052 | initial non paged pool is relocated| 00053 | to here during system startup. | 00054 | | 00055 +------------------------------------+ 00056 81000000 | | 00057 | Unused NO ACCESS | 00058 | | 00059 +------------------------------------+ 00060 A0000000 | | 00061 | System mapped views | 00062 | OR | 00063 | Session space | 00064 | | 00065 +------------------------------------+ 00066 A4000000 | | 00067 | Additional System PTEs | 00068 | | 00069 +------------------------------------+ 00070 C0000000 | Page Table Pages mapped through | 00071 | this 8mb region | 00072 | Kernel mode access only. | 00073 | | 00074 +------------------------------------+ 00075 C0800000 | HyperSpace - working set lists | 00076 | and per process memory management | 00077 | structures mapped in this 4mb | 00078 | region. | 00079 | Kernel mode access only. | 00080 +------------------------------------+ 00081 C0C00000 | System Cache Structures | 00082 | reside in this 4mb region | 00083 | Kernel mode access only. | 00084 +------------------------------------+ 00085 C1000000 | System cache resides here. | 00086 | Kernel mode access only. | 00087 | | 00088 | | 00089 +------------------------------------+ 00090 E1000000 | Start of paged system area | 00091 | Kernel mode access only. | 00092 | | 00093 | | 00094 +------------------------------------+ 00095 | | 00096 | System Pte area - for mapping | 00097 | kernel thread stacks and MDLs | 00098 | that require system VAs. | 00099 | Kernel mode access only. | 00100 | | 00101 +------------------------------------+ 00102 | | 00103 | NonPaged System area | 00104 | Kernel mode access only. | 00105 | | 00106 +------------------------------------+ 00107 FFBE0000 | Crash Dump Driver area | 00108 | Kernel mode access only. | 00109 +------------------------------------+ 00110 FFC00000 | Last 4mb reserved for HAL usage | 00111 +------------------------------------+ 00112 00113 00114 Virtual Memory Layout of the (48MB) Session Space (on 2GB user systems) is: 00115 00116 +------------------------------------+ 00117 A0000000 | | 00118 | win32k.sys and rebased NT4 printer | 00119 | drivers. | 00120 | | 00121 | (8MB) | 00122 | | 00123 +------------------------------------+ 00124 A0800000 | | 00125 | MM_SESSION_SPACE & Session WSLs | 00126 | (4MB) | 00127 | | 00128 +------------------------------------+ 00129 A0C00000 | | 00130 | Mapped Views for this session | 00131 | (20MB) | 00132 | | 00133 +------------------------------------+ 00134 A2000000 | | 00135 | Paged Pool for this session | 00136 | (16MB) | 00137 | | 00138 A3000000 +------------------------------------+ 00139 | System Mapped Views (not session)| 00140 | (16MB) | 00141 | | 00142 A4000000 +------------------------------------+ 00143 00144 --*/ 00145 00146 #if defined(NT_UP) 00147 #define _MI_USE_CLAIMS_ 1 00148 #endif 00149 00150 // 00151 // Define empty list markers. 00152 // 00153 00154 #define MM_EMPTY_LIST ((ULONG)0xFFFFFFFF) // 00155 #define MM_EMPTY_PTE_LIST ((ULONG)0xFFFFFFFF) // N.B. tied to MMPTE definition 00156 00157 #define MI_PTE_BASE_FOR_LOWEST_KERNEL_ADDRESS (MiGetPteAddress (0x80000000)) 00158 00159 #define MM_SESSION_SPACE_DEFAULT (0xA0000000) 00160 00161 #define MM_BOOT_IMAGE_SIZE (16 * 1024 * 1024) 00162 00163 // 00164 // Additional system PTEs are allocated out of this virtual address range. 00165 // 00166 00167 #define KSTACK_POOL_START (0xA4000000) 00168 00169 #define KSTACK_POOL_END (0xBFFFFFFF) 00170 00171 #define KSTACK_POOL_SIZE ((KSTACK_POOL_END-KSTACK_POOL_START) \ 00172 & ~(PAGE_SIZE-1)) 00173 00174 extern ULONG MiNumberOfExtraSystemPdes; 00175 00176 extern ULONG MiMaximumSystemCacheSizeExtra; 00177 00178 extern PVOID MiSystemCacheStartExtra; 00179 00180 extern PVOID MiSystemCacheEndExtra; 00181 00182 // 00183 // PAGE_SIZE for Intel x86 is 4k, virtual page is 20 bits with a PAGE_SHIFT 00184 // byte offset. 00185 // 00186 00187 #define MM_VIRTUAL_PAGE_FILLER 0 00188 #define MM_VIRTUAL_PAGE_SIZE 20 00189 00190 // 00191 // Address space layout definitions. 00192 // 00193 00194 #define MM_KSEG0_BASE ((ULONG)0x80000000) 00195 00196 #define MM_KSEG2_BASE ((ULONG)0xA0000000) 00197 00198 #define MM_PAGES_IN_KSEG0 ((MM_KSEG2_BASE - MM_KSEG0_BASE) >> PAGE_SHIFT) 00199 00200 extern ULONG MmKseg2Frame; 00201 00202 #define CODE_START MM_KSEG0_BASE 00203 00204 #define CODE_END MM_KSEG2_BASE 00205 00206 #define MM_SYSTEM_SPACE_START (0xC0C00000) 00207 00208 #define MM_SYSTEM_SPACE_END (0xFFFFFFFF) 00209 00210 #define PDE_TOP 0xC0603FFF 00211 00212 #define PTE_TOP 0xC07FFFFF 00213 00214 #define HYPER_SPACE ((PVOID)0xC0800000) 00215 00216 #define HYPER_SPACE2 ((PVOID)0xC0A00000) 00217 00218 #define HYPER_SPACE_END (0xC0BFFFFF) 00219 00220 #define MM_SYSTEM_VIEW_START (0xA0000000) 00221 00222 #define MM_SYSTEM_VIEW_SIZE (48*1024*1024) 00223 00224 #define MM_SYSTEM_VIEW_START_IF_HYDRA (0xA3000000) 00225 00226 #define MM_SYSTEM_VIEW_SIZE_IF_HYDRA (16*1024*1024) 00227 00228 #define MM_USER_ADDRESS_RANGE_LIMIT 0xFFFFFFFF // user address range limit 00229 #define MM_MAXIMUM_ZERO_BITS 21 // maximum number of zero bits 00230 00231 // 00232 // Define the start and maximum size for the system cache. 00233 // Maximum size is normally 512MB, but can be up to 512MB + 448MB = 960MB for 00234 // large system cache machines. 00235 // 00236 00237 #define MM_SYSTEM_CACHE_WORKING_SET (0xC0C00000) 00238 00239 #define MM_SYSTEM_CACHE_START (0xC1000000) 00240 00241 #define MM_SYSTEM_CACHE_END (0xE1000000) 00242 00243 #define MM_SYSTEM_CACHE_START_EXTRA (0xA4000000) 00244 00245 #define MM_SYSTEM_CACHE_END_EXTRA (0xC0000000) 00246 00247 #define MM_PAGED_POOL_START ((PVOID)(0xE1000000)) 00248 00249 #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(0xEB000000)) 00250 00251 #define MmProtopte_Base ((ULONG)0xE1000000) 00252 00253 #define MM_NONPAGED_POOL_END ((PVOID)(0xFFBE0000)) 00254 00255 #define MM_CRASH_DUMP_VA ((PVOID)(0xFFBE0000)) 00256 00257 #define MM_DEBUG_VA ((PVOID)0xFFBFF000) 00258 00259 #define NON_PAGED_SYSTEM_END ((ULONG)0xFFFFFFF0) //quadword aligned. 00260 00261 extern BOOLEAN MiWriteCombiningPtes; 00262 00263 // 00264 // Define absolute minimum and maximum count for system PTEs. 00265 // 00266 00267 #define MM_MINIMUM_SYSTEM_PTES 7000 00268 00269 #define MM_MAXIMUM_SYSTEM_PTES 50000 00270 00271 #define MM_DEFAULT_SYSTEM_PTES 11000 00272 00273 // 00274 // Pool limits 00275 // 00276 00277 // 00278 // The maximum amount of nonpaged pool that can be initially created. 00279 // 00280 00281 #define MM_MAX_INITIAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) 00282 00283 // 00284 // The total amount of nonpaged pool (initial pool + expansion). 00285 // 00286 00287 #define MM_MAX_ADDITIONAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) 00288 00289 // 00290 // The maximum amount of paged pool that can be created. 00291 // 00292 00293 #define MM_MAX_PAGED_POOL ((ULONG)MM_NONPAGED_POOL_END - (ULONG)MM_PAGED_POOL_START) 00294 00295 #define MM_MAX_TOTAL_POOL (((ULONG)MM_NONPAGED_POOL_END) - ((ULONG)(MM_PAGED_POOL_START))) 00296 00297 00298 // 00299 // Structure layout definitions. 00300 // 00301 00302 #define MM_PROTO_PTE_ALIGNMENT ((ULONG)PAGE_SIZE) 00303 00304 #define PAGE_DIRECTORY_MASK ((ULONG)0x001FFFFF) 00305 00306 #define MM_VA_MAPPED_BY_PDE (0x200000) 00307 00308 #define LOWEST_IO_ADDRESS 0xa0000 00309 00310 #define PTE_SHIFT 3 00311 00312 // 00313 // The number of bits in a physical address. 00314 // 00315 00316 #define PHYSICAL_ADDRESS_BITS 36 00317 00318 #define MM_MAXIMUM_NUMBER_OF_COLORS (1) 00319 00320 // 00321 // x86 does not require support for colored pages. 00322 // 00323 00324 #define MM_NUMBER_OF_COLORS (1) 00325 00326 // 00327 // Mask for obtaining color from a physical page number. 00328 // 00329 00330 #define MM_COLOR_MASK (0) 00331 00332 // 00333 // Boundary for aligned pages of like color upon. 00334 // 00335 00336 #define MM_COLOR_ALIGNMENT (0) 00337 00338 // 00339 // Mask for isolating color from virtual address. 00340 // 00341 00342 #define MM_COLOR_MASK_VIRTUAL (0) 00343 00344 // 00345 // Define 256k worth of secondary colors. 00346 // 00347 00348 #define MM_SECONDARY_COLORS_DEFAULT (64) 00349 00350 #define MM_SECONDARY_COLORS_MIN (2) 00351 00352 #define MM_SECONDARY_COLORS_MAX (1024) 00353 00354 // 00355 // Mask for isolating secondary color from physical page number; 00356 // 00357 00358 extern ULONG MmSecondaryColorMask; 00359 00360 // 00361 // Maximum number of paging files. 00362 // 00363 00364 #define MAX_PAGE_FILES 16 00365 00366 00367 // 00368 // Hyper space definitions. 00369 // 00370 00371 #define FIRST_MAPPING_PTE ((ULONG)0xC0801000) 00372 00373 #define NUMBER_OF_MAPPING_PTES 126 00374 #define LAST_MAPPING_PTE \ 00375 ((ULONG)((ULONG)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE))) 00376 00377 #define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG)LAST_MAPPING_PTE + PAGE_SIZE)) 00378 00379 #define ZEROING_PAGE_PTE ((PMMPTE)((ULONG)IMAGE_MAPPING_PTE + PAGE_SIZE)) 00380 00381 #define WORKING_SET_LIST ((PVOID)((ULONG)ZEROING_PAGE_PTE + PAGE_SIZE)) 00382 00383 #define MM_MAXIMUM_WORKING_SET MiMaximumWorkingSet 00384 00385 extern ULONG MiMaximumWorkingSet; 00386 00387 00388 #define MM_WORKING_SET_END ((ULONG)0xC0BFF000) 00389 00390 00391 // 00392 // Define masks for fields within the PTE. 00394 00395 #define MM_PTE_VALID_MASK 0x1 00396 #if defined(NT_UP) 00397 #define MM_PTE_WRITE_MASK 0x2 00398 #else 00399 #define MM_PTE_WRITE_MASK 0x800 00400 #endif 00401 #define MM_PTE_OWNER_MASK 0x4 00402 #define MM_PTE_WRITE_THROUGH_MASK 0x8 00403 #define MM_PTE_CACHE_DISABLE_MASK 0x10 00404 #define MM_PTE_ACCESS_MASK 0x20 00405 #if defined(NT_UP) 00406 #define MM_PTE_DIRTY_MASK 0x40 00407 #else 00408 #define MM_PTE_DIRTY_MASK 0x42 00409 #endif 00410 #define MM_PTE_LARGE_PAGE_MASK 0x80 00411 #define MM_PTE_GLOBAL_MASK 0x100 00412 #define MM_PTE_COPY_ON_WRITE_MASK 0x200 00413 #define MM_PTE_PROTOTYPE_MASK 0x400 00414 #define MM_PTE_TRANSITION_MASK 0x800 00415 00416 // 00417 // Bit fields to or into PTE to make a PTE valid based on the 00418 // protection field of the invalid PTE. 00419 // 00420 00421 #define MM_PTE_NOACCESS 0x0 // not expressable on x86 00422 #define MM_PTE_READONLY 0x0 00423 #define MM_PTE_READWRITE MM_PTE_WRITE_MASK 00424 #define MM_PTE_WRITECOPY 0x200 // read-only copy on write bit set. 00425 #define MM_PTE_EXECUTE 0x0 // read-only on x86 00426 #define MM_PTE_EXECUTE_READ 0x0 00427 #define MM_PTE_EXECUTE_READWRITE MM_PTE_WRITE_MASK 00428 #define MM_PTE_EXECUTE_WRITECOPY 0x200 // read-only copy on write bit set. 00429 #define MM_PTE_NOCACHE 0x010 00430 #define MM_PTE_GUARD 0x0 // not expressable on x86 00431 #define MM_PTE_CACHE 0x0 00432 00433 #define MM_PROTECT_FIELD_SHIFT 5 00434 00435 // 00436 // Bits available for the software working set index within the hardware PTE. 00437 // 00438 00439 #define MI_MAXIMUM_PTE_WORKING_SET_INDEX 0 00440 00441 // 00442 // Zero PTE 00443 // 00444 00445 #define MM_ZERO_PTE 0 00446 00447 // 00448 // Zero Kernel PTE 00449 // 00450 00451 #define MM_ZERO_KERNEL_PTE 0 00452 00453 // 00454 // A demand zero PTE with a protection of PAGE_READWRITE. 00455 // 00456 00457 #define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00458 00459 00460 // 00461 // A demand zero PTE with a protection of PAGE_READWRITE for system space. 00462 // 00463 00464 #define MM_KERNEL_DEMAND_ZERO_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00465 00466 // 00467 // A no access PTE for system space. 00468 // 00469 00470 #define MM_KERNEL_NOACCESS_PTE (MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) 00471 00472 // 00473 // Kernel stack alignment requirements. 00474 // 00475 00476 #define MM_STACK_ALIGNMENT 0x0 00477 00478 #define MM_STACK_OFFSET 0x0 00479 00480 // 00481 // System process definitions 00482 // 00483 00484 #define PDE_PER_PAGE ((ULONG)512) 00485 00486 #define PTE_PER_PAGE ((ULONG)512) 00487 00488 #define PD_PER_SYSTEM ((ULONG)4) 00489 00490 // 00491 // Number of page table pages for user addresses. 00492 // 00493 00494 #define MM_USER_PAGE_TABLE_PAGES (1536) 00495 00496 VOID 00497 MiPaeInitialize ( 00498 VOID 00499 ); 00500 00501 //++ 00502 //VOID 00503 //MI_MAKE_VALID_PTE ( 00504 // OUT OUTPTE, 00505 // IN FRAME, 00506 // IN PMASK, 00507 // IN PPTE 00508 // ); 00509 // 00510 // Routine Description: 00511 // 00512 // This macro makes a valid PTE from a page frame number, protection mask, 00513 // and owner. 00514 // 00515 // Arguments 00516 // 00517 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00518 // 00519 // FRAME - Supplies the page frame number for the PTE. 00520 // 00521 // PMASK - Supplies the protection to set in the transition PTE. 00522 // 00523 // PPTE - Supplies a pointer to the PTE which is being made valid. 00524 // For prototype PTEs NULL should be specified. 00525 // 00526 // Return Value: 00527 // 00528 // None. 00529 // 00530 //-- 00531 00532 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 00533 (OUTPTE).u.Long = (((ULONGLONG)FRAME << 12) | \ 00534 (MmProtectToPteMask[PMASK]) | \ 00535 MiDetermineUserGlobalPteMask ((PMMPTE)PPTE)); 00536 00537 //++ 00538 //VOID 00539 //MI_MAKE_VALID_PTE_TRANSITION ( 00540 // IN OUT OUTPTE 00541 // IN PROTECT 00542 // ); 00543 // 00544 // Routine Description: 00545 // 00546 // This macro takes a valid pte and turns it into a transition PTE. 00547 // 00548 // Arguments 00549 // 00550 // OUTPTE - Supplies the current valid PTE. This PTE is then 00551 // modified to become a transition PTE. 00552 // 00553 // PROTECT - Supplies the protection to set in the transition PTE. 00554 // 00555 // Return Value: 00556 // 00557 // None. 00558 // 00559 //-- 00560 00561 #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \ 00562 (OUTPTE).u.Soft.Transition = 1; \ 00563 (OUTPTE).u.Soft.Valid = 0; \ 00564 (OUTPTE).u.Soft.Prototype = 0; \ 00565 (OUTPTE).u.Soft.Protection = PROTECT; 00566 00567 //++ 00568 //VOID 00569 //MI_MAKE_TRANSITION_PTE ( 00570 // OUT OUTPTE, 00571 // IN PAGE, 00572 // IN PROTECT, 00573 // IN PPTE 00574 // ); 00575 // 00576 // Routine Description: 00577 // 00578 // This macro takes a valid pte and turns it into a transition PTE. 00579 // 00580 // Arguments 00581 // 00582 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00583 // 00584 // PAGE - Supplies the page frame number for the PTE. 00585 // 00586 // PROTECT - Supplies the protection to set in the transition PTE. 00587 // 00588 // PPTE - Supplies a pointer to the PTE, this is used to determine 00589 // the owner of the PTE. 00590 // 00591 // Return Value: 00592 // 00593 // None. 00594 // 00595 //-- 00596 00597 #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \ 00598 (OUTPTE).u.Long = 0; \ 00599 (OUTPTE).u.Trans.PageFrameNumber = PAGE; \ 00600 (OUTPTE).u.Trans.Transition = 1; \ 00601 (OUTPTE).u.Trans.Protection = PROTECT; \ 00602 (OUTPTE).u.Trans.Owner = MI_DETERMINE_OWNER(PPTE); 00603 00604 00605 //++ 00606 //VOID 00607 //MI_MAKE_TRANSITION_PTE_VALID ( 00608 // OUT OUTPTE, 00609 // IN PPTE 00610 // ); 00611 // 00612 // Routine Description: 00613 // 00614 // This macro takes a transition pte and makes it a valid PTE. 00615 // 00616 // Arguments 00617 // 00618 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00619 // 00620 // PPTE - Supplies a pointer to the transition PTE. 00621 // 00622 // Return Value: 00623 // 00624 // None. 00625 // 00626 //-- 00627 00628 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 00629 ASSERT (((PPTE)->u.Hard.Valid == 0) && \ 00630 ((PPTE)->u.Trans.Prototype == 0) && \ 00631 ((PPTE)->u.Trans.Transition == 1)); \ 00632 (OUTPTE).u.Long = (((PPTE)->u.Long & ~0xFFF) | \ 00633 (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) | \ 00634 MiDetermineUserGlobalPteMask ((PMMPTE)PPTE)); 00635 00636 //++ 00637 //VOID 00638 //MI_SET_PTE_IN_WORKING_SET ( 00639 // OUT PMMPTE PTE, 00640 // IN ULONG WSINDEX 00641 // ); 00642 // 00643 // Routine Description: 00644 // 00645 // This macro inserts the specified working set index into the argument PTE. 00646 // Since the x86 PTE has no free bits in the valid PTE, nothing needs to 00647 // be done on this architecture. 00648 // 00649 // Arguments 00650 // 00651 // OUTPTE - Supplies the PTE in which to insert the working set index. 00652 // 00653 // WSINDEX - Supplies the working set index for the PTE. 00654 // 00655 // Return Value: 00656 // 00657 // None. 00658 // 00659 //-- 00660 00661 #define MI_SET_PTE_IN_WORKING_SET(PTE, WSINDEX) 00662 00663 //++ 00664 //ULONG WsIndex 00665 //MI_GET_WORKING_SET_FROM_PTE( 00666 // IN PMMPTE PTE 00667 // ); 00668 // 00669 // Routine Description: 00670 // 00671 // This macro returns the working set index from the argument PTE. 00672 // Since the x86 PTE has no free bits in the valid PTE, nothing needs to 00673 // be done on this architecture. 00674 // 00675 // Arguments 00676 // 00677 // PTE - Supplies the PTE to extract the working set index from. 00678 // 00679 // Return Value: 00680 // 00681 // This macro returns the working set index for the argument PTE. 00682 // 00683 //-- 00684 00685 #define MI_GET_WORKING_SET_FROM_PTE(PTE) 0 00686 00687 //++ 00688 //VOID 00689 //MI_SET_PTE_WRITE_COMBINE ( 00690 // IN MMPTE PTE 00691 // ); 00692 // 00693 // Routine Description: 00694 // 00695 // This macro takes a valid PTE and enables WriteCombining as the 00696 // caching state. Note that the PTE bits may only be set this way 00697 // if the Page Attribute Table is present and the PAT has been 00698 // initialized to provide Write Combining. 00699 // 00700 // If either of the above conditions is not satisfied, then 00701 // the macro enables WEAK UC (PCD = 1, PWT = 0) in the PTE. 00702 // 00703 // Arguments 00704 // 00705 // PTE - Supplies a valid PTE. 00706 // 00707 // Return Value: 00708 // 00709 // None. 00710 // 00711 //-- 00712 // 00713 00714 #define MI_SET_PTE_WRITE_COMBINE(PTE) \ 00715 { \ 00716 if (MiWriteCombiningPtes == TRUE) { \ 00717 ((PTE).u.Hard.CacheDisable = 0); \ 00718 ((PTE).u.Hard.WriteThrough = 1); \ 00719 } else { \ 00720 ((PTE).u.Hard.CacheDisable = 1); \ 00721 ((PTE).u.Hard.WriteThrough = 0); \ 00722 } \ 00723 } 00724 00725 //++ 00726 //VOID 00727 //MI_SET_PTE_DIRTY ( 00728 // IN MMPTE PTE 00729 // ); 00730 // 00731 // Routine Description: 00732 // 00733 // This macro sets the dirty bit(s) in the specified PTE. 00734 // 00735 // Arguments 00736 // 00737 // PTE - Supplies the PTE to set dirty. 00738 // 00739 // Return Value: 00740 // 00741 // None. 00742 // 00743 //-- 00744 00745 #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Long |= HARDWARE_PTE_DIRTY_MASK 00746 00747 00748 //++ 00749 //VOID 00750 //MI_SET_PTE_CLEAN ( 00751 // IN MMPTE PTE 00752 // ); 00753 // 00754 // Routine Description: 00755 // 00756 // This macro clears the dirty bit(s) in the specified PTE. 00757 // 00758 // Arguments 00759 // 00760 // PTE - Supplies the PTE to set clear. 00761 // 00762 // Return Value: 00763 // 00764 // None. 00765 // 00766 //-- 00767 00768 #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Long &= ~HARDWARE_PTE_DIRTY_MASK 00769 00770 00771 00772 //++ 00773 //VOID 00774 //MI_IS_PTE_DIRTY ( 00775 // IN MMPTE PTE 00776 // ); 00777 // 00778 // Routine Description: 00779 // 00780 // This macro checks the dirty bit(s) in the specified PTE. 00781 // 00782 // Arguments 00783 // 00784 // PTE - Supplies the PTE to check. 00785 // 00786 // Return Value: 00787 // 00788 // TRUE if the page is dirty (modified), FALSE otherwise. 00789 // 00790 //-- 00791 00792 #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) 00793 00794 00795 00796 //++ 00797 //VOID 00798 //MI_SET_GLOBAL_BIT_IF_SYSTEM ( 00799 // OUT OUTPTE, 00800 // IN PPTE 00801 // ); 00802 // 00803 // Routine Description: 00804 // 00805 // This macro sets the global bit if the pointer PTE is within 00806 // system space. 00807 // 00808 // Arguments 00809 // 00810 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00811 // 00812 // PPTE - Supplies a pointer to the PTE becoming valid. 00813 // 00814 // Return Value: 00815 // 00816 // None. 00817 // 00818 //-- 00819 00820 #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE) \ 00821 if ((((PMMPTE)PPTE) > MiHighestUserPte) && \ 00822 ((((PMMPTE)PPTE) <= MiGetPteAddress (PTE_BASE)) || \ 00823 (((PMMPTE)PPTE) >= MiGetPteAddress (MM_SYSTEM_CACHE_WORKING_SET)))) { \ 00824 (OUTPTE).u.Long |= MmPteGlobal.u.Long; \ 00825 } \ 00826 else { \ 00827 (OUTPTE).u.Long &= ~MmPteGlobal.u.Long; \ 00828 } 00829 00830 00831 //++ 00832 //VOID 00833 //MI_SET_GLOBAL_STATE ( 00834 // IN MMPTE PTE, 00835 // IN ULONG STATE 00836 // ); 00837 // 00838 // Routine Description: 00839 // 00840 // This macro sets the global bit in the PTE based on the state argument. 00841 // 00842 // Arguments 00843 // 00844 // PTE - Supplies the PTE to set global state into. 00845 // 00846 // STATE - Supplies 1 if global, 0 if not. 00847 // 00848 // Return Value: 00849 // 00850 // None. 00851 // 00852 //-- 00853 00854 #define MI_SET_GLOBAL_STATE(PTE,STATE) \ 00855 if (STATE) { \ 00856 (PTE).u.Long |= MmPteGlobal.u.Long; \ 00857 } \ 00858 else { \ 00859 (PTE).u.Long &= ~MmPteGlobal.u.Long; \ 00860 } 00861 00862 00863 00864 00865 00866 //++ 00867 //VOID 00868 //MI_ENABLE_CACHING ( 00869 // IN MMPTE PTE 00870 // ); 00871 // 00872 // Routine Description: 00873 // 00874 // This macro takes a valid PTE and sets the caching state to be 00875 // enabled. This is performed by clearing the PCD and PWT bits in the PTE. 00876 // 00877 // Semantics of the overlap between PCD, PWT, and the 00878 // USWC memory type in the MTRR are: 00879 // 00880 // PCD PWT Mtrr Mem Type Effective Memory Type 00881 // 1 0 USWC USWC 00882 // 1 1 USWC UC 00883 // 00884 // Arguments 00885 // 00886 // PTE - Supplies a valid PTE. 00887 // 00888 // Return Value: 00889 // 00890 // None. 00891 // 00892 //-- 00893 00894 #define MI_ENABLE_CACHING(PTE) \ 00895 { \ 00896 ((PTE).u.Hard.CacheDisable = 0); \ 00897 ((PTE).u.Hard.WriteThrough = 0); \ 00898 } 00899 00900 00901 00902 //++ 00903 //VOID 00904 //MI_DISABLE_CACHING ( 00905 // IN MMPTE PTE 00906 // ); 00907 // 00908 // Routine Description: 00909 // 00910 // This macro takes a valid PTE and sets the caching state to be 00911 // disabled. This is performed by setting the PCD and PWT bits in the PTE. 00912 // 00913 // Semantics of the overlap between PCD, PWT, and the 00914 // USWC memory type in the MTRR are: 00915 // 00916 // PCD PWT Mtrr Mem Type Effective Memory Type 00917 // 1 0 USWC USWC 00918 // 1 1 USWC UC 00919 // 00920 // Since an effective memory type of UC is desired here, 00921 // the WT bit is set. 00922 // 00923 // Arguments 00924 // 00925 // PTE - Supplies a pointer to the valid PTE. 00926 // 00927 // Return Value: 00928 // 00929 // None. 00930 // 00931 //-- 00932 00933 00934 #define MI_DISABLE_CACHING(PTE) \ 00935 { \ 00936 ((PTE).u.Hard.CacheDisable = 1); \ 00937 ((PTE).u.Hard.WriteThrough = 1); \ 00938 } 00939 00940 00941 00942 00943 //++ 00944 //BOOLEAN 00945 //MI_IS_CACHING_DISABLED ( 00946 // IN PMMPTE PPTE 00947 // ); 00948 // 00949 // Routine Description: 00950 // 00951 // This macro takes a valid PTE and returns TRUE if caching is 00952 // disabled. 00953 // 00954 // Arguments 00955 // 00956 // PPTE - Supplies a pointer to the valid PTE. 00957 // 00958 // Return Value: 00959 // 00960 // TRUE if caching is disabled, FALSE if it is enabled. 00961 // 00962 //-- 00963 00964 #define MI_IS_CACHING_DISABLED(PPTE) \ 00965 ((PPTE)->u.Hard.CacheDisable == 1) 00966 00967 00968 00969 //++ 00970 //VOID 00971 //MI_SET_PFN_DELETED ( 00972 // IN PMMPFN PPFN 00973 // ); 00974 // 00975 // Routine Description: 00976 // 00977 // This macro takes a pointer to a PFN element and indicates that 00978 // the PFN is no longer in use. 00979 // 00980 // Arguments 00981 // 00982 // PPFN - Supplies a pointer to the PFN element. 00983 // 00984 // Return Value: 00985 // 00986 // none. 00987 // 00988 //-- 00989 00990 #define MI_SET_PFN_DELETED(PPFN) \ 00991 PERFINFO_DELETE_PAGE(PPFN); \ 00992 PPFN->PteAddress = (PMMPTE)-1; 00993 00994 00995 00996 00997 //++ 00998 //BOOLEAN 00999 //MI_IS_PFN_DELETED ( 01000 // IN PMMPFN PPFN 01001 // ); 01002 // 01003 // Routine Description: 01004 // 01005 // This macro takes a pointer to a PFN element and determines if 01006 // the PFN is no longer in use. 01007 // 01008 // Arguments 01009 // 01010 // PPTE - Supplies a pointer to the PFN element. 01011 // 01012 // Return Value: 01013 // 01014 // TRUE if PFN is no longer used, FALSE if it is still being used. 01015 // 01016 //-- 01017 01018 #define MI_IS_PFN_DELETED(PPFN) \ 01019 ((PPFN)->PteAddress == (PMMPTE)-1) 01020 01021 01022 //++ 01023 //VOID 01024 //MI_CHECK_PAGE_ALIGNMENT ( 01025 // IN ULONG PAGE, 01026 // IN PMMPTE PPTE 01027 // ); 01028 // 01029 // Routine Description: 01030 // 01031 // This macro takes a PFN element number (Page) and checks to see 01032 // if the virtual alignment for the previous address of the page 01033 // is compatible with the new address of the page. If they are 01034 // not compatible, the D cache is flushed. 01035 // 01036 // Arguments 01037 // 01038 // PAGE - Supplies the PFN element. 01039 // PPTE - Supplies a pointer to the new PTE which will contain the page. 01040 // 01041 // Return Value: 01042 // 01043 // none. 01044 // 01045 //-- 01046 01047 // does nothing on x86. 01048 01049 #define MI_CHECK_PAGE_ALIGNMENT(PAGE,PPTE) 01050 01051 01052 //++ 01053 //VOID 01054 //MI_INITIALIZE_HYPERSPACE_MAP ( 01055 // VOID 01056 // ); 01057 // 01058 // Routine Description: 01059 // 01060 // This macro initializes the PTEs reserved for double mapping within 01061 // hyperspace. 01062 // 01063 // Arguments 01064 // 01065 // None. 01066 // 01067 // Return Value: 01068 // 01069 // None. 01070 // 01071 //-- 01072 01073 // does nothing on x86. 01074 01075 #define MI_INITIALIZE_HYPERSPACE_MAP(INDEX) 01076 01077 01078 //++ 01079 //ULONG 01080 //MI_GET_PAGE_COLOR_FROM_PTE ( 01081 // IN PMMPTE PTEADDRESS 01082 // ); 01083 // 01084 // Routine Description: 01085 // 01086 // This macro determines the page's color based on the PTE address 01087 // that maps the page. 01088 // 01089 // Arguments 01090 // 01091 // PTEADDRESS - Supplies the PTE address the page is (or was) mapped at. 01092 // 01093 // Return Value: 01094 // 01095 // The page's color. 01096 // 01097 //-- 01098 01099 #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \ 01100 ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask)) 01101 01102 01103 01104 //++ 01105 //ULONG 01106 //MI_GET_PAGE_COLOR_FROM_VA ( 01107 // IN PVOID ADDRESS 01108 // ); 01109 // 01110 // Routine Description: 01111 // 01112 // This macro determines the page's color based on the PTE address 01113 // that maps the page. 01114 // 01115 // Arguments 01116 // 01117 // ADDRESS - Supplies the address the page is (or was) mapped at. 01118 // 01119 // Return Value: 01120 // 01121 // The page's color. 01122 // 01123 //-- 01124 01125 01126 #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \ 01127 ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask)) 01128 01129 //++ 01130 //ULONG 01131 //MI_GET_PAGE_COLOR_FROM_SESSION ( 01132 // IN PMM_SESSION_SPACE SessionSpace 01133 // ); 01134 // 01135 // Routine Description: 01136 // 01137 // This macro determines the page's color based on the PTE address 01138 // that maps the page. 01139 // 01140 // Arguments 01141 // 01142 // SessionSpace - Supplies the session space the page will be mapped into. 01143 // 01144 // Return Value: 01145 // 01146 // The page's color. 01147 // 01148 //-- 01149 01150 01151 #define MI_GET_PAGE_COLOR_FROM_SESSION(_SessionSpace) \ 01152 ((ULONG)((_SessionSpace->Color++) & MmSecondaryColorMask)) 01153 01154 01155 01156 //++ 01157 //ULONG 01158 //MI_PAGE_COLOR_PTE_PROCESS ( 01159 // IN PCHAR COLOR, 01160 // IN PMMPTE PTE 01161 // ); 01162 // 01163 // Routine Description: 01164 // 01165 // This macro determines the page's color based on the PTE address 01166 // that maps the page. 01167 // 01168 // Arguments 01169 // 01170 // 01171 // Return Value: 01172 // 01173 // The page's color. 01174 // 01175 //-- 01176 01177 01178 #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \ 01179 ((ULONG)((*(COLOR))++) & MmSecondaryColorMask) 01180 01181 01182 //++ 01183 //ULONG 01184 //MI_PAGE_COLOR_VA_PROCESS ( 01185 // IN PVOID ADDRESS, 01186 // IN PEPROCESS COLOR 01187 // ); 01188 // 01189 // Routine Description: 01190 // 01191 // This macro determines the page's color based on the PTE address 01192 // that maps the page. 01193 // 01194 // Arguments 01195 // 01196 // ADDRESS - Supplies the address the page is (or was) mapped at. 01197 // 01198 // Return Value: 01199 // 01200 // The page's color. 01201 // 01202 //-- 01203 01204 #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \ 01205 ((ULONG)((*(COLOR))++) & MmSecondaryColorMask) 01206 01207 01208 01209 //++ 01210 //ULONG 01211 //MI_GET_NEXT_COLOR ( 01212 // IN ULONG COLOR 01213 // ); 01214 // 01215 // Routine Description: 01216 // 01217 // This macro returns the next color in the sequence. 01218 // 01219 // Arguments 01220 // 01221 // COLOR - Supplies the color to return the next of. 01222 // 01223 // Return Value: 01224 // 01225 // Next color in sequence. 01226 // 01227 //-- 01228 01229 #define MI_GET_NEXT_COLOR(COLOR) ((COLOR + 1) & MM_COLOR_MASK) 01230 01231 01232 //++ 01233 //ULONG 01234 //MI_GET_PREVIOUS_COLOR ( 01235 // IN ULONG COLOR 01236 // ); 01237 // 01238 // Routine Description: 01239 // 01240 // This macro returns the previous color in the sequence. 01241 // 01242 // Arguments 01243 // 01244 // COLOR - Supplies the color to return the previous of. 01245 // 01246 // Return Value: 01247 // 01248 // Previous color in sequence. 01249 // 01250 //-- 01251 01252 #define MI_GET_PREVIOUS_COLOR(COLOR) (0) 01253 01254 01255 #define MI_GET_SECONDARY_COLOR(PAGE,PFN) (PAGE & MmSecondaryColorMask) 01256 01257 01258 #define MI_GET_COLOR_FROM_SECONDARY(SECONDARY_COLOR) (0) 01259 01260 01261 //++ 01262 //VOID 01263 //MI_GET_MODIFIED_PAGE_BY_COLOR ( 01264 // OUT ULONG PAGE, 01265 // IN ULONG COLOR 01266 // ); 01267 // 01268 // Routine Description: 01269 // 01270 // This macro returns the first page destined for a paging 01271 // file with the desired color. It does NOT remove the page 01272 // from its list. 01273 // 01274 // Arguments 01275 // 01276 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01277 // returned if there is no page of the specified color. 01278 // 01279 // COLOR - Supplies the color of page to locate. 01280 // 01281 // Return Value: 01282 // 01283 // none. 01284 // 01285 //-- 01286 01287 #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \ 01288 PAGE = MmModifiedPageListByColor[COLOR].Flink 01289 01290 01291 //++ 01292 //VOID 01293 //MI_GET_MODIFIED_PAGE_ANY_COLOR ( 01294 // OUT ULONG PAGE, 01295 // IN OUT ULONG COLOR 01296 // ); 01297 // 01298 // Routine Description: 01299 // 01300 // This macro returns the first page destined for a paging 01301 // file with the desired color. If not page of the desired 01302 // color exists, all colored lists are searched for a page. 01303 // It does NOT remove the page from its list. 01304 // 01305 // Arguments 01306 // 01307 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01308 // returned if there is no page of the specified color. 01309 // 01310 // COLOR - Supplies the color of page to locate and returns the 01311 // color of the page located. 01312 // 01313 // Return Value: 01314 // 01315 // none. 01316 // 01317 //-- 01318 01319 #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \ 01320 { \ 01321 if (MmTotalPagesForPagingFile == 0) { \ 01322 PAGE = MM_EMPTY_LIST; \ 01323 } else { \ 01324 PAGE = MmModifiedPageListByColor[COLOR].Flink; \ 01325 } \ 01326 } 01327 01328 01329 01330 //++ 01331 //VOID 01332 //MI_MAKE_VALID_PTE_WRITE_COPY ( 01333 // IN OUT PMMPTE PTE 01334 // ); 01335 // 01336 // Routine Description: 01337 // 01338 // This macro checks to see if the PTE indicates that the 01339 // page is writable and if so it clears the write bit and 01340 // sets the copy-on-write bit. 01341 // 01342 // Arguments 01343 // 01344 // PTE - Supplies the PTE to operate upon. 01345 // 01346 // Return Value: 01347 // 01348 // None. 01349 // 01350 //-- 01351 01352 #if defined(NT_UP) 01353 #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ 01354 if ((PPTE)->u.Hard.Write == 1) { \ 01355 (PPTE)->u.Hard.CopyOnWrite = 1; \ 01356 (PPTE)->u.Hard.Write = 0; \ 01357 } 01358 #else 01359 #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ 01360 if ((PPTE)->u.Hard.Write == 1) { \ 01361 (PPTE)->u.Hard.CopyOnWrite = 1; \ 01362 (PPTE)->u.Hard.Write = 0; \ 01363 (PPTE)->u.Hard.Writable = 0; \ 01364 } 01365 #endif 01366 01367 01368 01369 //++ 01370 //ULONG 01371 //MI_DETERMINE_OWNER ( 01372 // IN MMPTE PPTE 01373 // ); 01374 // 01375 // Routine Description: 01376 // 01377 // This macro examines the virtual address of the PTE and determines 01378 // if the PTE resides in system space or user space. 01379 // 01380 // Arguments 01381 // 01382 // PTE - Supplies the PTE to operate upon. 01383 // 01384 // Return Value: 01385 // 01386 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01387 // 01388 //-- 01389 01390 #define MI_DETERMINE_OWNER(PPTE) \ 01391 ((((PPTE) <= MiHighestUserPte) || \ 01392 ((PPTE) >= MiGetPdeAddress(NULL) && \ 01393 ((PPTE) <= MiHighestUserPde))) ? 1 : 0) 01394 01395 01396 01397 //++ 01398 //VOID 01399 //MI_SET_ACCESSED_IN_PTE ( 01400 // IN OUT MMPTE PPTE 01401 // ); 01402 // 01403 // Routine Description: 01404 // 01405 // This macro sets the ACCESSED field in the PTE. 01406 // 01407 // Arguments 01408 // 01409 // PTE - Supplies the PTE to operate upon. 01410 // 01411 // Return Value: 01412 // 01413 // None 01414 // 01415 //-- 01416 01417 #if defined(NT_UP) 01418 #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) \ 01419 ((PPTE)->u.Hard.Accessed = ACCESSED) 01420 #else 01421 01422 // 01423 // Don't do anything on MP systems. 01424 // 01425 01426 #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) 01427 #endif 01428 01429 01430 //++ 01431 //ULONG 01432 //MI_GET_ACCESSED_IN_PTE ( 01433 // IN OUT MMPTE PPTE 01434 // ); 01435 // 01436 // Routine Description: 01437 // 01438 // This macro returns the state of the ACCESSED field in the PTE. 01439 // 01440 // Arguments 01441 // 01442 // PTE - Supplies the PTE to operate upon. 01443 // 01444 // Return Value: 01445 // 01446 // The state of the ACCESSED field. 01447 // 01448 //-- 01449 01450 #if defined(NT_UP) 01451 #define MI_GET_ACCESSED_IN_PTE(PPTE) ((PPTE)->u.Hard.Accessed) 01452 #else 01453 #define MI_GET_ACCESSED_IN_PTE(PPTE) 0 01454 #endif 01455 01456 01457 //++ 01458 //VOID 01459 //MI_SET_OWNER_IN_PTE ( 01460 // IN PMMPTE PPTE 01461 // IN ULONG OWNER 01462 // ); 01463 // 01464 // Routine Description: 01465 // 01466 // This macro sets the owner field in the PTE. 01467 // 01468 // Arguments 01469 // 01470 // PTE - Supplies the PTE to operate upon. 01471 // 01472 // Return Value: 01473 // 01474 // None. 01475 // 01476 //-- 01477 01478 #define MI_SET_OWNER_IN_PTE(PPTE,OWNER) ((PPTE)->u.Hard.Owner = OWNER) 01479 01480 01481 01482 01483 //++ 01484 //ULONG 01485 //MI_GET_OWNER_IN_PTE ( 01486 // IN PMMPTE PPTE 01487 // ); 01488 // 01489 // Routine Description: 01490 // 01491 // This macro gets the owner field from the PTE. 01492 // 01493 // Arguments 01494 // 01495 // PTE - Supplies the PTE to operate upon. 01496 // 01497 // Return Value: 01498 // 01499 // The state of the OWNER field. 01500 // 01501 //-- 01502 01503 #define MI_GET_OWNER_IN_PTE(PPTE) ((PPTE)->u.Hard.Owner) 01504 01505 01506 // 01507 // bit mask to clear out fields in a PTE to or in paging file location. 01508 // 01509 01510 #define CLEAR_FOR_PAGE_FILE 0x000003E0 01511 01512 01513 //++ 01514 //VOID 01515 //MI_SET_PAGING_FILE_INFO ( 01516 // OUT MMPTE OUTPTE, 01517 // IN MMPTE PPTE, 01518 // IN ULONG FILEINFO, 01519 // IN ULONG OFFSET 01520 // ); 01521 // 01522 // Routine Description: 01523 // 01524 // This macro sets into the specified PTE the supplied information 01525 // to indicate where the backing store for the page is located. 01526 // 01527 // Arguments 01528 // 01529 // OUTPTE - Supplies the PTE in which to store the result. 01530 // 01531 // PTE - Supplies the PTE to operate upon. 01532 // 01533 // FILEINFO - Supplies the number of the paging file. 01534 // 01535 // OFFSET - Supplies the offset into the paging file. 01536 // 01537 // Return Value: 01538 // 01539 // None. 01540 // 01541 //-- 01542 01543 #define MI_SET_PAGING_FILE_INFO(OUTPTE,PPTE,FILEINFO,OFFSET) \ 01544 (OUTPTE).u.Long = (PPTE).u.Long; \ 01545 (OUTPTE).u.Long &= CLEAR_FOR_PAGE_FILE; \ 01546 (OUTPTE).u.Long |= (FILEINFO << 1); \ 01547 (OUTPTE).u.Soft.PageFileHigh = (OFFSET); 01548 01549 01550 //++ 01551 //PMMPTE 01552 //MiPteToProto ( 01553 // IN OUT MMPTE PPTE, 01554 // IN ULONG FILEINFO, 01555 // IN ULONG OFFSET 01556 // ); 01557 // 01558 // Routine Description: 01559 // 01560 // This macro returns the address of the corresponding prototype which 01561 // was encoded earlier into the supplied PTE. 01562 // 01563 // Arguments 01564 // 01565 // lpte - Supplies the PTE to operate upon. 01566 // 01567 // Return Value: 01568 // 01569 // Pointer to the prototype PTE that backs this PTE. 01570 // 01571 //-- 01572 01573 01574 #define MiPteToProto(lpte) \ 01575 ((PMMPTE)((lpte)->u.Proto.ProtoAddress)) 01576 01577 01578 //++ 01579 //MMPTE 01580 //MiProtoAddressForPte ( 01581 // IN PMMPTE proto_va 01582 // ); 01583 // 01584 // Routine Description: 01585 // 01586 // This macro sets into the specified PTE the supplied information 01587 // to indicate where the backing store for the page is located. 01588 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01589 // reference a prototype PTE. And set the protoPTE bit, 01590 // 01591 // N.B. This macro is dependent on the layout of the prototype PTE. 01592 // 01593 // Arguments 01594 // 01595 // proto_va - Supplies the address of the prototype PTE. 01596 // 01597 // Return Value: 01598 // 01599 // Mask to set into the PTE. 01600 // 01601 //-- 01602 01603 #define MiProtoAddressForPte(proto_va) \ 01604 (((ULONGLONG)proto_va << 32) | MM_PTE_PROTOTYPE_MASK) 01605 01606 01607 //++ 01608 //ULONG 01609 //MiProtoAddressForKernelPte ( 01610 // IN PMMPTE proto_va 01611 // ); 01612 // 01613 // Routine Description: 01614 // 01615 // This macro sets into the specified PTE the supplied information 01616 // to indicate where the backing store for the page is located. 01617 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01618 // reference a prototype PTE. And set the protoPTE bit, 01619 // MM_PTE_PROTOTYPE_MASK. 01620 // 01621 // This macro also sets any other information (such as global bits) 01622 // required for kernel mode PTEs. 01623 // 01624 // Arguments 01625 // 01626 // proto_va - Supplies the address of the prototype PTE. 01627 // 01628 // Return Value: 01629 // 01630 // Mask to set into the PTE. 01631 // 01632 //-- 01633 01634 // not different on x86. 01635 01636 #define MiProtoAddressForKernelPte(proto_va) MiProtoAddressForPte(proto_va) 01637 01638 01639 #define MM_SUBSECTION_MAP (128*1024*1024) 01640 01641 //++ 01642 //PSUBSECTION 01643 //MiGetSubsectionAddress ( 01644 // IN PMMPTE lpte 01645 // ); 01646 // 01647 // Routine Description: 01648 // 01649 // This macro takes a PTE and returns the address of the subsection that 01650 // the PTE refers to. Subsections are quadword structures allocated 01651 // from nonpaged pool. 01652 // 01653 // Arguments 01654 // 01655 // lpte - Supplies the PTE to operate upon. 01656 // 01657 // Return Value: 01658 // 01659 // A pointer to the subsection referred to by the supplied PTE. 01660 // 01661 //-- 01662 01663 #define MiGetSubsectionAddress(lpte) \ 01664 ((PSUBSECTION)((lpte)->u.Subsect.SubsectionAddress)) 01665 01666 01667 01668 //++ 01669 //ULONG 01670 //MiGetSubsectionAddressForPte ( 01671 // IN PSUBSECTION VA 01672 // ); 01673 // 01674 // Routine Description: 01675 // 01676 // This macro takes the address of a subsection and encodes it for use 01677 // in a PTE. 01678 // 01679 // Arguments 01680 // 01681 // VA - Supplies a pointer to the subsection to encode. 01682 // 01683 // Return Value: 01684 // 01685 // The mask to set into the PTE to make it reference the supplied 01686 // subsection. 01687 // 01688 //-- 01689 01690 #define MiGetSubsectionAddressForPte(VA) ((ULONGLONG)VA << 32) 01691 01692 01693 01694 //++ 01695 //PMMPTE 01696 //MiGetPpeAddress ( 01697 // IN PVOID va 01698 // ); 01699 // 01700 // Routine Description: 01701 // 01702 // MiGetPpeAddress returns the address of the page directory parent entry 01703 // which maps the given virtual address. This is one level above the 01704 // page directory. 01705 // 01706 // Arguments 01707 // 01708 // Va - Supplies the virtual address to locate the PPE for. 01709 // 01710 // Return Value: 01711 // 01712 // The address of the PPE. 01713 // 01714 //-- 01715 01716 #define MiGetPpeAddress(va) ((PMMPTE)0) 01717 01718 01719 //++ 01720 //PMMPTE 01721 //MiGetPdeAddress ( 01722 // IN PVOID va 01723 // ); 01724 // 01725 // Routine Description: 01726 // 01727 // MiGetPdeAddress returns the address of the PDE which maps the 01728 // given virtual address. 01729 // 01730 // Arguments 01731 // 01732 // Va - Supplies the virtual address to locate the PDE for. 01733 // 01734 // Return Value: 01735 // 01736 // The address of the PDE. 01737 // 01738 //-- 01739 01740 #define MiGetPdeAddress(va) ((PMMPTE)(PDE_BASE + ((((ULONG)(va)) >> 21) << 3))) 01741 01742 01743 //++ 01744 //PMMPTE 01745 //MiGetPteAddress ( 01746 // IN PVOID va 01747 // ); 01748 // 01749 // Routine Description: 01750 // 01751 // MiGetPteAddress returns the address of the PTE which maps the 01752 // given virtual address. 01753 // 01754 // Arguments 01755 // 01756 // Va - Supplies the virtual address to locate the PTE for. 01757 // 01758 // Return Value: 01759 // 01760 // The address of the PTE. 01761 // 01762 //-- 01763 01764 #define MiGetPteAddress(va) ((PMMPTE)(PTE_BASE + ((((ULONG)(va)) >> 12) << 3))) 01765 01766 01767 //++ 01768 //ULONG 01769 //MiGetPpeOffset ( 01770 // IN PVOID va 01771 // ); 01772 // 01773 // Routine Description: 01774 // 01775 // MiGetPpeOffset returns the offset into a page root 01776 // for a given virtual address. 01777 // 01778 // Arguments 01779 // 01780 // Va - Supplies the virtual address to locate the offset for. 01781 // 01782 // Return Value: 01783 // 01784 // The offset into the page root table the corresponding PPE is at. 01785 // 01786 //-- 01787 01788 #define MiGetPpeOffset(va) (0) 01789 01790 //++ 01791 //ULONG 01792 //MiGetPdPteOffset ( 01793 // IN PVOID va 01794 // ); 01795 // 01796 // Routine Description: 01797 // 01798 // MiGetPdPteOffset returns the offset into a page directory 01799 // pointer PTE table for a given virtual address. 01800 // 01801 // Arguments 01802 // 01803 // Va - Supplies the virtual address to locate the offset for. 01804 // 01805 // Return Value: 01806 // 01807 // The offset into the page directory pointer PTE table the corresponding 01808 // PDE is at. 01809 // 01810 //-- 01811 01812 #define MiGetPdPteOffset(va) (((ULONG)(va)) >> 30) 01813 01814 //++ 01815 //ULONG 01816 //MiGetPdeOffset ( 01817 // IN PVOID va 01818 // ); 01819 // 01820 // Routine Description: 01821 // 01822 // MiGetPdeOffset returns the offset into a page directory 01823 // for a given virtual address. 01824 // 01825 // Arguments 01826 // 01827 // Va - Supplies the virtual address to locate the offset for. 01828 // 01829 // Return Value: 01830 // 01831 // The offset into the page directory table the corresponding PDE is at. 01832 // 01833 //-- 01834 01835 #define MiGetPdeOffset(va) ((((ULONG)(va)) >> 21) & 0x1FF) 01836 01837 //++ 01838 //ULONG 01839 //MiGetPpePdeOffset ( 01840 // IN PVOID va 01841 // ); 01842 // 01843 // Routine Description: 01844 // 01845 // MiGetPdeOffset returns the offset into a page directory 01846 // for a given virtual address. 01847 // 01848 // N.B. This does not mask off PPE bits. 01849 // 01850 // Arguments 01851 // 01852 // Va - Supplies the virtual address to locate the offset for. 01853 // 01854 // Return Value: 01855 // 01856 // The offset into the page directory (and parent) table the 01857 // corresponding PDE is at. 01858 // 01859 //-- 01860 01861 #define MiGetPpePdeOffset(va) (((ULONG)(va)) >> 21) 01862 01863 //++ 01864 //ULONG 01865 //MiGetPteOffset ( 01866 // IN PVOID va 01867 // ); 01868 // 01869 // Routine Description: 01870 // 01871 // MiGetPteOffset returns the offset into a page table page 01872 // for a given virtual address. 01873 // 01874 // Arguments 01875 // 01876 // Va - Supplies the virtual address to locate the offset for. 01877 // 01878 // Return Value: 01879 // 01880 // The offset into the page table page table the corresponding PTE is at. 01881 // 01882 //-- 01883 01884 #define MiGetPteOffset(va) ((((ULONG)(va)) << 11) >> 23) 01885 01886 01887 01888 //++ 01889 //PVOID 01890 //MiGetVirtualAddressMappedByPpe ( 01891 // IN PMMPTE PTE 01892 // ); 01893 // 01894 // Routine Description: 01895 // 01896 // MiGetVirtualAddressMappedByPpe returns the virtual address 01897 // which is mapped by a given PPE address. 01898 // 01899 // Arguments 01900 // 01901 // PPE - Supplies the PPE to get the virtual address for. 01902 // 01903 // Return Value: 01904 // 01905 // Virtual address mapped by the PPE. 01906 // 01907 //-- 01908 01909 #define MiGetVirtualAddressMappedByPpe(PPE) (NULL) 01910 01911 //++ 01912 //PVOID 01913 //MiGetVirtualAddressMappedByPde ( 01914 // IN PMMPTE PTE 01915 // ); 01916 // 01917 // Routine Description: 01918 // 01919 // MiGetVirtualAddressMappedByPde returns the virtual address 01920 // which is mapped by a given PDE address. 01921 // 01922 // Arguments 01923 // 01924 // PDE - Supplies the PDE to get the virtual address for. 01925 // 01926 // Return Value: 01927 // 01928 // Virtual address mapped by the PDE. 01929 // 01930 //-- 01931 01932 #define MiGetVirtualAddressMappedByPde(PDE) ((PVOID)((ULONG)(PDE) << 18)) 01933 01934 01935 //++ 01936 //PVOID 01937 //MiGetVirtualAddressMappedByPte ( 01938 // IN PMMPTE PTE 01939 // ); 01940 // 01941 // Routine Description: 01942 // 01943 // MiGetVirtualAddressMappedByPte returns the virtual address 01944 // which is mapped by a given PTE address. 01945 // 01946 // Arguments 01947 // 01948 // PTE - Supplies the PTE to get the virtual address for. 01949 // 01950 // Return Value: 01951 // 01952 // Virtual address mapped by the PTE. 01953 // 01954 //-- 01955 01956 #define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG)(PTE) << 9)) 01957 01958 01959 //++ 01960 //LOGICAL 01961 //MiIsVirtualAddressOnPpeBoundary ( 01962 // IN PVOID VA 01963 // ); 01964 // 01965 // Routine Description: 01966 // 01967 // MiIsVirtualAddressOnPpeBoundary returns TRUE if the virtual address is 01968 // on a page directory entry boundary. 01969 // 01970 // Arguments 01971 // 01972 // VA - Supplies the virtual address to check. 01973 // 01974 // Return Value: 01975 // 01976 // TRUE if on a boundary, FALSE if not. 01977 // 01978 //-- 01979 01980 #define MiIsVirtualAddressOnPpeBoundary(VA) (FALSE) 01981 01982 01983 //++ 01984 //LOGICAL 01985 //MiIsVirtualAddressOnPdeBoundary ( 01986 // IN PVOID VA 01987 // ); 01988 // 01989 // Routine Description: 01990 // 01991 // MiIsVirtualAddressOnPdeBoundary returns TRUE if the virtual address is 01992 // on a page directory entry boundary. 01993 // 01994 // Arguments 01995 // 01996 // VA - Supplies the virtual address to check. 01997 // 01998 // Return Value: 01999 // 02000 // TRUE if on a 4MB PDE boundary, FALSE if not. 02001 // 02002 //-- 02003 02004 #define MiIsVirtualAddressOnPdeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY_MASK) == 0) 02005 02006 02007 //++ 02008 //LOGICAL 02009 //MiIsPteOnPpeBoundary ( 02010 // IN PVOID PTE 02011 // ); 02012 // 02013 // Routine Description: 02014 // 02015 // MiIsPteOnPpeBoundary returns TRUE if the PTE is 02016 // on a page directory parent entry boundary. 02017 // 02018 // Arguments 02019 // 02020 // PTE - Supplies the PTE to check. 02021 // 02022 // Return Value: 02023 // 02024 // TRUE if on a boundary, FALSE if not. 02025 // 02026 //-- 02027 02028 #define MiIsPteOnPpeBoundary(PTE) (FALSE) 02029 02030 02031 //++ 02032 //LOGICAL 02033 //MiIsPteOnPdeBoundary ( 02034 // IN PVOID PTE 02035 // ); 02036 // 02037 // Routine Description: 02038 // 02039 // MiIsPteOnPdeBoundary returns TRUE if the PTE is 02040 // on a page directory entry boundary. 02041 // 02042 // Arguments 02043 // 02044 // PTE - Supplies the PTE to check. 02045 // 02046 // Return Value: 02047 // 02048 // TRUE if on a 4MB PDE boundary, FALSE if not. 02049 // 02050 //-- 02051 02052 #define MiIsPteOnPdeBoundary(PTE) (((ULONG_PTR)(PTE) & (PAGE_SIZE - 1)) == 0) 02053 02054 02055 //++ 02056 //LOGICAL 02057 //MiDoesPpeExistAndMakeValid ( 02058 // IN PMMPTE PointerPpe, 02059 // IN PEPROCESS TargetProcess, 02060 // IN ULONG PfnMutexHeld 02061 // OUT PULONG Waited 02062 // ); 02063 // 02064 // Routine Description: 02065 // 02066 // MiDoesPpeExistAndMakeValid returns TRUE if the specified PPE entry 02067 // exists and can be made valid. 02068 // 02069 // Arguments 02070 // 02071 // PointerPpe - Supplies the PPE entry to check. 02072 // 02073 // TargetProcess - Supplies a pointer to the current process. 02074 // 02075 // PfnMutexHeld - Supplies the value TRUE if the PFN mutex is held, FALSE 02076 // otherwise. 02077 // 02078 // Waited - Supplies a pointer to increment if the mutex was released and 02079 // reacquired. 02080 // 02081 // Return Value: 02082 // 02083 // TRUE if valid, FALSE if not. Always TRUE on x86. 02084 // 02085 //-- 02086 02087 #define MiDoesPpeExistAndMakeValid(PPE, TARGETPROCESS, PFNMUTEXHELD, WAITED) (1) 02088 02089 02090 //++ 02091 //ULONG 02092 //GET_PAGING_FILE_NUMBER ( 02093 // IN MMPTE PTE 02094 // ); 02095 // 02096 // Routine Description: 02097 // 02098 // This macro extracts the paging file number from a PTE. 02099 // 02100 // Arguments 02101 // 02102 // PTE - Supplies the PTE to operate upon. 02103 // 02104 // Return Value: 02105 // 02106 // The paging file number. 02107 // 02108 //-- 02109 02110 #define GET_PAGING_FILE_NUMBER(PTE) ((ULONG)((((PTE).u.Long) >> 1) & 0x0000000F)) 02111 02112 02113 02114 //++ 02115 //ULONG 02116 //GET_PAGING_FILE_OFFSET ( 02117 // IN MMPTE PTE 02118 // ); 02119 // 02120 // Routine Description: 02121 // 02122 // This macro extracts the offset into the paging file from a PTE. 02123 // 02124 // Arguments 02125 // 02126 // PTE - Supplies the PTE to operate upon. 02127 // 02128 // Return Value: 02129 // 02130 // The paging file offset. 02131 // 02132 //-- 02133 02134 #define GET_PAGING_FILE_OFFSET(PTE) ((ULONG)((PTE).u.Soft.PageFileHigh)) 02135 02136 02137 02138 02139 //++ 02140 //ULONG 02141 //IS_PTE_NOT_DEMAND_ZERO ( 02142 // IN PMMPTE PPTE 02143 // ); 02144 // 02145 // Routine Description: 02146 // 02147 // This macro checks to see if a given PTE is NOT a demand zero PTE. 02148 // 02149 // Arguments 02150 // 02151 // PTE - Supplies the PTE to operate upon. 02152 // 02153 // Return Value: 02154 // 02155 // Returns 0 if the PTE is demand zero, non-zero otherwise. 02156 // 02157 //-- 02158 02159 #define IS_PTE_NOT_DEMAND_ZERO(PTE) ((PTE).u.Long & ~0x3FE) 02160 02161 02162 //++ 02163 //VOID 02164 //MI_MAKING_VALID_PTE_INVALID( 02165 // IN PMMPTE PPTE 02166 // ); 02167 // 02168 // Routine Description: 02169 // 02170 // Prepare to make a single valid PTE invalid. 02171 // No action is required on x86. 02172 // 02173 // Arguments 02174 // 02175 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 02176 // 02177 // Return Value: 02178 // 02179 // None. 02180 // 02181 //-- 02182 02183 #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE) 02184 02185 02186 //++ 02187 //VOID 02188 //MI_MAKING_VALID_MULTIPLE_PTES_INVALID( 02189 // IN PMMPTE PPTE 02190 // ); 02191 // 02192 // Routine Description: 02193 // 02194 // Prepare to make multiple valid PTEs invalid. 02195 // No action is required on x86. 02196 // 02197 // Arguments 02198 // 02199 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 02200 // 02201 // Return Value: 02202 // 02203 // None. 02204 // 02205 //-- 02206 02207 #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE) 02208 02209 02210 02211 //++ 02212 //VOID 02213 //MI_MAKE_PROTECT_WRITE_COPY ( 02214 // IN OUT MMPTE PPTE 02215 // ); 02216 // 02217 // Routine Description: 02218 // 02219 // This macro makes a writable PTE a writable-copy PTE. 02220 // 02221 // Arguments 02222 // 02223 // PTE - Supplies the PTE to operate upon. 02224 // 02225 // Return Value: 02226 // 02227 // NONE 02228 // 02229 //-- 02230 02231 #define MI_MAKE_PROTECT_WRITE_COPY(PTE) \ 02232 if ((PTE).u.Soft.Protection & MM_PROTECTION_WRITE_MASK) { \ 02233 (PTE).u.Long |= MM_PROTECTION_COPY_MASK << MM_PROTECT_FIELD_SHIFT; \ 02234 } 02235 02236 02237 //++ 02238 //VOID 02239 //MI_SET_PAGE_DIRTY( 02240 // IN PMMPTE PPTE, 02241 // IN PVOID VA, 02242 // IN PVOID PFNHELD 02243 // ); 02244 // 02245 // Routine Description: 02246 // 02247 // This macro sets the dirty bit (and release page file space). 02248 // 02249 // Arguments 02250 // 02251 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 02252 // 02253 // VA - Supplies a the virtual address of the page fault. 02254 // 02255 // PFNHELD - Supplies TRUE if the PFN lock is held. 02256 // 02257 // Return Value: 02258 // 02259 // None. 02260 // 02261 //-- 02262 02263 #if defined(NT_UP) 02264 #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) 02265 #else 02266 #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \ 02267 if ((PPTE)->u.Hard.Dirty == 1) { \ 02268 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 02269 } 02270 #endif 02271 02272 02273 02274 02275 //++ 02276 //VOID 02277 //MI_NO_FAULT_FOUND( 02278 // IN TEMP, 02279 // IN PMMPTE PPTE, 02280 // IN PVOID VA, 02281 // IN PVOID PFNHELD 02282 // ); 02283 // 02284 // Routine Description: 02285 // 02286 // This macro handles the case when a page fault is taken and no 02287 // PTE with the valid bit clear is found. 02288 // 02289 // Arguments 02290 // 02291 // TEMP - Supplies a temporary for usage. 02292 // 02293 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 02294 // 02295 // VA - Supplies a the virtual address of the page fault. 02296 // 02297 // PFNHELD - Supplies TRUE if the PFN lock is held. 02298 // 02299 // Return Value: 02300 // 02301 // None. 02302 // 02303 //-- 02304 02305 #if defined(NT_UP) 02306 #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) 02307 #else 02308 #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \ 02309 if (StoreInstruction && ((PPTE)->u.Hard.Dirty == 0)) { \ 02310 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 02311 } 02312 #endif 02313 02314 02315 02316 02317 //++ 02318 //ULONG 02319 //MI_CAPTURE_DIRTY_BIT_TO_PFN ( 02320 // IN PMMPTE PPTE, 02321 // IN PMMPFN PPFN 02322 // ); 02323 // 02324 // Routine Description: 02325 // 02326 // This macro gets captures the state of the dirty bit to the PFN 02327 // and frees any associated page file space if the PTE has been 02328 // modified element. 02329 // 02330 // NOTE - THE PFN LOCK MUST BE HELD! 02331 // 02332 // Arguments 02333 // 02334 // PPTE - Supplies the PTE to operate upon. 02335 // 02336 // PPFN - Supplies a pointer to the PFN database element that corresponds 02337 // to the page mapped by the PTE. 02338 // 02339 // Return Value: 02340 // 02341 // None. 02342 // 02343 //-- 02344 02345 #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \ 02346 ASSERT (KeGetCurrentIrql() > APC_LEVEL); \ 02347 if (((PPFN)->u3.e1.Modified == 0) && \ 02348 ((PPTE)->u.Hard.Dirty != 0)) { \ 02349 (PPFN)->u3.e1.Modified = 1; \ 02350 if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \ 02351 ((PPFN)->u3.e1.WriteInProgress == 0)) { \ 02352 MiReleasePageFileSpace ((PPFN)->OriginalPte); \ 02353 (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \ 02354 } \ 02355 } 02356 02357 02358 //++ 02359 //BOOLEAN 02360 //MI_IS_PHYSICAL_ADDRESS ( 02361 // IN PVOID VA 02362 // ); 02363 // 02364 // Routine Description: 02365 // 02366 // This macro determines if a given virtual address is really a 02367 // physical address. 02368 // 02369 // Arguments 02370 // 02371 // VA - Supplies the virtual address. 02372 // 02373 // Return Value: 02374 // 02375 // FALSE if it is not a physical address, TRUE if it is. 02376 // 02377 //-- 02378 02379 02380 #define MI_IS_PHYSICAL_ADDRESS(Va) \ 02381 (((ULONG)Va >= MM_KSEG0_BASE) && ((ULONG)Va < MM_KSEG2_BASE) && (MmKseg2Frame)) 02382 02383 02384 //++ 02385 //ULONG 02386 //MI_CONVERT_PHYSICAL_TO_PFN ( 02387 // IN PVOID VA 02388 // ); 02389 // 02390 // Routine Description: 02391 // 02392 // This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS) 02393 // to its corresponding physical frame number. 02394 // 02395 // Arguments 02396 // 02397 // VA - Supplies a pointer to the physical address. 02398 // 02399 // Return Value: 02400 // 02401 // Returns the PFN for the page. 02402 // 02403 //-- 02404 02405 02406 #define MI_CONVERT_PHYSICAL_TO_PFN(Va) (((ULONG)Va << 3) >> 15) 02407 02408 02409 typedef struct _MMCOLOR_TABLES { 02410 ULONG Flink; 02411 PVOID Blink; 02412 } MMCOLOR_TABLES, *PMMCOLOR_TABLES; 02413 02414 typedef struct _MMPRIMARY_COLOR_TABLES { 02415 LIST_ENTRY ListHead; 02416 } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES; 02417 02418 extern PMMCOLOR_TABLES MmFreePagesByColor[2]; 02419 02420 extern ULONG MmTotalPagesForPagingFile; 02421 02422 02423 // 02424 // A VALID Page Table Entry on an Intel PAE has the following definition. 02425 // 02426 02427 #define MI_PTE_LOOKUP_NEEDED (0xffffffff) 02428 02429 typedef struct _MMPTE_SOFTWARE { 02430 ULONGLONG Valid : 1; 02431 ULONGLONG PageFileLow : 4; 02432 ULONGLONG Protection : 5; 02433 ULONGLONG Prototype : 1; 02434 ULONGLONG Transition : 1; 02435 ULONGLONG Unused : 20; 02436 ULONGLONG PageFileHigh : 32; 02437 } MMPTE_SOFTWARE; 02438 02439 typedef struct _MMPTE_TRANSITION { 02440 ULONGLONG Valid : 1; 02441 ULONGLONG Write : 1; 02442 ULONGLONG Owner : 1; 02443 ULONGLONG WriteThrough : 1; 02444 ULONGLONG CacheDisable : 1; 02445 ULONGLONG Protection : 5; 02446 ULONGLONG Prototype : 1; 02447 ULONGLONG Transition : 1; 02448 ULONGLONG PageFrameNumber : 24; 02449 ULONGLONG Unused : 28; 02450 } MMPTE_TRANSITION; 02451 02452 typedef struct _MMPTE_PROTOTYPE { 02453 ULONGLONG Valid : 1; 02454 ULONGLONG Unused0: 7; 02455 ULONGLONG ReadOnly : 1; // if set allow read only access. LWFIX: remove 02456 ULONGLONG Unused1: 1; 02457 ULONGLONG Prototype : 1; 02458 ULONGLONG Protection : 5; 02459 ULONGLONG Unused: 16; 02460 ULONGLONG ProtoAddress: 32; 02461 } MMPTE_PROTOTYPE; 02462 02463 typedef struct _MMPTE_SUBSECTION { 02464 ULONGLONG Valid : 1; 02465 ULONGLONG Unused0 : 4; 02466 ULONGLONG Protection : 5; 02467 ULONGLONG Prototype : 1; 02468 ULONGLONG Unused1 : 21; 02469 ULONGLONG SubsectionAddress : 32; 02470 } MMPTE_SUBSECTION; 02471 02472 typedef struct _MMPTE_LIST { 02473 ULONGLONG Valid : 1; 02474 ULONGLONG OneEntry : 1; 02475 ULONGLONG filler0 : 10; 02476 ULONGLONG filler1 : 20; 02477 ULONGLONG NextEntry : 32; 02478 } MMPTE_LIST; 02479 02480 typedef struct _MMPTE_HIGHLOW { 02481 ULONG LowPart; 02482 ULONG HighPart; 02483 } MMPTE_HIGHLOW; 02484 02485 // 02486 // A Page Table Entry on an Intel PAE has the following definition. 02487 // 02488 02489 #if defined(NT_UP) 02490 02491 // 02492 // Uniprocessor version. 02493 // 02494 02495 typedef struct _MMPTE_HARDWARE { 02496 ULONGLONG Valid : 1; 02497 ULONGLONG Write : 1; // UP version 02498 ULONGLONG Owner : 1; 02499 ULONGLONG WriteThrough : 1; 02500 ULONGLONG CacheDisable : 1; 02501 ULONGLONG Accessed : 1; 02502 ULONGLONG Dirty : 1; 02503 ULONGLONG LargePage : 1; 02504 ULONGLONG Global : 1; 02505 ULONGLONG CopyOnWrite : 1; // software field 02506 ULONGLONG Prototype : 1; // software field 02507 ULONGLONG reserved0 : 1; // software field 02508 ULONGLONG PageFrameNumber : 24; 02509 ULONGLONG reserved1 : 28; // software field 02510 } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 02511 02512 #define HARDWARE_PTE_DIRTY_MASK 0x40 02513 02514 #else 02515 02516 // 02517 // MP version to avoid stalls when flushing TBs across processors. 02518 // 02519 02520 typedef struct _MMPTE_HARDWARE { 02521 ULONGLONG Valid : 1; 02522 ULONGLONG Writable : 1; // changed for MP version 02523 ULONGLONG Owner : 1; 02524 ULONGLONG WriteThrough : 1; 02525 ULONGLONG CacheDisable : 1; 02526 ULONGLONG Accessed : 1; 02527 ULONGLONG Dirty : 1; 02528 ULONGLONG LargePage : 1; 02529 ULONGLONG Global : 1; 02530 ULONGLONG CopyOnWrite : 1; // software field 02531 ULONGLONG Prototype : 1; // software field 02532 ULONGLONG Write : 1; // software field - MP change 02533 ULONGLONG PageFrameNumber : 24; 02534 ULONGLONG reserved1 : 28; // software field 02535 } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 02536 02537 #define HARDWARE_PTE_DIRTY_MASK 0x42 02538 02539 #endif //NT_UP 02540 02541 #define MI_GET_PAGE_FRAME_FROM_PTE(PTE) ((PFN_NUMBER)(PTE)->u.Hard.PageFrameNumber) 02542 #define MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE(PTE) ((PFN_NUMBER)(PTE)->u.Trans.PageFrameNumber) 02543 #define MI_GET_PROTECTION_FROM_SOFT_PTE(PTE) ((ULONG)(PTE)->u.Soft.Protection) 02544 #define MI_GET_PROTECTION_FROM_TRANSITION_PTE(PTE) ((ULONG)(PTE)->u.Trans.Protection) 02545 02546 typedef struct _MMPTE { 02547 union { 02548 ULONGLONG Long; 02549 MMPTE_HIGHLOW HighLow; 02550 MMPTE_HARDWARE Hard; 02551 HARDWARE_PTE Flush; 02552 MMPTE_PROTOTYPE Proto; 02553 MMPTE_SOFTWARE Soft; 02554 MMPTE_TRANSITION Trans; 02555 MMPTE_SUBSECTION Subsect; 02556 MMPTE_LIST List; 02557 } u; 02558 } MMPTE; 02559 02560 typedef MMPTE *PMMPTE; 02561 02562 extern MMPTE MmPteGlobal; // Set if processor supports Global Page, else zero. 02563 02564 //++ 02565 //VOID 02566 //MI_WRITE_VALID_PTE ( 02567 // IN PMMPTE PointerPte, 02568 // IN MMPTE PteContents 02569 // ); 02570 // 02571 // Routine Description: 02572 // 02573 // MI_WRITE_VALID_PTE fills in the specified PTE making it valid with the 02574 // specified contents. Note that the contents are very carefully written. 02575 // 02576 // Arguments 02577 // 02578 // PointerPte - Supplies a PTE to fill. 02579 // 02580 // PteContents - Supplies the contents to put in the PTE. 02581 // 02582 // Return Value: 02583 // 02584 // None. 02585 // 02586 //-- 02587 02588 #define MI_WRITE_VALID_PTE(_PointerPte, _PteContents) \ 02589 ASSERT ((_PointerPte)->u.Hard.Valid == 0); \ 02590 ASSERT ((_PteContents).u.Hard.Valid == 1); \ 02591 ((_PointerPte)->u.HighLow.HighPart = ((_PteContents).u.HighLow.HighPart)); \ 02592 ((_PointerPte)->u.HighLow.LowPart = ((_PteContents).u.HighLow.LowPart)) 02593 02594 //++ 02595 //VOID 02596 //MI_WRITE_INVALID_PTE ( 02597 // IN PMMPTE PointerPte, 02598 // IN MMPTE PteContents 02599 // ); 02600 // 02601 // Routine Description: 02602 // 02603 // MI_WRITE_INVALID_PTE fills in the specified PTE making it invalid with the 02604 // specified contents. Note that the contents are very carefully written. 02605 // 02606 // Arguments 02607 // 02608 // PointerPte - Supplies a PTE to fill. 02609 // 02610 // PteContents - Supplies the contents to put in the PTE. 02611 // 02612 // Return Value: 02613 // 02614 // None. 02615 // 02616 //-- 02617 02618 #define MI_WRITE_INVALID_PTE(_PointerPte, _PteContents) \ 02619 ASSERT ((_PteContents).u.Hard.Valid == 0); \ 02620 ((_PointerPte)->u.HighLow.LowPart = ((_PteContents).u.HighLow.LowPart)); \ 02621 ((_PointerPte)->u.HighLow.HighPart = ((_PteContents).u.HighLow.HighPart)) 02622 02623 //++ 02624 //VOID 02625 //MI_WRITE_VALID_PTE_NEW_PROTECTION ( 02626 // IN PMMPTE PointerPte, 02627 // IN MMPTE PteContents 02628 // ); 02629 // 02630 // Routine Description: 02631 // 02632 // MI_WRITE_VALID_PTE_NEW_PROTECTION fills in the specified PTE (which was 02633 // already valid) changing only the protection or the dirty bit. 02634 // Note that the contents are very carefully written. 02635 // 02636 // Arguments 02637 // 02638 // PointerPte - Supplies a PTE to fill. 02639 // 02640 // PteContents - Supplies the contents to put in the PTE. 02641 // 02642 // Return Value: 02643 // 02644 // None. 02645 // 02646 //-- 02647 02648 #define MI_WRITE_VALID_PTE_NEW_PROTECTION(_PointerPte, _PteContents) \ 02649 ASSERT ((_PointerPte)->u.Hard.Valid == 1); \ 02650 ASSERT ((_PteContents).u.Hard.Valid == 1); \ 02651 ASSERT ((_PointerPte)->u.Hard.PageFrameNumber == (_PteContents).u.Hard.PageFrameNumber); \ 02652 ((_PointerPte)->u.HighLow.LowPart = ((_PteContents).u.HighLow.LowPart)); 02653 02654 //++ 02655 //VOID 02656 //MiFillMemoryPte ( 02657 // IN PMMPTE Destination, 02658 // IN ULONG Length, 02659 // IN MMPTE Pattern, 02660 // }; 02661 // 02662 // Routine Description: 02663 // 02664 // This function fills memory with the specified PTE pattern. 02665 // 02666 // Arguments 02667 // 02668 // Destination - Supplies a pointer to the memory to fill. 02669 // 02670 // Length - Supplies the length, in bytes, of the memory to be 02671 // filled. 02672 // 02673 // Pattern - Supplies the PTE fill pattern. 02674 // 02675 // Return Value: 02676 // 02677 // None. 02678 // 02679 //-- 02680 02681 #define MiFillMemoryPte(Destination, Length, Pattern) \ 02682 RtlFillMemoryUlonglong ((Destination), (Length), (Pattern)) 02683 02684 ULONG 02685 FASTCALL 02686 MiDetermineUserGlobalPteMask ( 02687 IN PMMPTE Pte 02688 ); 02689 02690 //++ 02691 //BOOLEAN 02692 //MI_IS_PAGE_TABLE_ADDRESS ( 02693 // IN PVOID VA 02694 // ); 02695 // 02696 // Routine Description: 02697 // 02698 // This macro takes a virtual address and determines if 02699 // it is a page table address. 02700 // 02701 // Arguments 02702 // 02703 // VA - Supplies a virtual address. 02704 // 02705 // Return Value: 02706 // 02707 // TRUE if the address is a page table address, FALSE if not. 02708 // 02709 //-- 02710 02711 #define MI_IS_PAGE_TABLE_ADDRESS(VA) \ 02712 ((PVOID)(VA) >= (PVOID)PTE_BASE && (PVOID)(VA) <= (PVOID)PTE_TOP) 02713 02714 //++ 02715 //BOOLEAN 02716 //MI_IS_KERNEL_PAGE_TABLE_ADDRESS ( 02717 // IN PVOID VA 02718 // ); 02719 // 02720 // Routine Description: 02721 // 02722 // This macro takes a virtual address and determines if 02723 // it is a page table address for a kernel address. 02724 // 02725 // Arguments 02726 // 02727 // VA - Supplies a virtual address. 02728 // 02729 // Return Value: 02730 // 02731 // TRUE if the address is a kernel page table address, FALSE if not. 02732 // 02733 //-- 02734 02735 #define MI_IS_KERNEL_PAGE_TABLE_ADDRESS(VA) \ 02736 ((PVOID)(VA) >= (PVOID)MiGetPteAddress(MmSystemRangeStart) && (PVOID)(VA) <= (PVOID)PTE_TOP) 02737 02738 02739 //++ 02740 //BOOLEAN 02741 //MI_IS_PAGE_DIRECTORY_ADDRESS ( 02742 // IN PVOID VA 02743 // ); 02744 // 02745 // Routine Description: 02746 // 02747 // This macro takes a virtual address and determines if 02748 // it is a page directory address. 02749 // 02750 // Arguments 02751 // 02752 // VA - Supplies a virtual address. 02753 // 02754 // Return Value: 02755 // 02756 // TRUE if the address is a page directory address, FALSE if not. 02757 // 02758 //-- 02759 02760 #define MI_IS_PAGE_DIRECTORY_ADDRESS(VA) \ 02761 ((PVOID)(VA) >= (PVOID)PDE_BASE && (PVOID)(VA) <= (PVOID)PDE_TOP) 02762 02763 02764 //++ 02765 //BOOLEAN 02766 //MI_IS_HYPER_SPACE_ADDRESS ( 02767 // IN PVOID VA 02768 // ); 02769 // 02770 // Routine Description: 02771 // 02772 // This macro takes a virtual address and determines if 02773 // it is a hyper space address. 02774 // 02775 // Arguments 02776 // 02777 // VA - Supplies a virtual address. 02778 // 02779 // Return Value: 02780 // 02781 // TRUE if the address is a hyper space address, FALSE if not. 02782 // 02783 //-- 02784 02785 #define MI_IS_HYPER_SPACE_ADDRESS(VA) \ 02786 ((PVOID)(VA) >= (PVOID)HYPER_SPACE && (PVOID)(VA) <= (PVOID)HYPER_SPACE_END) 02787 02788 02789 //++ 02790 //BOOLEAN 02791 //MI_IS_PROCESS_SPACE_ADDRESS ( 02792 // IN PVOID VA 02793 // ); 02794 // 02795 // Routine Description: 02796 // 02797 // This macro takes a virtual address and determines if 02798 // it is a process-specific address. This is an address in user space 02799 // or page table pages or hyper space. 02800 // 02801 // Arguments 02802 // 02803 // VA - Supplies a virtual address. 02804 // 02805 // Return Value: 02806 // 02807 // TRUE if the address is a process-specific address, FALSE if not. 02808 // 02809 //-- 02810 02811 #define MI_IS_PROCESS_SPACE_ADDRESS(VA) \ 02812 (((PVOID)(VA) <= (PVOID)MM_HIGHEST_USER_ADDRESS) || \ 02813 ((PVOID)(VA) >= (PVOID)PTE_BASE && (PVOID)(VA) <= (PVOID)HYPER_SPACE_END)) 02814 02815 02816 //++ 02817 //BOOLEAN 02818 //MI_IS_PTE_PROTOTYPE ( 02819 // IN PMMPTE PTE 02820 // ); 02821 // 02822 // Routine Description: 02823 // 02824 // This macro takes a PTE address and determines if it is a prototype PTE. 02825 // 02826 // Arguments 02827 // 02828 // PTE - Supplies the virtual address of the PTE to check. 02829 // 02830 // Return Value: 02831 // 02832 // TRUE if the PTE is in a segment (ie, a prototype PTE), FALSE if not. 02833 // 02834 //-- 02835 02836 #define MI_IS_PTE_PROTOTYPE(PTE) \ 02837 ((PTE) > (PMMPTE)PTE_TOP) 02838 02839 //++ 02840 //BOOLEAN 02841 //MI_IS_SYSTEM_CACHE_ADDRESS ( 02842 // IN PVOID VA 02843 // ); 02844 // 02845 // Routine Description: 02846 // 02847 // This macro takes a virtual address and determines if 02848 // it is a system cache address. 02849 // 02850 // Arguments 02851 // 02852 // VA - Supplies a virtual address. 02853 // 02854 // Return Value: 02855 // 02856 // TRUE if the address is in the system cache, FALSE if not. 02857 // 02858 //-- 02859 02860 #define MI_IS_SYSTEM_CACHE_ADDRESS(VA) \ 02861 (((PVOID)(VA) >= (PVOID)MmSystemCacheStart && \ 02862 (PVOID)(VA) <= (PVOID)MmSystemCacheEnd) || \ 02863 ((PVOID)(VA) >= (PVOID)MiSystemCacheStartExtra && \ 02864 (PVOID)(VA) <= (PVOID)MiSystemCacheEndExtra)) 02865 02866 //++ 02867 //VOID 02868 //MI_BARRIER_SYNCHRONIZE ( 02869 // IN ULONG TimeStamp 02870 // ); 02871 // 02872 // Routine Description: 02873 // 02874 // MI_BARRIER_SYNCHRONIZE compares the argument timestamp against the 02875 // current IPI barrier sequence stamp. When equal, all processors will 02876 // issue memory barriers to ensure that newly created pages remain coherent. 02877 // 02878 // When a page is put in the zeroed or free page list the current 02879 // barrier sequence stamp is read (interlocked - this is necessary 02880 // to get the correct value - memory barriers won't do the trick) 02881 // and stored in the pfn entry for the page. The current barrier 02882 // sequence stamp is maintained by the IPI send logic and is 02883 // incremented (interlocked) when the target set of an IPI send 02884 // includes all processors, but the one doing the send. When a page 02885 // is needed its sequence number is compared against the current 02886 // barrier sequence number. If it is equal, then the contents of 02887 // the page may not be coherent on all processors, and an IPI must 02888 // be sent to all processors to ensure a memory barrier is 02889 // executed (generic call can be used for this). Sending the IPI 02890 // automatically updates the barrier sequence number. The compare 02891 // is for equality as this is the only value that requires the IPI 02892 // (i.e., the sequence number wraps, values in both directions are 02893 // older). When a page is removed in this fashion and either found 02894 // to be coherent or made coherent, it cannot be modified between 02895 // that time and writing the PTE. If the page is modified between 02896 // these times, then an IPI must be sent. 02897 // 02898 // Arguments 02899 // 02900 // TimeStamp - Supplies the timestamp at the time when the page was zeroed. 02901 // 02902 // Return Value: 02903 // 02904 // None. 02905 // 02906 //-- 02907 02908 // does nothing on PAE. 02909 02910 #define MI_BARRIER_SYNCHRONIZE(TimeStamp) 02911 02912 //++ 02913 //VOID 02914 //MI_BARRIER_STAMP_ZEROED_PAGE ( 02915 // IN PULONG PointerTimeStamp 02916 // ); 02917 // 02918 // Routine Description: 02919 // 02920 // MI_BARRIER_STAMP_ZEROED_PAGE issues an interlocked read to get the 02921 // current IPI barrier sequence stamp. This is called AFTER a page is 02922 // zeroed. 02923 // 02924 // Arguments 02925 // 02926 // PointerTimeStamp - Supplies a timestamp pointer to fill with the 02927 // current IPI barrier sequence stamp. 02928 // 02929 // Return Value: 02930 // 02931 // None. 02932 // 02933 //-- 02934 02935 // does nothing on PAE. 02936 02937 #define MI_BARRIER_STAMP_ZEROED_PAGE(PointerTimeStamp) 02938 02939 typedef struct _PAE_PAGEINFO { 02940 LIST_ENTRY ListHead; 02941 PFN_NUMBER PageFrameNumber; 02942 ULONG EntriesInUse; 02943 } PAE_PAGEINFO, *PPAE_PAGEINFO; 02944 02945 typedef struct _PAE_ENTRY { 02946 union { 02947 MMPTE PteEntry[PD_PER_SYSTEM]; 02948 PAE_PAGEINFO PaeEntry; 02949 }; 02950 } PAE_ENTRY, *PPAE_ENTRY; 02951 02952 //++ 02953 //VOID 02954 //MI_FLUSH_SINGLE_SESSION_TB ( 02955 // IN PVOID Virtual, 02956 // IN ULONG Invalid, 02957 // IN LOGICAL AllProcessors, 02958 // IN PMMPTE PtePointer, 02959 // IN MMPTE PteValue, 02960 // IN MMPTE PreviousPte 02961 // ); 02962 // 02963 // Routine Description: 02964 // 02965 // MI_FLUSH_SINGLE_SESSION_TB flushes the requested single address 02966 // translation from the TB. 02967 // 02968 // Since there are no ASNs on the x86, this routine becomes a single 02969 // TB invalidate. 02970 // 02971 // Arguments 02972 // 02973 // Virtual - Supplies the virtual address to invalidate. 02974 // 02975 // Invalid - TRUE if invalidating. 02976 // 02977 // AllProcessors - TRUE if all processors need to be IPI'd. 02978 // 02979 // PtePointer - Supplies the PTE to invalidate. 02980 // 02981 // PteValue - Supplies the new PTE value. 02982 // 02983 // PreviousPte - The previous PTE value is returned here. 02984 // 02985 // Return Value: 02986 // 02987 // None. 02988 // 02989 //-- 02990 02991 #define MI_FLUSH_SINGLE_SESSION_TB(Virtual, Invalid, AllProcessors, PtePointer, PteValue, PreviousPte) \ 02992 PreviousPte.u.Flush = KeFlushSingleTb (Virtual, \ 02993 TRUE, \ 02994 TRUE, \ 02995 PtePointer, \ 02996 PteValue); 02997 02998 //++ 02999 //VOID 03000 //MI_FLUSH_ENTIRE_SESSION_TB ( 03001 // IN ULONG Invalid, 03002 // IN LOGICAL AllProcessors 03003 // ); 03004 // 03005 // Routine Description: 03006 // 03007 // MI_FLUSH_ENTIRE_SESSION_TB flushes the entire TB on processors which 03008 // support ASNs. 03009 // 03010 // Since there are no ASNs on the x86, this routine does nothing. 03011 // 03012 // Arguments 03013 // 03014 // Invalid - TRUE if invalidating. 03015 // 03016 // AllProcessors - TRUE if all processors need to be IPI'd. 03017 // 03018 // Return Value: 03019 // 03020 // None. 03021 // 03022 03023 #define MI_FLUSH_ENTIRE_SESSION_TB(Invalid, AllProcessors) \ 03024 NOTHING; 03025 03026 #endif

Generated on Sat May 15 19:40:48 2004 for test by doxygen 1.3.7