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

mi386.h

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

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