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

miia64.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 Copyright (c) 1995 Intel Corporation 00005 00006 Module Name: 00007 00008 miia64.h 00009 00010 Abstract: 00011 00012 This module contains the private data structures and procedure 00013 prototypes for the hardware dependent portion of the 00014 memory management system. 00015 00016 This module is specifically tailored for the Intel MERCED, 00017 00018 Author: 00019 00020 Lou Perazzoli (loup) 6-Jan-1990 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 /*++ 00027 00028 Virtual Memory Layout on MERCED is: 00029 00030 /*++ 00031 00032 Virtual Memory Layout for the initial Merced port is: 00033 00034 +------------------------------------+ 00035 0000000000000000 | User mode addresses - 8tb minus 8gb| UADDRESS_BASE 00036 | | 00037 | | 00038 000003FFFFFEFFFF | | MM_HIGHEST_USER_ADDRESS 00039 +------------------------------------+ 00040 000003FFFFFF0000 | 64k No Access Region | MM_USER_PROBE_ADDRESS 00041 +------------------------------------+ 00042 0000040000000000 | HyperSpace - working set lists | HYPER_SPACE 00043 | and per process memory management | 00044 | structures mapped in this 8gb | 00045 00000401FFFFFFFF | region. | HYPER_SPACE_END 00046 +------------------------------------+ 00047 0000040200000000 | Remaining per process addresses for| 00048 | eventual 43-bit address space. | 00049 | | 00050 | | 00051 000007FFFFFFFFFF | | 00052 +------------------------------------+ 00053 . 00054 . 00055 +------------------------------------+ 00056 1FFFFF0000000000 | 8gb leaf level page table map | PTE_UBASE 00057 | for user space | 00058 1FFFFF01FFFFFFFF | | PTE_UTOP 00059 +------------------------------------+ 00060 +------------------------------------+ 00061 1FFFFFFFC0000000 | 8mb page directory (2nd level) | PDE_UBASE 00062 | table map for user space | 00063 1FFFFFFFC07FFFFF | | PDE_UTOP 00064 +------------------------------------+ 00065 +------------------------------------+ 00066 1FFFFFFFFFF00000 | 8KB parent directory (1st level) | PDE_UTBASE 00067 +------------------------------------+ 00068 . 00069 . 00070 +------------------------------------+ 00071 2000000000000000 | Hydra - 8gb | MM_SESSION_SPACE_DEFAULT 00072 | and per process memory management | 00073 | structures mapped in this 8gb | 00074 | region. | 00075 +------------------------------------+ 00076 . 00077 +------------------------------------+ 00078 3FFFFF0000000000 | 8gb leaf level page table map | PTE_SBASE 00079 | for session space | 00080 3FFFFF01FFFFFFFF | | PTE_STOP 00081 +------------------------------------+ 00082 +------------------------------------+ 00083 3FFFFFFFC0000000 | 8mb page directory (2nd level) | PDE_SBASE 00084 | table map for session space | 00085 3FFFFFFFC07FFFFF | | PDE_STOP 00086 +------------------------------------+ 00087 +------------------------------------+ 00088 3FFFFFFFFFF00000 | 8KB parent directory (1st level) | PDE_STBASE 00089 +------------------------------------+ 00090 . 00091 +------------------------------------+ 00092 8000000000000000 | physical addressable memory | KSEG3_BASE 00093 | for 44-bit of address space | 00094 80000FFFFFFFFFFF | mapped by VHPT 64KB page | KSEG3_LIMIT 00095 +------------------------------------+ 00096 . 00097 +------------------------------------+ 00098 9FFFFF00000000000| vhpt 64kb page for KSEG3 space | 00099 | (not used) | 00100 +------------------------------------+ 00101 . 00102 . 00103 +------------------------------------+ MM_SYSTEM_RANGE_START 00104 E000000000000000 | | KADDRESS_BASE 00105 +------------------------------------+ 00106 E000000080000000 | The HAL, kernel, initial drivers, | KSEG0_BASE 00107 | NLS data, and registry load in the | 00108 | first 16mb of this region which | 00109 | physically addresses memory. | 00110 | | 00111 | Kernel mode access only. | 00112 | | 00113 | Initial NonPaged Pool is within | 00114 | KSEG0 | 00115 | | KSEG2_BASE 00116 +------------------------------------+ 00117 E0000000A0000000 | System mapped views | MM_SYSTEM_VIEW_START 00118 | Win32k.sys | MM_SYSTEM_CACHE_END 00119 | | 00120 +------------------------------------+ 00121 E0000000FF000000 | Shared system page | KI_USER_SHARED_DATA 00122 +------------------------------------+ 00123 E0000000FF002000 | Reserved for the HAL. | 00124 | | 00125 | | 00126 E0000000FFFFFFFF | | 00127 +------------------------------------+ 00128 . 00129 . 00130 +------------------------------------+ 00131 E000000200000000 | | 00132 | | 00133 | | 00134 | | 00135 +------------------------------------+ 00136 E000000400000000 | The system cache working set | MM_SYSTEM_CACHE_WORKING_SET 00137 | | MM_SYSTEM_SPACE_START 00138 | information resides in this 8gb | 00139 | region. | 00140 +------------------------------------+ 00141 E000000600000000 | System cache resides here. | MM_SYSTEM_CACHE_START 00142 | Kernel mode access only. | 00143 | 1tb. | 00144 +------------------------------------+ 00145 E000010600000000 | Start of paged system area. | MM_PAGED_POOL_START 00146 | Kernel mode access only. | 00147 | 128gb. | 00148 +------------------------------------+ 00149 | | 00150 . 00151 . 00152 00153 In general, the next two areas (system PTE pool and nonpaged pool) will both 00154 be shifted upwards to conserve a PPE... 00155 00156 . 00157 . 00158 +------------------------------------+ 00159 E000012600000000 | System PTE pool. | MM_LOWEST_NONPAGED_SYSTEM_START 00160 | Kernel mode access only. | 00161 | 128gb. | 00162 +------------------------------------+ 00163 E000014600000000 | NonPaged pool. | MM_NON_PAGED_POOL_START 00164 | Kernel mode access only. | 00165 | 128gb. | 00166 | | 00167 E0000165FFFFFFFF | NonPaged System area | MM_NONPAGED_POOL_END 00168 +------------------------------------+ 00169 . 00170 . 00171 E000040000000000 +------------------------------------+ MM_PFN_DATABASE_START 00172 | PFN Database space | 00173 | Kernel mode access only. | 00174 | 2tb. | 00175 E000060000000000 +------------------------------------+ MM_PFN_DATABASE_END 00176 . MM_SYSTEM_SPACE_END 00177 . 00178 . 00179 +------------------------------------+ 00180 FFFFFF0000000000 | 8gb leaf level page table map | PTE_KBASE 00181 | for kernel space | 00182 FFFFFF01FFFFFFFF | | PTE_KTOP 00183 +------------------------------------+ 00184 +------------------------------------+ 00185 FFFFFFFFC0000000 | 8mb page directory (2nd level) | PDE_KBASE 00186 | table map for kernel space | 00187 FFFFFFFFC07FFFFF | | PDE_KTOP 00188 +------------------------------------+ 00189 +------------------------------------+ 00190 FFFFFFFFFFF00000 | 8KB parent directory (1st level) | PDE_KTBASE 00191 +------------------------------------+ 00192 00193 --*/ 00194 00195 #define _MM64_ 1 00196 00197 #define _MIALT4K_ 1 00198 // #define HYPERMAP 1 00199 00200 // 00201 // Define empty list markers. 00202 // 00203 00204 #define MM_EMPTY_LIST ((ULONG)0xFFFFFFFF) // 00205 #define MM_EMPTY_PTE_LIST ((ULONG)0xFFFFFFFF) // N.B. tied to MMPTE definition 00206 00207 #define MI_PTE_BASE_FOR_LOWEST_KERNEL_ADDRESS ((PMMPTE)PTE_KBASE) 00208 00209 // 00210 // 43-Bit virtual address mask. 00211 // 00212 00213 #define MASK_43 0x7FFFFFFFFFFUI64 // 00214 00215 // 00216 // 44-Bit Physical address mask. 00217 // 00218 00219 #define MASK_44 0xFFFFFFFFFFFUI64 00220 00221 #define MM_PAGES_IN_KSEG0 ((ULONG)((KSEG2_BASE - KSEG0_BASE) >> PAGE_SHIFT)) 00222 00223 extern ULONG_PTR MmKseg2Frame; 00224 extern ULONGLONG MmPageSizeInfo; 00225 00226 #define MM_USER_ADDRESS_RANGE_LIMIT (0xFFFFFFFFFFFFFFFFUI64) // user address range limit 00227 #define MM_MAXIMUM_ZERO_BITS 53 // maximum number of zero bits 00228 00229 // 00230 // PAGE_SIZE for Intel MERCED is 8k, virtual page is 20 bits with a PAGE_SHIFT 00231 // byte offset. 00232 // 00233 00234 #define MM_VIRTUAL_PAGE_FILLER (PAGE_SHIFT - 12) 00235 #define MM_VIRTUAL_PAGE_SIZE (64-PAGE_SHIFT) 00236 00237 // 00238 // Address space layout definitions. 00239 // 00240 00241 #define CODE_START KSEG0_BASE 00242 00243 #define CODE_END KSEG2_BASE 00244 00245 #define MM_SYSTEM_SPACE_START (KADDRESS_BASE + 0x400000000UI64) 00246 00247 #define MM_SYSTEM_SPACE_END (KADDRESS_BASE + 0x60000000000UI64) 00248 00249 #define PDE_TOP PDE_UTOP 00250 00251 // 00252 // Define Althernate 4KB permission table space for X86 00253 // 00254 00255 #define ALT4KB_PERMISSION_TABLE_START (UADDRESS_BASE + 0x40000000000) 00256 00257 #define ALT4KB_PERMISSION_TABLE_END (UADDRESS_BASE + 0x40000400000) 00258 00259 // 00260 // Define hyper space 00261 // 00262 00263 #define HYPER_SPACE ((PVOID)(UADDRESS_BASE + 0x40000800000)) 00264 00265 #define HYPER_SPACE_END (UADDRESS_BASE + 0x401FFFFFFFF) 00266 00267 // 00268 // Define area for mapping views into system space 00269 // 00270 00271 #define MM_SYSTEM_VIEW_START (KADDRESS_BASE + 0xA0000000) 00272 00273 #define MM_SYSTEM_VIEW_SIZE (48*1024*1024) 00274 00275 #define MM_SESSION_SPACE_DEFAULT (0x2000000000000000UI64) // make it the region 1 space 00276 00277 #define MM_SYSTEM_VIEW_START_IF_HYDRA MM_SYSTEM_VIEW_START 00278 00279 #define MM_SYSTEM_VIEW_SIZE_IF_HYDRA MM_SYSTEM_VIEW_SIZE 00280 00281 // 00282 // Define the start and maximum size for the system cache. 00283 // Maximum size 512MB. 00284 // 00285 00286 #define MM_SYSTEM_CACHE_WORKING_SET (KADDRESS_BASE + 0x400000000UI64) 00287 00288 #define MM_SYSTEM_CACHE_START (KADDRESS_BASE + 0x600000000UI64) 00289 00290 #define MM_SYSTEM_CACHE_END (KADDRESS_BASE + 0x1005FFFFFFFFUI64) 00291 00292 #define MM_MAXIMUM_SYSTEM_CACHE_SIZE \ 00293 (((ULONG_PTR)MM_SYSTEM_CACHE_END - (ULONG_PTR)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT) 00294 00295 #define MM_PAGED_POOL_START ((PVOID)(KADDRESS_BASE + 0x10600000000UI64)) 00296 00297 #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(KADDRESS_BASE + 0x12600000000UI64)) 00298 00299 #define MmProtopte_Base (KADDRESS_BASE) 00300 00301 #define MM_NONPAGED_POOL_END ((PVOID)(KADDRESS_BASE + 0x16600000000UI64 - (16 * PAGE_SIZE))) 00302 00303 #define MM_CRASH_DUMP_VA ((PVOID)(KADDRESS_BASE + 0xFF800000)) 00304 00305 // EPC VA at 0xFFA00000 (see ntia64.h) 00306 00307 #define MM_DEBUG_VA ((PVOID)(KADDRESS_BASE + 0xFF900000)) 00308 00309 #define NON_PAGED_SYSTEM_END (KADDRESS_BASE + 0x16600000000UI64) //quadword aligned. 00310 00311 #define MM_PFN_DATABASE_START (KADDRESS_BASE + 0x40000000000UI64) 00312 00313 #define MM_PFN_DATABASE_END (KADDRESS_BASE + 0x60000000000UI64) 00314 00315 extern ULONG MiMaximumSystemCacheSize; 00316 00317 // 00318 // Define absolute minumum and maximum count for system ptes. 00319 // 00320 00321 #define MM_MINIMUM_SYSTEM_PTES 7000 00322 00323 #define MM_MAXIMUM_SYSTEM_PTES 50000 00324 00325 #define MM_DEFAULT_SYSTEM_PTES 11000 00326 00327 // 00328 // Pool limits 00329 // 00330 00331 // 00332 // The maximim amount of nonpaged pool that can be initially created. 00333 // 00334 00335 #define MM_MAX_INITIAL_NONPAGED_POOL ((SIZE_T)(128 * 1024 * 1024)) 00336 00337 // 00338 // The total amount of nonpaged pool (initial pool + expansion + system PTEs). 00339 // 00340 00341 #define MM_MAX_ADDITIONAL_NONPAGED_POOL (((SIZE_T)128 * 1024 * 1024 * 1024) - 16) 00342 00343 // 00344 // The maximum amount of paged pool that can be created. 00345 // 00346 00347 #define MM_MAX_PAGED_POOL ((SIZE_T)128 * 1024 * 1024 * 1024) 00348 00349 // 00350 // Define the maximum default for pool (user specified 0 in registry). 00351 // 00352 00353 #define MM_MAX_DEFAULT_NONPAGED_POOL ((SIZE_T)8 * 1024 * 1024 * 1024) 00354 00355 00356 // 00357 // Structure layout defintions. 00358 // 00359 00360 #define MM_PROTO_PTE_ALIGNMENT ((ULONG)PAGE_SIZE) 00361 00362 // 00363 // Define the address bits mapped by PPE and PDE entries. 00364 // 00365 // A PPE entry maps 10+10+13 = 33 bits of address space. 00366 // A PDE entry maps 10+13 = 23 bits of address space. 00367 // 00368 00369 #define PAGE_DIRECTORY1_MASK (((ULONG_PTR)1 << PDI1_SHIFT) - 1) 00370 #define PAGE_DIRECTORY2_MASK (((ULONG_PTR)1 << PDI_SHIFT) -1) 00371 00372 #define MM_VA_MAPPED_BY_PDE ((ULONG_PTR)1 << PDI_SHIFT) 00373 00374 #define LOWEST_IO_ADDRESS 0xa0000 00375 00376 // 00377 // The number of bits in a physical address. 00378 // 00379 00380 #define PHYSICAL_ADDRESS_BITS 44 00381 00382 #define MM_MAXIMUM_NUMBER_OF_COLORS (1) 00383 00384 // 00385 // MERCED does not require support for colored pages. 00386 // 00387 00388 #define MM_NUMBER_OF_COLORS (1) 00389 00390 // 00391 // Mask for obtaining color from a physical page number. 00392 // 00393 00394 #define MM_COLOR_MASK (0) 00395 00396 // 00397 // Boundary for aligned pages of like color upon. 00398 // 00399 00400 #define MM_COLOR_ALIGNMENT (0) 00401 00402 // 00403 // Mask for isolating color from virtual address. 00404 // 00405 00406 #define MM_COLOR_MASK_VIRTUAL (0) 00407 00408 // 00409 // Define 256k worth of secondary colors. 00410 // 00411 00412 #define MM_SECONDARY_COLORS_DEFAULT (64) 00413 00414 #define MM_SECONDARY_COLORS_MIN (2) 00415 00416 #define MM_SECONDARY_COLORS_MAX (1024) 00417 00418 // 00419 // Mask for isolating secondary color from physical page number; 00420 // 00421 00422 extern ULONG MmSecondaryColorMask; 00423 00424 // 00425 // Maximum number of paging files. 00426 // 00427 00428 #define MAX_PAGE_FILES 16 00429 00430 00431 // 00432 // Hyper space definitions. 00433 // 00434 00435 #define FIRST_MAPPING_PTE ((PMMPTE)HYPER_SPACE) 00436 00437 #define NUMBER_OF_MAPPING_PTES 255 00438 #define LAST_MAPPING_PTE \ 00439 ((ULONG_PTR)((ULONG_PTR)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE))) 00440 00441 #define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG_PTR)LAST_MAPPING_PTE + PAGE_SIZE)) 00442 00443 #define ZEROING_PAGE_PTE ((PMMPTE)((ULONG_PTR)IMAGE_MAPPING_PTE + PAGE_SIZE)) 00444 00445 #define WORKING_SET_LIST ((PVOID)((ULONG_PTR)ZEROING_PAGE_PTE + PAGE_SIZE)) 00446 00447 #define MM_MAXIMUM_WORKING_SET \ 00448 ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb 00449 00450 #define MM_WORKING_SET_END (UADDRESS_BASE + 0x3FFFFFFFFFFUI64) 00451 00452 // 00453 // Define memory attributes fields within PTE 00454 // 00455 00456 #define MM_PTE_TB_MA_WB (0x0 << 2) // cacheable, write-back 00457 #define MM_PTE_TB_MA_UC (0x4 << 2) // uncheable 00458 #define MM_PTE_TB_MA_UCE (0x5 << 2) // uncheable, exporting fetchadd 00459 #define MM_PTE_TB_MA_WC (0x6 << 2) // uncheable, coalesing 00460 #define MM_PTE_TB_MA_NATPAGE (0x7 << 2) // Nat Page 00461 00462 // 00463 // Define masks for the PTE cache attributes 00464 // 00465 00466 #define MM_PTE_CACHE_ENABLED 0 // WB 00467 #define MM_PTE_CACHE_DISABLED 4 // UC 00468 #define MM_PTE_CACHE_DISPLAY 6 // WC 00469 #define MM_PTE_CACHE_RESERVED 1 // special encoding to cause a TLB miss 00470 00471 // 00472 // Define masks for fields within the PTE. 00473 // 00474 00475 #define MM_PTE_OWNER_MASK 0x0180 00476 #define MM_PTE_VALID_MASK 1 00477 #define MM_PTE_CACHE_DISABLE_MASK MM_PTE_TB_MA_UC 00478 #define MM_PTE_ACCESS_MASK 0x0020 00479 #define MM_PTE_DIRTY_MASK 0x0040 00480 #define MM_PTE_EXECUTE_MASK 0x0200 00481 #define MM_PTE_WRITE_MASK 0x0400 00482 #define MM_PTE_LARGE_PAGE_MASK 0 00483 #define MM_PTE_COPY_ON_WRITE_MASK ((ULONG)1 << (PAGE_SHIFT-1)) 00484 00485 #define MM_PTE_PROTOTYPE_MASK 0x0002 00486 #define MM_PTE_TRANSITION_MASK 0x0080 00487 00488 // 00489 // Bit fields to or into PTE to make a PTE valid based on the 00490 // protection field of the invalid PTE. 00491 // 00492 00493 #define MM_PTE_NOACCESS 0x0 00494 #define MM_PTE_READONLY 0x0 00495 #define MM_PTE_READWRITE MM_PTE_WRITE_MASK 00496 #define MM_PTE_WRITECOPY MM_PTE_COPY_ON_WRITE_MASK 00497 #define MM_PTE_EXECUTE MM_PTE_EXECUTE_MASK 00498 #define MM_PTE_EXECUTE_READ MM_PTE_EXECUTE_MASK 00499 #define MM_PTE_EXECUTE_READWRITE MM_PTE_EXECUTE_MASK | MM_PTE_WRITE_MASK 00500 #define MM_PTE_EXECUTE_WRITECOPY MM_PTE_EXECUTE_MASK | MM_PTE_COPY_ON_WRITE_MASK 00501 #define MM_PTE_GUARD 0x0 00502 #define MM_PTE_CACHE MM_PTE_TB_MA_WB 00503 #define MM_PTE_NOCACHE MM_PTE_CACHE // PAGE_NOCACHE is cached 00504 #define MM_PTE_EXC_DEFER 0x10000000000000 // defer exception 00505 00506 00507 #define MM_PROTECT_FIELD_SHIFT 2 00508 00509 // 00510 // Define masks for fields within the EM TB entry 00511 // 00512 00513 #define MM_PTE_TB_VALID 0x0001 00514 #define MM_PTE_TB_ACCESSED 0x0020 00515 #define MM_PTE_TB_MODIFIED 0x0040 00516 #define MM_PTE_TB_WRITE 0x0400 00517 #define MM_PTE_TB_EXECUTE 0x0200 // read/execute on EM 00518 #define MM_PTE_TB_EXC_DEFER 0x10000000000000 // defer exception 00519 00520 // 00521 // Define masks for PTE PageSize field 00522 // 00523 00524 #define MM_PTE_1MB_PAGE 20 00525 #define MM_PTE_2MB_PAGE 21 00526 #define MM_PTE_4MB_PAGE 22 00527 #define MM_PTE_16MB_PAGE 24 00528 #define MM_PTE_64MB_PAGE 26 00529 #define MM_PTE_256MB_PAGE 28 00530 00531 // 00532 // Define the number of VHPT pages 00533 // 00534 00535 #define MM_VHPT_PAGES 32 00536 00537 // 00538 // Bits available for the software working set index within the hardware PTE. 00539 // 00540 00541 #define MI_MAXIMUM_PTE_WORKING_SET_INDEX (1 << _HARDWARE_PTE_WORKING_SET_BITS) 00542 00543 // 00544 // Zero PTE 00545 // 00546 00547 #define MM_ZERO_PTE 0 00548 00549 // 00550 // Zero Kernel PTE 00551 // 00552 00553 #define MM_ZERO_KERNEL_PTE 0 00554 00555 // 00556 // A demand zero PTE with a protection or PAGE_READWRITE. 00557 // 00558 00559 #define MM_DEMAND_ZERO_WRITE_PTE ((ULONGLONG)MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00560 00561 00562 // 00563 // A demand zero PTE with a protection or PAGE_READWRITE for system space. 00564 // 00565 00566 #define MM_KERNEL_DEMAND_ZERO_PTE ((ULONGLONG)MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00567 00568 // 00569 // A no access PTE for system space. 00570 // 00571 00572 #define MM_KERNEL_NOACCESS_PTE ((ULONGLONG)MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) 00573 00574 extern ULONG_PTR MmPteGlobal; // One if processor supports Global Page, else zero. 00575 00576 // 00577 // Kernel stack alignment requirements. 00578 // 00579 00580 #define MM_STACK_ALIGNMENT 0x0 00581 00582 #define MM_STACK_OFFSET 0x0 00583 00584 // 00585 // System process definitions 00586 // 00587 00588 #define PDE_PER_PAGE ((ULONG)(PAGE_SIZE/(1 << PTE_SHIFT))) 00589 00590 #define PTE_PER_PAGE ((ULONG)(PAGE_SIZE/(1 << PTE_SHIFT))) 00591 00592 #define PTE_PER_PAGE_BITS 11 // This handles the case where the page is full 00593 00594 #if PTE_PER_PAGE_BITS > 32 00595 error - too many bits to fit into MMPTE_SOFTWARE or MMPFN.u1 00596 #endif 00597 00598 // 00599 // Number of page table pages for user addresses. 00600 // 00601 00602 #define MM_USER_PAGE_TABLE_PAGES PTE_PER_PAGE 00603 00604 00605 //++ 00606 //VOID 00607 //MI_MAKE_VALID_PTE ( 00608 // OUT OUTPTE, 00609 // IN FRAME, 00610 // IN PMASK, 00611 // IN PPTE 00612 // ); 00613 // 00614 // Routine Description: 00615 // 00616 // This macro makes a valid PTE from a page frame number, protection mask, 00617 // and owner. 00618 // 00619 // Argments 00620 // 00621 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00622 // 00623 // FRAME - Supplies the page frame number for the PTE. 00624 // 00625 // PMASK - Supplies the protection to set in the transition PTE. 00626 // 00627 // PPTE - Supplies a pointer to the PTE which is being made valid. 00628 // For prototype PTEs NULL should be specified. 00629 // 00630 // Return Value: 00631 // 00632 // None. 00633 // 00634 //-- 00635 00636 #if !defined(_MIALT4K_) 00637 00638 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 00639 (OUTPTE).u.Long = 0; \ 00640 (OUTPTE).u.Hard.Valid = 1; \ 00641 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 00642 (OUTPTE).u.Hard.Accessed = 1; \ 00643 (OUTPTE).u.Hard.Exception = 1; \ 00644 (OUTPTE).u.Hard.PageFrameNumber = FRAME; \ 00645 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 00646 (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]); 00647 00648 #endif 00649 00650 //++ 00651 //VOID 00652 //MI_MAKE_VALID_PTE_TRANSITION ( 00653 // IN OUT OUTPTE 00654 // IN PROTECT 00655 // ); 00656 // 00657 // Routine Description: 00658 // 00659 // This macro takes a valid pte and turns it into a transition PTE. 00660 // 00661 // Argments 00662 // 00663 // OUTPTE - Supplies the current valid PTE. This PTE is then 00664 // modified to become a transition PTE. 00665 // 00666 // PROTECT - Supplies the protection to set in the transition PTE. 00667 // 00668 // Return Value: 00669 // 00670 // None. 00671 // 00672 //-- 00673 00674 #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \ 00675 (OUTPTE).u.Soft.Transition = 1; \ 00676 (OUTPTE).u.Soft.Valid = 0; \ 00677 (OUTPTE).u.Soft.Prototype = 0; \ 00678 (OUTPTE).u.Soft.Protection = PROTECT; 00679 00680 //++ 00681 //VOID 00682 //MI_MAKE_TRANSITION_PTE ( 00683 // OUT OUTPTE, 00684 // IN PAGE, 00685 // IN PROTECT, 00686 // IN PPTE 00687 // ); 00688 // 00689 // Routine Description: 00690 // 00691 // This macro takes a valid pte and turns it into a transition PTE. 00692 // 00693 // Argments 00694 // 00695 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00696 // 00697 // PAGE - Supplies the page frame number for the PTE. 00698 // 00699 // PROTECT - Supplies the protection to set in the transition PTE. 00700 // 00701 // PPTE - Supplies a pointer to the PTE, this is used to determine 00702 // the owner of the PTE. 00703 // 00704 // Return Value: 00705 // 00706 // None. 00707 // 00708 //-- 00709 00710 #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \ 00711 (OUTPTE).u.Long = 0; \ 00712 (OUTPTE).u.Trans.PageFrameNumber = PAGE; \ 00713 (OUTPTE).u.Trans.Transition = 1; \ 00714 (OUTPTE).u.Trans.Protection = PROTECT; 00715 00716 00717 00718 //++ 00719 //VOID 00720 //MI_MAKE_TRANSITION_PTE_VALID ( 00721 // OUT OUTPTE, 00722 // IN PPTE 00723 // ); 00724 // 00725 // Routine Description: 00726 // 00727 // This macro takes a transition pte and makes it a valid PTE. 00728 // 00729 // Argments 00730 // 00731 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00732 // 00733 // PPTE - Supplies a pointer to the transition PTE. 00734 // 00735 // Return Value: 00736 // 00737 // None. 00738 // 00739 //-- 00740 00741 #if !defined(_MIALT4K_) 00742 00743 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 00744 ASSERT (((PPTE)->u.Hard.Valid == 0) && \ 00745 ((PPTE)->u.Trans.Prototype == 0) && \ 00746 ((PPTE)->u.Trans.Transition == 1)); \ 00747 (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000; \ 00748 (OUTPTE).u.Hard.Valid = 1; \ 00749 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 00750 (OUTPTE).u.Hard.Accessed = 1; \ 00751 (OUTPTE).u.Hard.Exception = 1; \ 00752 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 00753 (OUTPTE).u.Long |= (MmProtectToPteMask[(PPTE)->u.Trans.Protection]); 00754 #endif 00755 00756 //++ 00757 //VOID 00758 //MI_SET_PTE_IN_WORKING_SET ( 00759 // OUT PMMPTE PTE, 00760 // IN ULONG WSINDEX 00761 // ); 00762 // 00763 // Routine Description: 00764 // 00765 // This macro inserts the specified working set index into the argument PTE. 00766 // 00767 // No TB invalidation is needed for other processors (or this one) even 00768 // though the entry may already be in a TB - it's just a software field 00769 // update and doesn't affect miss resolution. 00770 // 00771 // Arguments 00772 // 00773 // OUTPTE - Supplies the PTE in which to insert the working set index. 00774 // 00775 // WSINDEX - Supplies the working set index for the PTE. 00776 // 00777 // Return Value: 00778 // 00779 // None. 00780 // 00781 //-- 00782 00783 #define MI_SET_PTE_IN_WORKING_SET(PTE, WSINDEX) { \ 00784 MMPTE _TempPte; \ 00785 _TempPte = *(PTE); \ 00786 _TempPte.u.Hard.SoftwareWsIndex = (WSINDEX); \ 00787 *(PTE) = _TempPte; \ 00788 } 00789 00790 //++ 00791 //ULONG WsIndex 00792 //MI_GET_WORKING_SET_FROM_PTE( 00793 // IN PMMPTE PTE 00794 // ); 00795 // 00796 // Routine Description: 00797 // 00798 // This macro returns the working set index from the argument PTE. 00799 // 00800 // Arguments 00801 // 00802 // PTE - Supplies the PTE to extract the working set index from. 00803 // 00804 // Return Value: 00805 // 00806 // This macro returns the working set index for the argument PTE. 00807 // 00808 //-- 00809 00810 #define MI_GET_WORKING_SET_FROM_PTE(PTE) (ULONG)(PTE)->u.Hard.SoftwareWsIndex 00811 00812 //++ 00813 //VOID 00814 //MI_SET_PTE_WRITE_COMBINE ( 00815 // IN MMPTE PTE 00816 // ); 00817 // 00818 // Routine Description: 00819 // 00820 // This macro sets the write combined bit(s) in the specified PTE. 00821 // 00822 // Arguments 00823 // 00824 // PTE - Supplies the PTE to set dirty. 00825 // 00826 // Return Value: 00827 // 00828 // None. 00829 // 00830 //-- 00831 00832 #define MI_SET_PTE_WRITE_COMBINE(PTE) \ 00833 ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISABLED) 00834 00835 #define MI_SET_PTE_WRITE_COMBINE2(PTE) \ 00836 ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISPLAY) 00837 00838 00839 //++ 00840 //VOID 00841 //MI_SET_PTE_DIRTY ( 00842 // IN MMPTE PTE 00843 // ); 00844 // 00845 // Routine Description: 00846 // 00847 // This macro sets the dirty bit(s) in the specified PTE. 00848 // 00849 // Argments 00850 // 00851 // PTE - Supplies the PTE to set dirty. 00852 // 00853 // Return Value: 00854 // 00855 // None. 00856 // 00857 //-- 00858 00859 #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Hard.Dirty = 1 00860 00861 00862 //++ 00863 //VOID 00864 //MI_SET_PTE_CLEAN ( 00865 // IN MMPTE PTE 00866 // ); 00867 // 00868 // Routine Description: 00869 // 00870 // This macro clears the dirty bit(s) in the specified PTE. 00871 // 00872 // Argments 00873 // 00874 // PTE - Supplies the PTE to set clear. 00875 // 00876 // Return Value: 00877 // 00878 // None. 00879 // 00880 //-- 00881 00882 #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Hard.Dirty = 0 00883 00884 00885 00886 //++ 00887 //VOID 00888 //MI_IS_PTE_DIRTY ( 00889 // IN MMPTE PTE 00890 // ); 00891 // 00892 // Routine Description: 00893 // 00894 // This macro checks the dirty bit(s) in the specified PTE. 00895 // 00896 // Argments 00897 // 00898 // PTE - Supplies the PTE to check. 00899 // 00900 // Return Value: 00901 // 00902 // TRUE if the page is dirty (modified), FALSE otherwise. 00903 // 00904 //-- 00905 00906 #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) 00907 00908 00909 00910 //++ 00911 //VOID 00912 //MI_SET_GLOBAL_BIT_IF_SYSTEM ( 00913 // OUT OUTPTE, 00914 // IN PPTE 00915 // ); 00916 // 00917 // Routine Description: 00918 // 00919 // This macro sets the global bit if the pointer PTE is within 00920 // system space. 00921 // 00922 // Argments 00923 // 00924 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00925 // 00926 // PPTE - Supplies a pointer to the PTE becoming valid. 00927 // 00928 // Return Value: 00929 // 00930 // None. 00931 // 00932 //-- 00933 00934 #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE) 00935 00936 00937 00938 //++ 00939 //VOID 00940 //MI_SET_GLOBAL_STATE ( 00941 // IN MMPTE PTE, 00942 // IN ULONG STATE 00943 // ); 00944 // 00945 // Routine Description: 00946 // 00947 // This macro sets the global bit in the PTE. if the pointer PTE is within 00948 // 00949 // Argments 00950 // 00951 // PTE - Supplies the PTE to set global state into. 00952 // 00953 // STATE - Supplies 1 if global, 0 if not. 00954 // 00955 // Return Value: 00956 // 00957 // None. 00958 // 00959 //-- 00960 00961 #define MI_SET_GLOBAL_STATE(PTE,STATE) 00962 00963 00964 00965 //++ 00966 //VOID 00967 //MI_ENABLE_CACHING ( 00968 // IN MMPTE PTE 00969 // ); 00970 // 00971 // Routine Description: 00972 // 00973 // This macro takes a valid PTE and sets the caching state to be 00974 // enabled. 00975 // 00976 // Argments 00977 // 00978 // PTE - Supplies a valid PTE. 00979 // 00980 // Return Value: 00981 // 00982 // None. 00983 // 00984 //-- 00985 00986 #define MI_ENABLE_CACHING(PTE) ((PTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED) 00987 00988 00989 00990 //++ 00991 //VOID 00992 //MI_DISABLE_CACHING ( 00993 // IN MMPTE PTE 00994 // ); 00995 // 00996 // Routine Description: 00997 // 00998 // This macro takes a valid PTE and sets the caching state to be 00999 // disabled. 01000 // 01001 // Argments 01002 // 01003 // PTE - Supplies a pointer to the valid PTE. 01004 // 01005 // Return Value: 01006 // 01007 // None. 01008 // 01009 //-- 01010 01011 #define MI_DISABLE_CACHING(PTE) ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISABLED) 01012 01013 01014 01015 01016 //++ 01017 //BOOLEAN 01018 //MI_IS_CACHING_DISABLED ( 01019 // IN PMMPTE PPTE 01020 // ); 01021 // 01022 // Routine Description: 01023 // 01024 // This macro takes a valid PTE and returns TRUE if caching is 01025 // disabled. 01026 // 01027 // Argments 01028 // 01029 // PPTE - Supplies a pointer to the valid PTE. 01030 // 01031 // Return Value: 01032 // 01033 // TRUE if caching is disabled, FALSE if it is enabled. 01034 // 01035 //-- 01036 01037 #define MI_IS_CACHING_DISABLED(PPTE) \ 01038 ((PPTE)->u.Hard.Cache == MM_PTE_CACHE_DISABLED) 01039 01040 01041 01042 //++ 01043 //VOID 01044 //MI_SET_PFN_DELETED ( 01045 // IN PMMPFN PPFN 01046 // ); 01047 // 01048 // Routine Description: 01049 // 01050 // This macro takes a pointer to a PFN element and indicates that 01051 // the PFN is no longer in use. 01052 // 01053 // Argments 01054 // 01055 // PPTE - Supplies a pointer to the PFN element. 01056 // 01057 // Return Value: 01058 // 01059 // none. 01060 // 01061 //-- 01062 01063 #define MI_SET_PFN_DELETED(PPFN) (((PPFN)->PteAddress = (PMMPTE)((INT_PTR)(LONG)0xFFFFFFFF))) 01064 01065 01066 01067 01068 //++ 01069 //BOOLEAN 01070 //MI_IS_PFN_DELETED ( 01071 // IN PMMPFN PPFN 01072 // ); 01073 // 01074 // Routine Description: 01075 // 01076 // This macro takes a pointer to a PFN element a determines if 01077 // the PFN is no longer in use. 01078 // 01079 // Argments 01080 // 01081 // PPTE - Supplies a pointer to the PFN element. 01082 // 01083 // Return Value: 01084 // 01085 // TRUE if PFN is no longer used, FALSE if it is still being used. 01086 // 01087 //-- 01088 01089 #define MI_IS_PFN_DELETED(PPFN) \ 01090 ((PPFN)->PteAddress == (PMMPTE)((INT_PTR)(LONG)0xFFFFFFFF)) 01091 01092 01093 //++ 01094 //VOID 01095 //MI_CHECK_PAGE_ALIGNMENT ( 01096 // IN ULONG PAGE, 01097 // IN PMMPTE PPTE 01098 // ); 01099 // 01100 // Routine Description: 01101 // 01102 // This macro takes a PFN element number (Page) and checks to see 01103 // if the virtual alignment for the previous address of the page 01104 // is compatable with the new address of the page. If they are 01105 // not compatible, the D cache is flushed. 01106 // 01107 // Argments 01108 // 01109 // PAGE - Supplies the PFN element. 01110 // PPTE - Supplies a pointer to the new PTE which will contain the page. 01111 // 01112 // Return Value: 01113 // 01114 // none. 01115 // 01116 //-- 01117 01118 // does nothing on MERCED. 01119 01120 #define MI_CHECK_PAGE_ALIGNMENT(PAGE,PPTE) 01121 01122 01123 01124 01125 //++ 01126 //VOID 01127 //MI_INITIALIZE_HYPERSPACE_MAP ( 01128 // VOID 01129 // ); 01130 // 01131 // Routine Description: 01132 // 01133 // This macro initializes the PTEs reserved for double mapping within 01134 // hyperspace. 01135 // 01136 // Argments 01137 // 01138 // None. 01139 // 01140 // Return Value: 01141 // 01142 // None. 01143 // 01144 //-- 01145 01146 // does nothing on MERCED. 01147 01148 #define MI_INITIALIZE_HYPERSPACE_MAP(INDEX) 01149 01150 01151 //++ 01152 //ULONG 01153 //MI_GET_PAGE_COLOR_FROM_PTE ( 01154 // IN PMMPTE PTEADDRESS 01155 // ); 01156 // 01157 // Routine Description: 01158 // 01159 // This macro determines the pages color based on the PTE address 01160 // that maps the page. 01161 // 01162 // Argments 01163 // 01164 // PTEADDRESS - Supplies the PTE address the page is (or was) mapped at. 01165 // 01166 // Return Value: 01167 // 01168 // The pages color. 01169 // 01170 //-- 01171 01172 #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \ 01173 ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask)) 01174 01175 01176 01177 //++ 01178 //ULONG 01179 //MI_GET_PAGE_COLOR_FROM_VA ( 01180 // IN PVOID ADDRESS 01181 // ); 01182 // 01183 // Routine Description: 01184 // 01185 // This macro determines the pages color based on the PTE address 01186 // that maps the page. 01187 // 01188 // Argments 01189 // 01190 // ADDRESS - Supplies the address the page is (or was) mapped at. 01191 // 01192 // Return Value: 01193 // 01194 // The pages color. 01195 // 01196 //-- 01197 01198 01199 #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \ 01200 ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask)) 01201 01202 01203 //++ 01204 //ULONG 01205 //MI_GET_PAGE_COLOR_FROM_SESSION ( 01206 // IN PMM_SESSION_SPACE SessionSpace 01207 // ); 01208 // 01209 // Routine Description: 01210 // 01211 // This macro determines the page's color based on the PTE address 01212 // that maps the page. 01213 // 01214 // Arguments 01215 // 01216 // SessionSpace - Supplies the session space the page will be mapped into. 01217 // 01218 // Return Value: 01219 // 01220 // The page's color. 01221 // 01222 //-- 01223 01224 01225 #define MI_GET_PAGE_COLOR_FROM_SESSION(_SessionSpace) \ 01226 ((ULONG)((_SessionSpace->Color++) & MmSecondaryColorMask)) 01227 01228 01229 //++ 01230 //ULONG 01231 //MI_PAGE_COLOR_PTE_PROCESS ( 01232 // IN PCHAR COLOR, 01233 // IN PMMPTE PTE 01234 // ); 01235 // 01236 // Routine Description: 01237 // 01238 // This macro determines the pages color based on the PTE address 01239 // that maps the page. 01240 // 01241 // Argments 01242 // 01243 // 01244 // Return Value: 01245 // 01246 // The pages color. 01247 // 01248 //-- 01249 01250 01251 #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \ 01252 (ULONG)((ULONG_PTR)((*(COLOR))++) & MmSecondaryColorMask) 01253 01254 01255 01256 //++ 01257 //ULONG 01258 //MI_PAGE_COLOR_VA_PROCESS ( 01259 // IN PVOID ADDRESS, 01260 // IN PEPROCESS COLOR 01261 // ); 01262 // 01263 // Routine Description: 01264 // 01265 // This macro determines the pages color based on the PTE address 01266 // that maps the page. 01267 // 01268 // Argments 01269 // 01270 // ADDRESS - Supplies the address the page is (or was) mapped at. 01271 // 01272 // Return Value: 01273 // 01274 // The pages color. 01275 // 01276 //-- 01277 01278 #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \ 01279 ((ULONG)((*(COLOR))++) & MmSecondaryColorMask) 01280 01281 01282 01283 //++ 01284 //ULONG 01285 //MI_GET_NEXT_COLOR ( 01286 // IN ULONG COLOR 01287 // ); 01288 // 01289 // Routine Description: 01290 // 01291 // This macro returns the next color in the sequence. 01292 // 01293 // Argments 01294 // 01295 // COLOR - Supplies the color to return the next of. 01296 // 01297 // Return Value: 01298 // 01299 // Next color in sequence. 01300 // 01301 //-- 01302 01303 #define MI_GET_NEXT_COLOR(COLOR) ((COLOR + 1) & MM_COLOR_MASK) 01304 01305 01306 //++ 01307 //ULONG 01308 //MI_GET_PREVIOUS_COLOR ( 01309 // IN ULONG COLOR 01310 // ); 01311 // 01312 // Routine Description: 01313 // 01314 // This macro returns the previous color in the sequence. 01315 // 01316 // Argments 01317 // 01318 // COLOR - Supplies the color to return the previous of. 01319 // 01320 // Return Value: 01321 // 01322 // Previous color in sequence. 01323 // 01324 //-- 01325 01326 #define MI_GET_PREVIOUS_COLOR(COLOR) (0) 01327 01328 01329 #define MI_GET_SECONDARY_COLOR(PAGE,PFN) ((ULONG)(PAGE & MmSecondaryColorMask)) 01330 01331 01332 #define MI_GET_COLOR_FROM_SECONDARY(SECONDARY_COLOR) (0) 01333 01334 01335 //++ 01336 //VOID 01337 //MI_GET_MODIFIED_PAGE_BY_COLOR ( 01338 // OUT ULONG PAGE, 01339 // IN ULONG COLOR 01340 // ); 01341 // 01342 // Routine Description: 01343 // 01344 // This macro returns the first page destined for a paging 01345 // file with the desired color. It does NOT remove the page 01346 // from its list. 01347 // 01348 // Argments 01349 // 01350 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01351 // returned if there is no page of the specified color. 01352 // 01353 // COLOR - Supplies the color of page to locate. 01354 // 01355 // Return Value: 01356 // 01357 // none. 01358 // 01359 //-- 01360 01361 #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \ 01362 PAGE = MmModifiedPageListByColor[COLOR].Flink 01363 01364 01365 //++ 01366 //VOID 01367 //MI_GET_MODIFIED_PAGE_ANY_COLOR ( 01368 // OUT ULONG PAGE, 01369 // IN OUT ULONG COLOR 01370 // ); 01371 // 01372 // Routine Description: 01373 // 01374 // This macro returns the first page destined for a paging 01375 // file with the desired color. If not page of the desired 01376 // color exists, all colored lists are searched for a page. 01377 // It does NOT remove the page from its list. 01378 // 01379 // Argments 01380 // 01381 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01382 // returned if there is no page of the specified color. 01383 // 01384 // COLOR - Supplies the color of page to locate and returns the 01385 // color of the page located. 01386 // 01387 // Return Value: 01388 // 01389 // none. 01390 // 01391 //-- 01392 01393 #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \ 01394 { \ 01395 if (MmTotalPagesForPagingFile == 0) { \ 01396 PAGE = MM_EMPTY_LIST; \ 01397 } else { \ 01398 PAGE = MmModifiedPageListByColor[COLOR].Flink; \ 01399 } \ 01400 } 01401 01402 01403 01404 //++ 01405 //VOID 01406 //MI_MAKE_VALID_PTE_WRITE_COPY ( 01407 // IN OUT PMMPTE PTE 01408 // ); 01409 // 01410 // Routine Description: 01411 // 01412 // This macro checks to see if the PTE indicates that the 01413 // page is writable and if so it clears the write bit and 01414 // sets the copy-on-write bit. 01415 // 01416 // Argments 01417 // 01418 // PTE - Supplies the PTE to operate upon. 01419 // 01420 // Return Value: 01421 // 01422 // None. 01423 // 01424 //-- 01425 01426 #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ 01427 if ((PPTE)->u.Hard.Write == 1) { \ 01428 (PPTE)->u.Hard.CopyOnWrite = 1; \ 01429 (PPTE)->u.Hard.Write = 0; \ 01430 } 01431 01432 01433 //++ 01434 //ULONG 01435 //MI_DETERMINE_OWNER ( 01436 // IN MMPTE PPTE 01437 // ); 01438 // 01439 // Routine Description: 01440 // 01441 // This macro examines the virtual address of the PTE and determines 01442 // if the PTE resides in system space or user space. 01443 // 01444 // Argments 01445 // 01446 // PTE - Supplies the PTE to operate upon. 01447 // 01448 // Return Value: 01449 // 01450 // 3 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01451 // 01452 //-- 01453 01454 #if defined(_MIALT4K_) 01455 01456 #define MI_DETERMINE_OWNER(PPTE) \ 01457 ((((((PPTE) >= (PMMPTE)PTE_UBASE) && ((PPTE) <= MiHighestUserPte))) || \ 01458 (MI_IS_ALT_PAGE_TABLE_ADDRESS(PPTE))) ? 3 : 0) 01459 01460 #else 01461 01462 #define MI_DETERMINE_OWNER(PPTE) \ 01463 ((((PPTE) >= (PMMPTE)PTE_UBASE) && \ 01464 ((PPTE) <= MiHighestUserPte)) ? 3 : 0) 01465 #endif 01466 01467 01468 //++ 01469 //VOID 01470 //MI_SET_ACCESSED_IN_PTE ( 01471 // IN OUT MMPTE PPTE 01472 // ); 01473 // 01474 // Routine Description: 01475 // 01476 // This macro sets the ACCESSED field in the PTE. 01477 // 01478 // Argments 01479 // 01480 // PTE - Supplies the PTE to operate upon. 01481 // 01482 // Return Value: 01483 // 01484 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01485 // 01486 //-- 01487 01488 #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) 01489 01490 01491 01492 //++ 01493 //ULONG 01494 //MI_GET_ACCESSED_IN_PTE ( 01495 // IN OUT MMPTE PPTE 01496 // ); 01497 // 01498 // Routine Description: 01499 // 01500 // This macro returns the state of the ACCESSED field in the PTE. 01501 // 01502 // Argments 01503 // 01504 // PTE - Supplies the PTE to operate upon. 01505 // 01506 // Return Value: 01507 // 01508 // The state of the ACCESSED field. 01509 // 01510 //-- 01511 01512 #define MI_GET_ACCESSED_IN_PTE(PPTE) 0 01513 01514 01515 01516 //++ 01517 //VOID 01518 //MI_SET_OWNER_IN_PTE ( 01519 // IN PMMPTE PPTE 01520 // IN ULONG OWNER 01521 // ); 01522 // 01523 // Routine Description: 01524 // 01525 // This macro sets the owner field in the PTE. 01526 // 01527 // Argments 01528 // 01529 // PTE - Supplies the PTE to operate upon. 01530 // 01531 // Return Value: 01532 // 01533 // None. 01534 // 01535 //-- 01536 01537 #define MI_SET_OWNER_IN_PTE(PPTE,OWNER) 01538 01539 01540 01541 01542 //++ 01543 //ULONG 01544 //MI_GET_OWNER_IN_PTE ( 01545 // IN PMMPTE PPTE 01546 // ); 01547 // 01548 // Routine Description: 01549 // 01550 // This macro gets the owner field from the PTE. 01551 // 01552 // Argments 01553 // 01554 // PTE - Supplies the PTE to operate upon. 01555 // 01556 // Return Value: 01557 // 01558 // The state of the OWNER field. 01559 // 01560 //-- 01561 01562 #define MI_GET_OWNER_IN_PTE(PPTE) KernelMode 01563 01564 01565 01566 // 01567 // bit mask to clear out fields in a PTE to or in prototype pte offset. 01568 // 01569 01570 #define CLEAR_FOR_PROTO_PTE_ADDRESS ((ULONG)0x701) 01571 01572 // 01573 // bit mask to clear out fields in a PTE to or in paging file location. 01574 // 01575 01576 #define CLEAR_FOR_PAGE_FILE 0x000003E0 01577 01578 01579 //++ 01580 //VOID 01581 //MI_SET_PAGING_FILE_INFO ( 01582 // OUT MMPTE OUTPTE, 01583 // IN MMPTE PPTE, 01584 // IN ULONG FILEINFO, 01585 // IN ULONG OFFSET 01586 // ); 01587 // 01588 // Routine Description: 01589 // 01590 // This macro sets into the specified PTE the supplied information 01591 // to indicate where the backing store for the page is located. 01592 // 01593 // Argments 01594 // 01595 // OUTPTE - Supplies the PTE in which to store the result. 01596 // 01597 // PTE - Supplies the PTE to operate upon. 01598 // 01599 // FILEINFO - Supplies the number of the paging file. 01600 // 01601 // OFFSET - Supplies the offset into the paging file. 01602 // 01603 // Return Value: 01604 // 01605 // None. 01606 // 01607 //-- 01608 01609 #define MI_SET_PAGING_FILE_INFO(OUTPTE,PTE,FILEINFO,OFFSET) \ 01610 (OUTPTE).u.Long = (((PTE).u.Soft.Protection << MM_PROTECT_FIELD_SHIFT) | \ 01611 ((ULONGLONG)(FILEINFO) << _MM_PAGING_FILE_LOW_SHIFT) | \ 01612 ((ULONGLONG)(OFFSET) << _MM_PAGING_FILE_HIGH_SHIFT)); 01613 01614 01615 //++ 01616 //PMMPTE 01617 //MiPteToProto ( 01618 // IN OUT MMPTE PPTE, 01619 // IN ULONG FILEINFO, 01620 // IN ULONG OFFSET 01621 // ); 01622 // 01623 // Routine Description: 01624 // 01625 // This macro returns the address of the corresponding prototype which 01626 // was encoded earlier into the supplied PTE. 01627 // 01628 // NOTE THAT AS PROTOPTE CAN ONLY RESIDE IN PAGED POOL!!!!!! 01629 // 01630 // MAX SIZE = 2^(2+7+21) = 2^30 = 1GB. 01631 // 01632 // NOTE, that the valid bit must be zero! 01633 // 01634 // Argments 01635 // 01636 // lpte - Supplies the PTE to operate upon. 01637 // 01638 // Return Value: 01639 // 01640 // Pointer to the prototype PTE that backs this PTE. 01641 // 01642 //-- 01643 01644 01645 #define MiPteToProto(lpte) \ 01646 ((PMMPTE) ((ULONG_PTR)((lpte)->u.Proto.ProtoAddress) + MmProtopte_Base)) 01647 01648 //++ 01649 //ULONG_PTR 01650 //MiProtoAddressForPte ( 01651 // IN PMMPTE proto_va 01652 // ); 01653 // 01654 // Routine Description: 01655 // 01656 // This macro sets into the specified PTE the supplied information 01657 // to indicate where the backing store for the page is located. 01658 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01659 // reference a prototype PTE. And set the protoPTE bit, 01660 // MM_PTE_PROTOTYPE_MASK. 01661 // 01662 // Argments 01663 // 01664 // proto_va - Supplies the address of the prototype PTE. 01665 // 01666 // Return Value: 01667 // 01668 // Mask to set into the PTE. 01669 // 01670 //-- 01671 01672 #define MiProtoAddressForPte(proto_va) \ 01673 (( (ULONGLONG)((ULONG_PTR)proto_va - MmProtopte_Base) << \ 01674 (_MM_PROTO_ADDRESS_SHIFT)) | MM_PTE_PROTOTYPE_MASK) 01675 01676 #define MISetProtoAddressForPte(PTE, proto_va) \ 01677 (PTE).u.Long = 0; \ 01678 (PTE).u.Proto.Prototype = 1; \ 01679 (PTE).u.Proto.ProtoAddress = (ULONG_PTR)proto_va - MmProtopte_Base; 01680 01681 01682 //++ 01683 //ULONG_PTR 01684 //MiProtoAddressForKernelPte ( 01685 // IN PMMPTE proto_va 01686 // ); 01687 // 01688 // Routine Description: 01689 // 01690 // This macro sets into the specified PTE the supplied information 01691 // to indicate where the backing store for the page is located. 01692 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01693 // reference a prototype PTE. And set the protoPTE bit, 01694 // MM_PTE_PROTOTYPE_MASK. 01695 // 01696 // This macro also sets any other information (such as global bits) 01697 // required for kernel mode PTEs. 01698 // 01699 // Argments 01700 // 01701 // proto_va - Supplies the address of the prototype PTE. 01702 // 01703 // Return Value: 01704 // 01705 // Mask to set into the PTE. 01706 // 01707 //-- 01708 01709 // not different on x86. 01710 01711 #define MiProtoAddressForKernelPte(proto_va) MiProtoAddressForPte(proto_va) 01712 01713 01714 #define MM_SUBSECTION_MAP (128*1024*1024) 01715 01716 //++ 01717 //PSUBSECTION 01718 //MiGetSubsectionAddress ( 01719 // IN PMMPTE lpte 01720 // ); 01721 // 01722 // Routine Description: 01723 // 01724 // This macro takes a PTE and returns the address of the subsection that 01725 // the PTE refers to. Subsections are quadword structures allocated 01726 // from nonpaged pool. 01727 // 01728 // NOTE THIS MACRO LIMITS THE SIZE OF NONPAGED POOL! 01729 // MAXIMUM NONPAGED POOL = 2^(3+4+21) = 2^28 = 256mb. 01730 // 01731 // 01732 // Argments 01733 // 01734 // lpte - Supplies the PTE to operate upon. 01735 // 01736 // Return Value: 01737 // 01738 // A pointer to the subsection referred to by the supplied PTE. 01739 // 01740 //-- 01741 01742 #define MiGetSubsectionAddress(lpte) \ 01743 (((lpte)->u.Subsect.WhichPool == 1) ? \ 01744 ((PSUBSECTION)((ULONG_PTR)MmSubsectionBase + \ 01745 ((ULONG_PTR)(lpte)->u.Subsect.SubsectionAddress))) \ 01746 : \ 01747 ((PSUBSECTION)((ULONG_PTR)MM_NONPAGED_POOL_END - \ 01748 ((ULONG_PTR)(lpte)->u.Subsect.SubsectionAddress)))) 01749 01750 //++ 01751 //ULONGLONG 01752 //MiGetSubsectionAddressForPte ( 01753 // IN PSUBSECTION VA 01754 // ); 01755 // 01756 // Routine Description: 01757 // 01758 // This macro takes the address of a subsection and encodes it for use 01759 // in a PTE. 01760 // 01761 // NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED! 01762 // 01763 // Argments 01764 // 01765 // VA - Supplies a pointer to the subsection to encode. 01766 // 01767 // Return Value: 01768 // 01769 // The mask to set into the PTE to make it reference the supplied 01770 // subsetion. 01771 // 01772 //-- 01773 01774 #define MiGetSubsectionAddressForPte(VA) \ 01775 ( ((ULONG_PTR)(VA) < (ULONG_PTR)KSEG2_BASE) ? \ 01776 ( ((ULONGLONG)((ULONG_PTR)VA - (ULONG_PTR)MmSubsectionBase) \ 01777 << (_MM_PTE_SUBSECTION_ADDRESS_SHIFT)) | 0x80) \ 01778 : \ 01779 ((ULONGLONG)((ULONG_PTR)MM_NONPAGED_POOL_END - (ULONG_PTR)VA) \ 01780 << (_MM_PTE_SUBSECTION_ADDRESS_SHIFT)) ) 01781 01782 #define MiSetSubsectionAddressForPte(PTE, VA) \ 01783 (PTE).u.Long = 0; \ 01784 if ((ULONG_PTR)(VA) < (ULONG_PTR)KSEG2_BASE) { \ 01785 (PTE).u.Subsect.SubsectionAddress = (ULONG_PTR)VA - (ULONG_PTR)MmSubsectionBase; \ 01786 (PTE).u.Subsect.WhichPool = 1; \ 01787 } else { \ 01788 (PTE).u.Subsect.SubsectionAddress = (ULONG_PTR)MM_NONPAGED_POOL_END - (ULONG_PTR)VA; \ 01789 } 01790 01791 //++ 01792 //ULONG 01793 //MiGetPpeOffset ( 01794 // IN PVOID va 01795 // ); 01796 // 01797 // Routine Description: 01798 // 01799 // MiGetPpeOffset returns the offset into a page root 01800 // for a given virtual address. 01801 // 01802 // Arguments 01803 // 01804 // Va - Supplies the virtual address to locate the offset for. 01805 // 01806 // Return Value: 01807 // 01808 // The offset into the page root table the corresponding PPE is at. 01809 // 01810 // LWFIX: expand for 3-level 01811 // 01812 //-- 01813 01814 #define MiGetPpeOffset(va) ((ULONG)(((ULONG_PTR)(va) >> PDI1_SHIFT) & PDI_MASK)) 01815 01816 //++ 01817 //ULONG_PTR 01818 //MiGetPdeOffset ( 01819 // IN PVOID va 01820 // ); 01821 // 01822 // Routine Description: 01823 // 01824 // MiGetPdeOffset returns the offset into a page directory 01825 // for a given virtual address. 01826 // 01827 // Argments 01828 // 01829 // Va - Supplies the virtual address to locate the offset for. 01830 // 01831 // Return Value: 01832 // 01833 // The offset into the page directory table the corresponding PDE is at. 01834 // 01835 //-- 01836 01837 #define MiGetPdeOffset(va) ((ULONG) (((ULONG_PTR)(va) >> PDI_SHIFT) & PDI_MASK)) 01838 01839 //++ 01840 //ULONG 01841 //MiGetPpePdeOffset ( 01842 // IN PVOID va 01843 // ); 01844 // 01845 // Routine Description: 01846 // 01847 // MiGetPpePdeOffset returns the offset into a page directory 01848 // for a given virtual address. 01849 // 01850 // N.B. This does not mask off PPE bits. 01851 // 01852 // Arguments 01853 // 01854 // Va - Supplies the virtual address to locate the offset for. 01855 // 01856 // Return Value: 01857 // 01858 // The offset into the page directory (and parent) table the 01859 // corresponding PDE is at. 01860 // 01861 //-- 01862 01863 #define MiGetPpePdeOffset(va) ((ULONG) ((ULONG_PTR)(va) >> PDI_SHIFT)) 01864 01865 //++ 01866 //ULONG_PTR 01867 //MiGetPteOffset ( 01868 // IN PVOID va 01869 // ); 01870 // 01871 // Routine Description: 01872 // 01873 // MiGetPteOffset returns the offset into a page table page 01874 // for a given virtual address. 01875 // 01876 // Argments 01877 // 01878 // Va - Supplies the virtual address to locate the offset for. 01879 // 01880 // Return Value: 01881 // 01882 // The offset into the page table page table the corresponding PTE is at. 01883 // 01884 //-- 01885 01886 #define MiGetPteOffset(va) ((ULONG) (((ULONG_PTR)(va) >> PTI_SHIFT) & PDI_MASK)) 01887 01888 01889 //++ 01890 //++ 01891 //PVOID 01892 //MiGetVirtualAddressMappedByPpe ( 01893 // IN PMMPTE PTE 01894 // ); 01895 // 01896 // Routine Description: 01897 // 01898 // MiGetVirtualAddressMappedByPpe returns the virtual address 01899 // which is mapped by a given PPE address. 01900 // 01901 // Arguments 01902 // 01903 // PPE - Supplies the PPE to get the virtual address for. 01904 // 01905 // Return Value: 01906 // 01907 // Virtual address mapped by the PPE. 01908 // 01909 //-- 01910 01911 #define MiGetVirtualAddressMappedByPpe(PPE) \ 01912 MiGetVirtualAddressMappedByPte(MiGetVirtualAddressMappedByPde(PPE)) 01913 01914 //++ 01915 //PVOID 01916 //MiGetVirtualAddressMappedByPde ( 01917 // IN PMMPTE PDE 01918 // ); 01919 // 01920 // Routine Description: 01921 // 01922 // MiGetVirtualAddressMappedByPde returns the virtual address 01923 // which is mapped by a given PDE address. 01924 // 01925 // Arguments 01926 // 01927 // PDE - Supplies the PDE to get the virtual address for. 01928 // 01929 // Return Value: 01930 // 01931 // Virtual address mapped by the PDE. 01932 // 01933 //-- 01934 01935 #define MiGetVirtualAddressMappedByPde(Pde) \ 01936 MiGetVirtualAddressMappedByPte(MiGetVirtualAddressMappedByPte(Pde)) 01937 01938 //++ 01939 //PVOID 01940 //MiGetVirtualAddressMappedByPte ( 01941 // IN PMMPTE PTE 01942 // ); 01943 // 01944 // Routine Description: 01945 // 01946 // MiGetVirtualAddressMappedByPte returns the virtual address 01947 // which is mapped by a given PTE address. 01948 // 01949 // Argments 01950 // 01951 // PTE - Supplies the PTE to get the virtual address for. 01952 // 01953 // Return Value: 01954 // 01955 // Virtual address mapped by the PTE. 01956 // 01957 //-- 01958 01959 #ifdef _WIN64 01960 01961 #define MiGetVirtualAddressMappedByPte(PTE) \ 01962 (((ULONG_PTR)(PTE) & PTA_SIGN) ? \ 01963 (PVOID)(((ULONG_PTR)(PTE) & VRN_MASK) | VA_FILL | \ 01964 (((ULONG_PTR)(PTE)-PTE_BASE) << (PAGE_SHIFT - PTE_SHIFT))) : \ 01965 (PVOID)(((ULONG_PTR)(PTE) & VRN_MASK) | (((ULONG_PTR)(PTE)-PTE_BASE) << (PAGE_SHIFT - PTE_SHIFT)))) 01966 01967 #else 01968 01969 #define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG_PTR)(PTE) << (PAGE_SHIFT - PTE_SHIFT))) 01970 01971 #endif 01972 01973 01974 //++ 01975 //LOGICAL 01976 //MiIsVirtualAddressOnPpeBoundary ( 01977 // IN PVOID VA 01978 // ); 01979 // 01980 // Routine Description: 01981 // 01982 // MiIsVirtualAddressOnPpeBoundary returns TRUE if the virtual address is 01983 // on a page directory entry boundary. 01984 // 01985 // Arguments 01986 // 01987 // VA - Supplies the virtual address to check. 01988 // 01989 // Return Value: 01990 // 01991 // TRUE if on a boundary, FALSE if not. 01992 // 01993 //-- 01994 01995 #define MiIsVirtualAddressOnPpeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY1_MASK) == 0) 01996 01997 01998 //++ 01999 //LOGICAL 02000 //MiIsVirtualAddressOnPdeBoundary ( 02001 // IN PVOID VA 02002 // ); 02003 // 02004 // Routine Description: 02005 // 02006 // MiIsVirtualAddressOnPdeBoundary returns TRUE if the virtual address is 02007 // on a page directory entry boundary. 02008 // 02009 // Arguments 02010 // 02011 // VA - Supplies the virtual address to check. 02012 // 02013 // Return Value: 02014 // 02015 // TRUE if on a 4MB PDE boundary, FALSE if not. 02016 // 02017 //-- 02018 02019 #define MiIsVirtualAddressOnPdeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY2_MASK) == 0) 02020 02021 02022 //++ 02023 //LOGICAL 02024 //MiIsPteOnPpeBoundary ( 02025 // IN PVOID VA 02026 // ); 02027 // 02028 // Routine Description: 02029 // 02030 // MiIsPteOnPpeBoundary returns TRUE if the PTE is 02031 // on a page directory parent entry boundary. 02032 // 02033 // Arguments 02034 // 02035 // VA - Supplies the virtual address to check. 02036 // 02037 // Return Value: 02038 // 02039 // TRUE if on a boundary, FALSE if not. 02040 // 02041 //-- 02042 02043 #define MiIsPteOnPpeBoundary(PTE) (((ULONG_PTR)(PTE) & (MM_VA_MAPPED_BY_PDE - 1)) == 0) 02044 02045 02046 02047 //++ 02048 //LOGICAL 02049 //MiIsPteOnPdeBoundary ( 02050 // IN PVOID PTE 02051 // ); 02052 // 02053 // Routine Description: 02054 // 02055 // MiIsPteOnPdeBoundary returns TRUE if the PTE is 02056 // on a page directory entry boundary. 02057 // 02058 // Arguments 02059 // 02060 // PTE - Supplies the PTE to check. 02061 // 02062 // Return Value: 02063 // 02064 // TRUE if on a 8MB PDE boundary, FALSE if not. 02065 // 02066 //-- 02067 02068 #define MiIsPteOnPdeBoundary(PTE) (((ULONG_PTR)(PTE) & (PAGE_SIZE - 1)) == 0) 02069 02070 02071 //++ 02072 //ULONG 02073 //GET_PAGING_FILE_NUMBER ( 02074 // IN MMPTE PTE 02075 // ); 02076 // 02077 // Routine Description: 02078 // 02079 // This macro extracts the paging file number from a PTE. 02080 // 02081 // Argments 02082 // 02083 // PTE - Supplies the PTE to operate upon. 02084 // 02085 // Return Value: 02086 // 02087 // The paging file number. 02088 // 02089 //-- 02090 02091 #define GET_PAGING_FILE_NUMBER(PTE) ((ULONG) (PTE).u.Soft.PageFileLow) 02092 02093 02094 02095 //++ 02096 //ULONG 02097 //GET_PAGING_FILE_OFFSET ( 02098 // IN MMPTE PTE 02099 // ); 02100 // 02101 // Routine Description: 02102 // 02103 // This macro extracts the offset into the paging file from a PTE. 02104 // 02105 // Argments 02106 // 02107 // PTE - Supplies the PTE to operate upon. 02108 // 02109 // Return Value: 02110 // 02111 // The paging file offset. 02112 // 02113 //-- 02114 02115 #define GET_PAGING_FILE_OFFSET(PTE) ((ULONG) (PTE).u.Soft.PageFileHigh) 02116 02117 02118 02119 02120 //++ 02121 //ULONG_PTR 02122 //IS_PTE_NOT_DEMAND_ZERO ( 02123 // IN PMMPTE PPTE 02124 // ); 02125 // 02126 // Routine Description: 02127 // 02128 // This macro checks to see if a given PTE is NOT a demand zero PTE. 02129 // 02130 // Argments 02131 // 02132 // PTE - Supplies the PTE to operate upon. 02133 // 02134 // Return Value: 02135 // 02136 // Returns 0 if the PTE is demand zero, non-zero otherwise. 02137 // 02138 //-- 02139 02140 #define IS_PTE_NOT_DEMAND_ZERO(PTE) \ 02141 ((PTE).u.Long & ((ULONG_PTR)0xFFFFFFFFFFFFF000 | \ 02142 MM_PTE_VALID_MASK | \ 02143 MM_PTE_PROTOTYPE_MASK | \ 02144 MM_PTE_TRANSITION_MASK)) 02145 02146 02147 //++ 02148 //VOID 02149 //MI_MAKING_VALID_PTE_INVALID( 02150 // IN PMMPTE PPTE 02151 // ); 02152 // 02153 // Routine Description: 02154 // 02155 // Prepare to make a single valid PTE invalid. 02156 // No action is required on x86. 02157 // 02158 // Argments 02159 // 02160 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 02161 // 02162 // Return Value: 02163 // 02164 // None. 02165 // 02166 //-- 02167 02168 #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE) 02169 02170 02171 //++ 02172 //VOID 02173 //MI_MAKING_VALID_MULTIPLE_PTES_INVALID( 02174 // IN PMMPTE PPTE 02175 // ); 02176 // 02177 // Routine Description: 02178 // 02179 // Prepare to make multiple valid PTEs invalid. 02180 // No action is required on x86. 02181 // 02182 // Argments 02183 // 02184 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 02185 // 02186 // Return Value: 02187 // 02188 // None. 02189 // 02190 //-- 02191 02192 #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE) 02193 02194 02195 02196 //++ 02197 //VOID 02198 //MI_MAKE_PROTECT_WRITE_COPY ( 02199 // IN OUT MMPTE PPTE 02200 // ); 02201 // 02202 // Routine Description: 02203 // 02204 // This macro makes a writable PTE a writeable-copy PTE. 02205 // 02206 // Argments 02207 // 02208 // PTE - Supplies the PTE to operate upon. 02209 // 02210 // Return Value: 02211 // 02212 // NONE 02213 // 02214 //-- 02215 02216 #define MI_MAKE_PROTECT_WRITE_COPY(PTE) \ 02217 if ((PTE).u.Soft.Protection & MM_PROTECTION_WRITE_MASK) { \ 02218 (PTE).u.Long |= MM_PROTECTION_COPY_MASK << MM_PROTECT_FIELD_SHIFT; \ 02219 } 02220 02221 02222 //++ 02223 //VOID 02224 //MI_SET_PAGE_DIRTY( 02225 // IN PMMPTE PPTE, 02226 // IN PVOID VA, 02227 // IN PVOID PFNHELD 02228 // ); 02229 // 02230 // Routine Description: 02231 // 02232 // This macro sets the dirty bit (and release page file space). 02233 // 02234 // Argments 02235 // 02236 // TEMP - Supplies a temporary for usage. 02237 // 02238 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 02239 // 02240 // VA - Supplies a the virtual address of the page fault. 02241 // 02242 // PFNHELD - Supplies TRUE if the PFN lock is held. 02243 // 02244 // Return Value: 02245 // 02246 // None. 02247 // 02248 //-- 02249 02250 #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \ 02251 if ((PPTE)->u.Hard.Dirty == 1) { \ 02252 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 02253 } 02254 02255 02256 //++ 02257 //VOID 02258 //MI_NO_FAULT_FOUND( 02259 // IN TEMP, 02260 // IN PMMPTE PPTE, 02261 // IN PVOID VA, 02262 // IN PVOID PFNHELD 02263 // ); 02264 // 02265 // Routine Description: 02266 // 02267 // This macro handles the case when a page fault is taken and no 02268 // PTE with the valid bit clear is found. 02269 // 02270 // Argments 02271 // 02272 // TEMP - Supplies a temporary for usage. 02273 // 02274 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 02275 // 02276 // VA - Supplies a the virtual address of the page fault. 02277 // 02278 // PFNHELD - Supplies TRUE if the PFN lock is held. 02279 // 02280 // Return Value: 02281 // 02282 // None. 02283 // 02284 //-- 02285 02286 #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \ 02287 if (StoreInstruction && ((PPTE)->u.Hard.Dirty == 0)) { \ 02288 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 02289 } 02290 02291 02292 //++ 02293 //ULONG_PTR 02294 //MI_CAPTURE_DIRTY_BIT_TO_PFN ( 02295 // IN PMMPTE PPTE, 02296 // IN PMMPFN PPFN 02297 // ); 02298 // 02299 // Routine Description: 02300 // 02301 // This macro gets captures the state of the dirty bit to the PFN 02302 // and frees any associated page file space if the PTE has been 02303 // modified element. 02304 // 02305 // NOTE - THE PFN LOCK MUST BE HELD! 02306 // 02307 // Argments 02308 // 02309 // PPTE - Supplies the PTE to operate upon. 02310 // 02311 // PPFN - Supplies a pointer to the PFN database element that corresponds 02312 // to the page mapped by the PTE. 02313 // 02314 // Return Value: 02315 // 02316 // None. 02317 // 02318 //-- 02319 02320 #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \ 02321 ASSERT (KeGetCurrentIrql() > APC_LEVEL); \ 02322 if (((PPFN)->u3.e1.Modified == 0) && \ 02323 ((PPTE)->u.Hard.Dirty != 0)) { \ 02324 (PPFN)->u3.e1.Modified = 1; \ 02325 if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \ 02326 ((PPFN)->u3.e1.WriteInProgress == 0)) { \ 02327 MiReleasePageFileSpace ((PPFN)->OriginalPte); \ 02328 (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \ 02329 } \ 02330 } 02331 02332 02333 //++ 02334 //BOOLEAN 02335 //MI_IS_PHYSICAL_ADDRESS ( 02336 // IN PVOID VA 02337 // ); 02338 // 02339 // Routine Description: 02340 // 02341 // This macro deterines if a give virtual address is really a 02342 // physical address. 02343 // 02344 // Argments 02345 // 02346 // VA - Supplies the virtual address. 02347 // 02348 // Return Value: 02349 // 02350 // FALSE if it is not a physical address, TRUE if it is. 02351 // 02352 //-- 02353 02354 02355 #define MI_IS_PHYSICAL_ADDRESS(Va) \ 02356 ((((ULONG_PTR)(Va) >= KSEG3_BASE) && ((ULONG_PTR)(Va) < KSEG3_LIMIT)) || \ 02357 (((ULONG_PTR)Va >= KSEG0_BASE) && ((ULONG_PTR)Va < KSEG2_BASE))) 02358 02359 02360 //++ 02361 //ULONG_PTR 02362 //MI_CONVERT_PHYSICAL_TO_PFN ( 02363 // IN PVOID VA 02364 // ); 02365 // 02366 // Routine Description: 02367 // 02368 // This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS) 02369 // to its corresponding physical frame number. 02370 // 02371 // Argments 02372 // 02373 // VA - Supplies a pointer to the physical address. 02374 // 02375 // Return Value: 02376 // 02377 // Returns the PFN for the page. 02378 // 02379 //-- 02380 02381 PVOID KiGetPhysicalAddress( 02382 IN PVOID VirtualAddress 02383 ); 02384 02385 #define MI_CONVERT_PHYSICAL_TO_PFN(Va) \ 02386 (((ULONG_PTR)(Va) < KSEG0_BASE) ? \ 02387 ((PFN_NUMBER)(((ULONG_PTR)(Va) - KSEG3_BASE) >> PAGE_SHIFT)) : \ 02388 ((PFN_NUMBER)(((ULONG_PTR)KiGetPhysicalAddress(Va)) >> PAGE_SHIFT))) 02389 02390 02391 typedef struct _MMCOLOR_TABLES { 02392 PFN_NUMBER Flink; 02393 PVOID Blink; 02394 } MMCOLOR_TABLES, *PMMCOLOR_TABLES; 02395 02396 typedef struct _MMPRIMARY_COLOR_TABLES { 02397 LIST_ENTRY ListHead; 02398 } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES; 02399 02400 02401 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1 02402 extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS]; 02403 #endif 02404 02405 extern PMMCOLOR_TABLES MmFreePagesByColor[2]; 02406 02407 extern ULONG MmTotalPagesForPagingFile; 02408 02409 02410 // 02411 // A VALID Page Table Entry on an Intel IA64 has the following definition. 02412 // 02413 02414 #define _MM_PAGING_FILE_LOW_SHIFT 28 02415 #define _MM_PAGING_FILE_HIGH_SHIFT 32 02416 02417 #define MI_PTE_LOOKUP_NEEDED ((ULONG64)0xffffffff) 02418 02419 typedef struct _MMPTE_SOFTWARE { 02420 ULONGLONG Valid : 1; 02421 ULONGLONG Prototype : 1; 02422 ULONGLONG Protection : 5; 02423 ULONGLONG Transition : 1; 02424 ULONGLONG UsedPageTableEntries : PTE_PER_PAGE_BITS; 02425 ULONGLONG Reserved : 20 - PTE_PER_PAGE_BITS; 02426 ULONGLONG PageFileLow: 4; 02427 ULONGLONG PageFileHigh : 32; 02428 } MMPTE_SOFTWARE; 02429 02430 typedef struct _MMPTE_TRANSITION { 02431 ULONGLONG Valid : 1; 02432 ULONGLONG Prototype : 1; 02433 ULONGLONG Protection : 5; 02434 ULONGLONG Transition : 1; 02435 ULONGLONG Rsvd0 : PAGE_SHIFT - 8; 02436 ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT; 02437 ULONGLONG Rsvd1 : 14; 02438 } MMPTE_TRANSITION; 02439 02440 02441 #define _MM_PROTO_ADDRESS_SHIFT 12 02442 02443 typedef struct _MMPTE_PROTOTYPE { 02444 ULONGLONG Valid : 1; 02445 ULONGLONG Prototype : 1; 02446 ULONGLONG ReadOnly : 1; // if set allow read only access. 02447 ULONGLONG Rsvd : 9; 02448 ULONGLONG ProtoAddress : 52; 02449 } MMPTE_PROTOTYPE; 02450 02451 02452 #define _MM_PTE_SUBSECTION_ADDRESS_SHIFT 12 02453 02454 typedef struct _MMPTE_SUBSECTION { 02455 ULONGLONG Valid : 1; 02456 ULONGLONG Prototype : 1; 02457 ULONGLONG Protection : 5; 02458 ULONGLONG WhichPool : 1; 02459 ULONGLONG Rsvd : 4; 02460 ULONGLONG SubsectionAddress : 52; 02461 } MMPTE_SUBSECTION; 02462 02463 typedef struct _MMPTE_LIST { 02464 ULONGLONG Valid : 1; 02465 ULONGLONG OneEntry : 1; 02466 ULONGLONG filler10 : 10; 02467 ULONGLONG NextEntry : 32; 02468 ULONGLONG Rsvd : 20; 02469 } MMPTE_LIST; 02470 02471 02472 // 02473 // A Page Table Entry on an Intel IA64 has the following definition. 02474 // 02475 02476 #define _HARDWARE_PTE_WORKING_SET_BITS 11 02477 02478 typedef struct _MMPTE_HARDWARE { 02479 ULONGLONG Valid : 1; 02480 ULONGLONG Rsvd0 : 1; 02481 ULONGLONG Cache : 3; 02482 ULONGLONG Accessed : 1; 02483 ULONGLONG Dirty : 1; 02484 ULONGLONG Owner : 2; 02485 ULONGLONG Execute : 1; 02486 ULONGLONG Write : 1; 02487 ULONGLONG Rsvd1 : PAGE_SHIFT - 12; 02488 ULONGLONG CopyOnWrite : 1; 02489 ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT; 02490 ULONGLONG Rsvd2 : 2; 02491 ULONGLONG Exception : 1; 02492 ULONGLONG SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS; 02493 } MMPTE_HARDWARE, *PMMPTE_HARDWARE; 02494 02495 typedef struct _MMPTE_LARGEPAGE { 02496 ULONGLONG Valid : 1; 02497 ULONGLONG Rsvd0 : 1; 02498 ULONGLONG Cache : 3; 02499 ULONGLONG Accessed : 1; 02500 ULONGLONG Dirty : 1; 02501 ULONGLONG Owner : 2; 02502 ULONGLONG Execute : 1; 02503 ULONGLONG Write : 1; 02504 ULONGLONG Rsvd1 : PAGE_SHIFT - 12; 02505 ULONGLONG CopyOnWrite : 1; 02506 ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT; 02507 ULONGLONG Rsvd2 : 2; 02508 ULONGLONG Exception : 1; 02509 ULONGLONG Rsvd3 : 1; 02510 ULONGLONG LargePage : 1; 02511 ULONGLONG PageSize : 6; 02512 ULONGLONG Rsvd4 : 3; 02513 } MMPTE_LARGEPAGE, *PMMPTE_LARGEPAGE; 02514 02515 typedef struct _ALT_4KPTE { 02516 ULONGLONG Commit : 1; 02517 ULONGLONG Rsvd0 : 1; 02518 ULONGLONG Cache : 3; 02519 ULONGLONG Accessed : 1; 02520 ULONGLONG Dirty : 1; 02521 ULONGLONG Owner : 2; 02522 ULONGLONG Execute : 1; 02523 ULONGLONG Write : 1; 02524 ULONGLONG Rsvd1 : 1; 02525 ULONGLONG PteOffset : 32; 02526 ULONGLONG Rsvd2 : 8; 02527 ULONGLONG Exception : 1; 02528 ULONGLONG Protection : 5; 02529 ULONGLONG Lock : 1; 02530 ULONGLONG FillZero : 1; 02531 ULONGLONG NoAccess : 1; 02532 ULONGLONG CopyOnWrite : 1; 02533 ULONGLONG PteIndirect : 1; 02534 ULONGLONG Private : 1; 02535 } ALT_4KPTE, *PALT_4KPTE; 02536 02537 #define MI_GET_PAGE_FRAME_FROM_PTE(PTE) ((ULONG)((PTE)->u.Hard.PageFrameNumber)) 02538 #define MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE(PTE) ((ULONG)((PTE)->u.Trans.PageFrameNumber)) 02539 #define MI_GET_PROTECTION_FROM_SOFT_PTE(PTE) ((ULONG)((PTE)->u.Soft.Protection)) 02540 #define MI_GET_PROTECTION_FROM_TRANSITION_PTE(PTE) ((ULONG)((PTE)->u.Trans.Protection)) 02541 02542 02543 typedef struct _MMPTE { 02544 union { 02545 ULONGLONG Long; 02546 MMPTE_HARDWARE Hard; 02547 MMPTE_LARGEPAGE Large; 02548 HARDWARE_PTE Flush; 02549 MMPTE_PROTOTYPE Proto; 02550 MMPTE_SOFTWARE Soft; 02551 MMPTE_TRANSITION Trans; 02552 MMPTE_SUBSECTION Subsect; 02553 MMPTE_LIST List; 02554 ALT_4KPTE Alt; 02555 } u; 02556 } MMPTE; 02557 02558 typedef MMPTE *PMMPTE; 02559 02560 //++ 02561 //VOID 02562 //MI_WRITE_VALID_PTE ( 02563 // IN PMMPTE PointerPte, 02564 // IN MMPTE PteContents 02565 // ); 02566 // 02567 // Routine Description: 02568 // 02569 // MI_WRITE_VALID_PTE fills in the specified PTE making it valid with the 02570 // specified contents. 02571 // 02572 // Arguments 02573 // 02574 // PointerPte - Supplies a PTE to fill. 02575 // 02576 // PteContents - Supplies the contents to put in the PTE. 02577 // 02578 // Return Value: 02579 // 02580 // None. 02581 // 02582 //-- 02583 02584 #define MI_WRITE_VALID_PTE(_PointerPte, _PteContents) \ 02585 (*(_PointerPte) = (_PteContents)) 02586 02587 //++ 02588 //VOID 02589 //MI_WRITE_INVALID_PTE ( 02590 // IN PMMPTE PointerPte, 02591 // IN MMPTE PteContents 02592 // ); 02593 // 02594 // Routine Description: 02595 // 02596 // MI_WRITE_INVALID_PTE fills in the specified PTE making it invalid with the 02597 // specified contents. 02598 // 02599 // Arguments 02600 // 02601 // PointerPte - Supplies a PTE to fill. 02602 // 02603 // PteContents - Supplies the contents to put in the PTE. 02604 // 02605 // Return Value: 02606 // 02607 // None. 02608 // 02609 //-- 02610 02611 #define MI_WRITE_INVALID_PTE(_PointerPte, _PteContents) \ 02612 (*(_PointerPte) = (_PteContents)) 02613 02614 //++ 02615 //VOID 02616 //MI_WRITE_VALID_PTE_NEW_PROTECTION ( 02617 // IN PMMPTE PointerPte, 02618 // IN MMPTE PteContents 02619 // ); 02620 // 02621 // Routine Description: 02622 // 02623 // MI_WRITE_VALID_PTE_NEW_PROTECTION fills in the specified PTE (which was 02624 // already valid) changing only the protection or the dirty bit. 02625 // 02626 // Arguments 02627 // 02628 // PointerPte - Supplies a PTE to fill. 02629 // 02630 // PteContents - Supplies the contents to put in the PTE. 02631 // 02632 // Return Value: 02633 // 02634 // None. 02635 // 02636 //-- 02637 02638 #define MI_WRITE_VALID_PTE_NEW_PROTECTION(_PointerPte, _PteContents) \ 02639 (*(_PointerPte) = (_PteContents)) 02640 02641 // 02642 // For EM build, need to export this function to ps/psldt.c 02643 // 02644 02645 extern PVOID 02646 MiCreatePebOrTeb ( 02647 IN PEPROCESS TargetProcess, 02648 IN ULONG Size 02649 ); 02650 02651 02652 //++ 02653 //VOID 02654 //MiFillMemoryPte ( 02655 // IN PMMPTE Destination, 02656 // IN ULONG Length, 02657 // IN MMPTE Pattern, 02658 // }; 02659 // 02660 // Routine Description: 02661 // 02662 // This function fills memory with the specified PTE pattern. 02663 // 02664 // Arguments 02665 // 02666 // Destination - Supplies a pointer to the memory to fill. 02667 // 02668 // Length - Supplies the length, in bytes, of the memory to be 02669 // filled. 02670 // 02671 // Pattern - Supplies the PTE fill pattern. 02672 // 02673 // Return Value: 02674 // 02675 // None. 02676 // 02677 //-- 02678 02679 #define MiFillMemoryPte(Destination, Length, Pattern) \ 02680 RtlFillMemoryUlonglong ((Destination), (Length), (Pattern)) 02681 02682 02683 #define KiWbInvalidateCache 02684 02685 02686 //++ 02687 //BOOLEAN 02688 //MI_IS_PAGE_TABLE_ADDRESS ( 02689 // IN PVOID VA 02690 // ); 02691 // 02692 // Routine Description: 02693 // 02694 // This macro determines if a given virtual address is really a 02695 // page table address (PTE, PDE, PPE). 02696 // 02697 // Arguments 02698 // 02699 // VA - Supplies the virtual address. 02700 // 02701 // Return Value: 02702 // 02703 // FALSE if it is not a page table address, TRUE if it is. 02704 // 02705 //-- 02706 02707 #if defined(_MIALT4K_) 02708 #define MI_IS_PAGE_TABLE_ADDRESS(VA) \ 02709 ((((ULONG_PTR)VA >= PTE_UBASE) && ((ULONG_PTR)VA <= (PDE_UTBASE + PAGE_SIZE))) || \ 02710 (((ULONG_PTR)VA >= PTE_KBASE) && ((ULONG_PTR)VA <= (PDE_KTBASE + PAGE_SIZE))) || \ 02711 (((ULONG_PTR)VA >= PTE_SBASE) && ((ULONG_PTR)VA <= (PDE_STBASE + PAGE_SIZE))) || \ 02712 (((ULONG_PTR)VA >= ALT4KB_PERMISSION_TABLE_START) && \ 02713 ((ULONG_PTR)VA <= ALT4KB_PERMISSION_TABLE_END))) 02714 #else 02715 #define MI_IS_PAGE_TABLE_ADDRESS(VA) \ 02716 ((((ULONG_PTR)VA >= PTE_UBASE) && ((ULONG_PTR)VA <= (PDE_UTBASE + PAGE_SIZE))) || \ 02717 (((ULONG_PTR)VA >= PTE_KBASE) && ((ULONG_PTR)VA <= (PDE_KTBASE + PAGE_SIZE))) || \ 02718 (((ULONG_PTR)VA >= PTE_SBASE) && ((ULONG_PTR)VA <= (PDE_STBASE + PAGE_SIZE)))) 02719 #endif 02720 02721 //++ 02722 //BOOLEAN 02723 //MI_IS_HYPER_SPACE_ADDRESS ( 02724 // IN PVOID VA 02725 // ); 02726 // 02727 // Routine Description: 02728 // 02729 // This macro determines if a given virtual address resides in 02730 // the hyper space. 02731 // 02732 // Arguments 02733 // 02734 // VA - Supplies the virtual address. 02735 // 02736 // Return Value: 02737 // 02738 // FALSE if it is not a hyper space address, TRUE if it is. 02739 // 02740 //-- 02741 02742 #define MI_IS_HYPER_SPACE_ADDRESS(VA) \ 02743 (((ULONG_PTR)VA >= (ULONG_PTR)HYPER_SPACE) && ((ULONG_PTR)VA <= HYPER_SPACE_END)) 02744 02745 //++ 02746 //BOOLEAN 02747 //MI_IS_PTE_ADDRESS ( 02748 // IN PMMPTE PTE 02749 // ); 02750 // 02751 // Routine Description: 02752 // 02753 // This macro determines if a given virtual address is really a 02754 // page table page (PTE) address. 02755 // 02756 // Arguments 02757 // 02758 // PTE - Supplies the PTE virtual address. 02759 // 02760 // Return Value: 02761 // 02762 // FALSE if it is not a PTE address, TRUE if it is. 02763 // 02764 //-- 02765 02766 #define MI_IS_PTE_ADDRESS(PTE) \ 02767 (((PTE >= (PMMPTE)PTE_UBASE) && (PTE <= (PMMPTE)PTE_UTOP)) || \ 02768 ((PTE >= (PMMPTE)PTE_KBASE) && (PTE <= (PMMPTE)PTE_KTOP)) || \ 02769 ((PTE >= (PMMPTE)PTE_SBASE) && (PTE <= (PMMPTE)PTE_STOP))) 02770 02771 02772 #define MI_IS_PPE_ADDRESS(PTE) \ 02773 (((PTE >= (PMMPTE)PDE_UTBASE) && (PTE <= (PMMPTE)(PDE_UTBASE + PAGE_SIZE))) || \ 02774 ((PTE >= (PMMPTE)PDE_KTBASE) && (PTE <= (PMMPTE)(PDE_KTBASE + PAGE_SIZE))) || \ 02775 ((PTE >= (PMMPTE)PDE_STBASE) && (PTE <= (PMMPTE)(PDE_STBASE + PAGE_SIZE)))) 02776 02777 //++ 02778 //BOOLEAN 02779 //MI_IS_KERNEL_PTE_ADDRESS ( 02780 // IN PMMPTE PTE 02781 // ); 02782 // 02783 // Routine Description: 02784 // 02785 // This macro determines if a given virtual address is really a 02786 // kernel page table page (PTE) address. 02787 // 02788 // Arguments 02789 // 02790 // PTE - Supplies the PTE virtual address. 02791 // 02792 // Return Value: 02793 // 02794 // FALSE if it is not a kernel PTE address, TRUE if it is. 02795 // 02796 //-- 02797 02798 #define MI_IS_KERNEL_PTE_ADDRESS(PTE) \ 02799 (((PMMPTE)PTE >= (PMMPTE)PTE_KBASE) && ((PMMPTE)PTE <= (PMMPTE)PTE_KTOP)) 02800 02801 02802 //++ 02803 //BOOLEAN 02804 //MI_IS_USER_PTE_ADDRESS ( 02805 // IN PMMPTE PTE 02806 // ); 02807 // 02808 // Routine Description: 02809 // 02810 // This macro determines if a given virtual address is really a 02811 // page table page (PTE) address. 02812 // 02813 // Arguments 02814 // 02815 // PTE - Supplies the PTE virtual address. 02816 // 02817 // Return Value: 02818 // 02819 // FALSE if it is not a PTE address, TRUE if it is. 02820 // 02821 //-- 02822 02823 #define MI_IS_USER_PTE_ADDRESS(PTE) \ 02824 ((PTE >= (PMMPTE)PTE_UBASE) && (PTE <= (PMMPTE)PTE_UTOP)) 02825 02826 02827 //++ 02828 //BOOLEAN 02829 //MI_IS_PAGE_DIRECTORY_ADDRESS ( 02830 // IN PMMPTE PDE 02831 // ); 02832 // 02833 // Routine Description: 02834 // 02835 // This macro determines if a given virtual address is really a 02836 // page directory page (PDE) address. 02837 // 02838 // Arguments 02839 // 02840 // PDE - Supplies the virtual address. 02841 // 02842 // Return Value: 02843 // 02844 // FALSE if it is not a PDE address, TRUE if it is. 02845 // 02846 //-- 02847 02848 #define MI_IS_PAGE_DIRECTORY_ADDRESS(PDE) \ 02849 (((PDE >= (PMMPTE)PDE_UBASE) && (PDE <= (PMMPTE)PDE_UTOP)) || \ 02850 ((PDE >= (PMMPTE)PDE_KBASE) && (PDE <= (PMMPTE)PDE_KTOP)) || \ 02851 ((PDE >= (PMMPTE)PDE_SBASE) && (PDE <= (PMMPTE)PDE_STOP))) 02852 02853 //++ 02854 //BOOLEAN 02855 //MI_IS_USER_PDE_ADDRESS ( 02856 // IN PMMPTE PDE 02857 // ); 02858 // 02859 // Routine Description: 02860 // 02861 // This macro determines if a given virtual address is really a 02862 // user page directory page (PDE) address. 02863 // 02864 // Arguments 02865 // 02866 // PDE - Supplies the PDE virtual address. 02867 // 02868 // Return Value: 02869 // 02870 // FALSE if it is not a user PDE address, TRUE if it is. 02871 // 02872 //-- 02873 02874 #define MI_IS_USER_PDE_ADDRESS(PDE) \ 02875 ((PDE >= (PMMPTE)PDE_UBASE) && (PDE <= (PMMPTE)PDE_UTOP)) 02876 02877 02878 //++ 02879 //BOOLEAN 02880 //MI_IS_KERNEL_PDE_ADDRESS ( 02881 // IN PMMPTE PDE 02882 // ); 02883 // 02884 // Routine Description: 02885 // 02886 // This macro determines if a given virtual address is really a 02887 // kernel page directory page (PDE) address. 02888 // 02889 // Arguments 02890 // 02891 // PDE - Supplies the PDE virtual address. 02892 // 02893 // Return Value: 02894 // 02895 // FALSE if it is not a user PDE address, TRUE if it is. 02896 // 02897 //-- 02898 02899 #define MI_IS_KERNEL_PDE_ADDRESS(PDE) \ 02900 ((PDE >= (PMMPTE)PDE_KBASE) && (PDE <= (PMMPTE)PDE_KTOP)) 02901 02902 02903 //++ 02904 //BOOLEAN 02905 //MI_IS_PROCESS_SPACE_ADDRESS ( 02906 // IN PVOID VA 02907 // ); 02908 // 02909 // Routine Description: 02910 // 02911 // This macro determines if a given virtual address resides in 02912 // the per-process space. 02913 // 02914 // Arguments 02915 // 02916 // VA - Supplies the virtual address. 02917 // 02918 // Return Value: 02919 // 02920 // FALSE if it is not a per-process address, TRUE if it is. 02921 // 02922 //-- 02923 02924 #define MI_IS_PROCESS_SPACE_ADDRESS(VA) (((ULONG_PTR)VA >> 61) == UREGION_INDEX) 02925 02926 //++ 02927 //BOOLEAN 02928 //MI_IS_SYSTEM_ADDRESS ( 02929 // IN PVOID VA 02930 // ); 02931 // 02932 // Routine Description: 02933 // 02934 // This macro determines if a given virtual address resides in 02935 // the system (global) space. 02936 // 02937 // Arguments 02938 // 02939 // VA - Supplies the virtual address. 02940 // 02941 // Return Value: 02942 // 02943 // FALSE if it is not a system (global) address, TRUE if it is. 02944 // 02945 //-- 02946 02947 #define MI_IS_SYSTEM_ADDRESS(VA) (((ULONG_PTR)VA >> 61) == KREGION_INDEX) 02948 02949 02950 // 02951 // Generate kernel segment physical address 02952 // 02953 02954 //PVOID 02955 //MiGetKSegAddress ( 02956 // PFN_NUMBER FrameNumber 02957 // ); 02958 02959 // 02960 //++ 02961 //PVOID 02962 //KSEG_ADDRESS ( 02963 // IN ULONG PAGE 02964 // ); 02965 // 02966 // Routine Description: 02967 // 02968 // This macro returns a KSEG virtual address which maps the page. 02969 // 02970 // Arguments: 02971 // 02972 // PAGE - Supplies the physical page frame number 02973 // 02974 // Return Value: 02975 // 02976 // The address of the KSEG address 02977 // 02978 //-- 02979 02980 // #define KSEG_ADDRESS(PAGE) ((PVOID)(KSEG3_BASE | ((ULONG_PTR)(PAGE) << PAGE_SHIFT))) 02981 02982 // #define KSEG_ADDRESS(PAGE) MiGetKSegAddress ((ULONG)PAGE) 02983 02984 02985 // 02986 //++ 02987 //PVOID 02988 //KSEG0_ADDRESS ( 02989 // IN ULONG PAGE 02990 // ); 02991 // 02992 // Routine Description: 02993 // 02994 // This macro returns a KSEG0 virtual address which maps the page. 02995 // 02996 // Arguments: 02997 // 02998 // PAGE - Supplies the physical page frame number 02999 // 03000 // Return Value: 03001 // 03002 // The address of the KSEG address 03003 // 03004 //-- 03005 03006 #define KSEG0_ADDRESS(PAGE) \ 03007 (PVOID)(KSEG0_BASE | ((PAGE) << PAGE_SHIFT)) 03008 03009 03010 extern MMPTE ValidPpePte; 03011 03012 extern PFN_NUMBER MmSystemParentTablePage; 03013 03014 //++ 03015 //PMMPTE 03016 //MiGetPpeAddress ( 03017 // IN PVOID va 03018 // ); 03019 // 03020 // Routine Description: 03021 // 03022 // MiGetPpeAddress returns the address of the page directory parent entry 03023 // which maps the given virtual address. This is one level above the 03024 // page directory. 03025 // 03026 // Arguments 03027 // 03028 // Va - Supplies the virtual address to locate the PPE for. 03029 // 03030 // Return Value: 03031 // 03032 // The address of the PPE. // LWFIX: expand for 3 level 03033 // 03034 //-- 03035 03036 #if PTE_THASH 03037 03038 __inline 03039 PMMPTE 03040 MiGetPpeAddress_XX( 03041 IN PVOID Va 03042 ) 03043 { 03044 if (((ULONG_PTR)(Va) & PTE_BASE) == PTE_BASE) { 03045 03046 return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))); 03047 03048 } else { 03049 03050 return ((PMMPTE)(__thash(__thash(__thash((ULONG_PTR)Va))))); 03051 03052 } 03053 } 03054 03055 #define MiGetPpeAddress(va) MiGetPpeAddress_XX((PVOID)(va)) 03056 03057 #else 03058 03059 #define MiGetPpeAddress(Va) \ 03060 (((((ULONG_PTR)(Va)) & PTE_BASE) == PTE_BASE) ? \ 03061 ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :\ 03062 ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | \ 03063 ((((((ULONG_PTR)(Va)) >> PDI1_SHIFT) << PTE_SHIFT) & \ 03064 (~(PDE_TBASE|VRN_MASK)) ) + PDE_TBASE)))) 03065 03066 #endif 03067 03068 //MiGetPdeAddress ( 03069 // IN PVOID va 03070 // ); 03071 // 03072 // Routine Description: 03073 // 03074 // MiGetPdeAddress returns the address of the PDE which maps the 03075 // given virtual address. 03076 // 03077 // Argments 03078 // 03079 // Va - Supplies the virtual address to locate the PDE for. 03080 // 03081 // Return Value: 03082 // 03083 // The address of the PDE. 03084 // 03085 //-- 03086 03087 #if PTE_THASH 03088 03089 __inline 03090 PMMPTE 03091 MiGetPdeAddress_XX( 03092 IN PVOID Va 03093 ) 03094 { 03095 if (((ULONG_PTR)(Va) & PDE_BASE) == PDE_BASE) { 03096 03097 return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))); 03098 03099 } else { 03100 03101 return ((PMMPTE)(__thash(__thash((ULONG_PTR)(Va))))); 03102 } 03103 } 03104 03105 #define MiGetPdeAddress(va) MiGetPdeAddress_XX((PVOID)(va)) 03106 03107 #else 03108 03109 #define MiGetPdeAddress(Va) \ 03110 (((((ULONG_PTR)(Va)) & PDE_BASE) == PDE_BASE) ? \ 03111 ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :\ 03112 ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | \ 03113 ((((((ULONG_PTR)(Va)) >> PDI_SHIFT) << PTE_SHIFT) & (~(PDE_BASE|VRN_MASK))) + PDE_BASE)))) 03114 03115 #endif 03116 03117 03118 //++ 03119 //PMMPTE 03120 //MiGetPteAddress ( 03121 // IN PVOID va 03122 // ); 03123 // 03124 // Routine Description: 03125 // 03126 // MiGetPteAddress returns the address of the PTE which maps the 03127 // given virtual address. 03128 // 03129 // Argments 03130 // 03131 // Va - Supplies the virtual address to locate the PTE for. 03132 // 03133 // Return Value: 03134 // 03135 // The address of the PTE. 03136 // 03137 //-- 03138 03139 #if PTE_THASH 03140 03141 __inline 03142 PMMPTE 03143 MiGetPteAddress_XX( 03144 IN PVOID Va 03145 ) 03146 { 03147 if (((ULONG_PTR)(Va) & PDE_TBASE) == PDE_TBASE) { 03148 03149 return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))); 03150 03151 } else { 03152 03153 return ((PMMPTE)(__thash((ULONG_PTR)(Va)))); 03154 03155 } 03156 } 03157 03158 #define MiGetPteAddress(va) MiGetPteAddress_XX((PVOID)(va)) 03159 03160 #else 03161 03162 #define MiGetPteAddress(Va) \ 03163 (((((ULONG_PTR)(Va)) & PDE_TBASE) == PDE_TBASE) ? \ 03164 ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :\ 03165 ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | \ 03166 ((((((ULONG_PTR)(Va)) >> PTI_SHIFT) << PTE_SHIFT) & (~(PTE_BASE|VRN_MASK))) + PTE_BASE)))) 03167 03168 #endif 03169 03170 03171 #define MI_IS_PTE_PROTOTYPE(PointerPte) (!MI_IS_USER_PTE_ADDRESS (PointerPte)) 03172 03173 //++ 03174 //BOOLEAN 03175 //MI_IS_SYSTEM_CACHE_ADDRESS ( 03176 // IN PVOID VA 03177 // ); 03178 // 03179 // Routine Description: 03180 // 03181 // This macro takes a virtual address and determines if 03182 // it is a system cache address. 03183 // 03184 // Arguments 03185 // 03186 // VA - Supplies a virtual address. 03187 // 03188 // Return Value: 03189 // 03190 // TRUE if the address is in the system cache, FALSE if not. 03191 // 03192 //-- 03193 03194 #define MI_IS_SYSTEM_CACHE_ADDRESS(VA) \ 03195 (((PVOID)(VA) >= (PVOID)MmSystemCacheStart && \ 03196 (PVOID)(VA) <= (PVOID)MmSystemCacheEnd)) 03197 03198 03199 #if defined(_MIALT4K_) 03200 03201 // 03202 // Define constants and macros for alternate 4kb table. 03203 // 03204 // These are constants and defines that mimic the PAGE_SIZE constant but are 03205 // hard coded to use 4K page values. 03206 // 03207 03208 #define PAGE_4K 4096 03209 #define PAGE_4K_SHIFT 12 03210 #define PAGE_4K_MASK (PAGE_4K - 1) 03211 #define PAGE_4K_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_4K - 1))) 03212 #define ROUND_TO_4K_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_4K - 1) & ~(PAGE_4K - 1)) 03213 03214 #define PAGE_NEXT_ALIGN(Va) ((PVOID)(PAGE_ALIGN((ULONG_PTR)Va + PAGE_SIZE - 1))) 03215 03216 #define BYTES_TO_4K_PAGES(Size) ((ULONG)((ULONG_PTR)(Size) >> PAGE_4K_SHIFT) + \ 03217 (((ULONG)(Size) & (PAGE_4K - 1)) != 0)) 03218 03219 // 03220 // Relative constants between native pages and 4K pages 03221 // 03222 03223 #define SPLITS_PER_PAGE (PAGE_SIZE / PAGE_4K) 03224 #define PAGE_SHIFT_DIFF (PAGE_SHIFT - PAGE_4K_SHIFT) 03225 03226 #define ALT_PTE_SHIFT 3 03227 03228 #define ALT_PROTECTION_MASK (MM_PTE_EXECUTE_MASK|MM_PTE_WRITE_MASK) 03229 03230 #define MiGetAltPteAddress(VA) \ 03231 ((PMMPTE) (ALT4KB_PERMISSION_TABLE_START + \ 03232 ((((ULONG_PTR) (VA)) >> PAGE_4K_SHIFT) << ALT_PTE_SHIFT))) 03233 03234 // 03235 // define Alternate 4k table flags 03236 // 03237 03238 #define MI_ALTFLG_FLUSH2G 0x0000000000000001 03239 03240 // 03241 // define MiProtectFor4kPage flages 03242 // 03243 03244 #define ALT_ALLOCATE 1 03245 #define ALT_COMMIT 2 03246 #define ALT_CHANGE 4 03247 03248 // 03249 // define ATE protection bits 03250 // 03251 03252 #define MM_ATE_COMMIT 0x0000000000000001 03253 #define MM_ATE_ACCESS 0x0000000000000020 03254 03255 #define MM_ATE_READONLY 0x0000000000000200 03256 #define MM_ATE_EXECUTE 0x0400000000000200 03257 #define MM_ATE_EXECUTE_READ 0x0400000000000200 03258 #define MM_ATE_READWRITE 0x0000000000000600 03259 #define MM_ATE_WRITECOPY 0x0020000000000200 03260 #define MM_ATE_EXECUTE_READWRITE 0x0400000000000600 03261 #define MM_ATE_EXECUTE_WRITECOPY 0x0420000000000400 03262 03263 #define MM_ATE_ZEROFILL 0x0800000000000000 03264 #define MM_ATE_NOACCESS 0x1000000000000000 03265 #define MM_ATE_COPY_ON_WRITE 0x2000000000000000 03266 #define MM_ATE_PRIVATE 0x8000000000000000 03267 #define MM_ATE_PROTO_MASK 0x0000000000000621 03268 03269 03270 // 03271 // How big is the IA32 subsystem allowed? 03272 // Assume it will be "not Large Address Aware" so limited to 2G 03273 // 03274 #define _MAX_WOW64_ADDRESS (0x00000000080000000UI64) 03275 03276 MmX86Fault ( 03277 IN BOOLEAN StoreInstruction, 03278 IN PVOID VirtualAddress, 03279 IN KPROCESSOR_MODE PreviousMode, 03280 IN PVOID TrapInformation 03281 ); 03282 03283 VOID 03284 MiProtectFor4kPage( 03285 IN PVOID Base, 03286 IN SIZE_T Size, 03287 IN ULONG NewProtect, 03288 IN ULONG Flags, 03289 IN PEPROCESS Process 03290 ); 03291 03292 VOID 03293 MiProtectMapFileFor4kPage( 03294 IN PVOID Base, 03295 IN SIZE_T Size, 03296 IN ULONG NewProtect, 03297 IN PMMPTE PointerPte, 03298 IN PEPROCESS Process 03299 ); 03300 03301 VOID 03302 MiProtectImageFileFor4kPage( 03303 IN PVOID Base, 03304 IN SIZE_T Size, 03305 IN PMMPTE PointerPte, 03306 IN PEPROCESS Process 03307 ); 03308 03309 VOID 03310 MiReleaseFor4kPage( 03311 IN PVOID StartVirtual, 03312 IN PVOID EndVirtual, 03313 IN PEPROCESS Process 03314 ); 03315 03316 VOID 03317 MiDecommitFor4kPage( 03318 IN PVOID StartVirtual, 03319 IN PVOID EndVirtual, 03320 IN PEPROCESS Process 03321 ); 03322 03323 VOID 03324 MiDeleteFor4kPage( 03325 IN PVOID StartVirtual, 03326 IN PVOID EndVirtual, 03327 IN PEPROCESS Process 03328 ); 03329 03330 VOID 03331 MiQueryRegionFor4kPage( 03332 IN PVOID BaseAddress, 03333 IN PVOID EndAddress, 03334 IN OUT PSIZE_T RegionSize, 03335 IN OUT PULONG RegionState, 03336 IN OUT PULONG RegionProtect, 03337 IN PEPROCESS Process 03338 ); 03339 03340 ULONG 03341 MiQueryProtectionFor4kPage ( 03342 IN PVOID BaseAddress, 03343 IN PEPROCESS Process 03344 ); 03345 03346 NTSTATUS 03347 MiInitializeAlternateTable( 03348 PEPROCESS Process 03349 ); 03350 03351 VOID 03352 MiDeleteAlternateTable( 03353 PEPROCESS Process 03354 ); 03355 03356 VOID 03357 MiLockFor4kPage( 03358 PVOID CapturedBase, 03359 SIZE_T CapturedRegionSize, 03360 PEPROCESS Process 03361 ); 03362 03363 NTSTATUS 03364 MiUnlockFor4kPage( 03365 PVOID CapturedBase, 03366 SIZE_T CapturedRegionSize, 03367 PEPROCESS Process 03368 ); 03369 03370 BOOLEAN 03371 MiShouldBeUnlockedFor4kPage( 03372 PVOID VirtualAddress, 03373 PEPROCESS Process 03374 ); 03375 03376 VOID 03377 MiMarkSplitPages( 03378 IN PVOID StartVirtual, 03379 IN PVOID EndVirtual, 03380 IN PULONG Bitmap, 03381 IN BOOLEAN SetBit 03382 ); 03383 03384 ULONG 03385 MiMakeProtectForNativePage( 03386 IN PVOID VirtualAddress, 03387 IN ULONG NewProtect, 03388 IN PEPROCESS Process 03389 ); 03390 03391 03392 extern ULONG MmProtectToPteMaskForIA32[32]; 03393 extern ULONG MmProtectToPteMaskForSplit[32]; 03394 extern ULONGLONG MmProtectToAteMask[32]; 03395 03396 03397 #define MiMakeProtectionAteMask(NewProtect) MmProtectToAteMask[NewProtect] 03398 03399 03400 #define _ALTPERM_BITMAP_MASK ((_MAX_WOW64_ADDRESS - 1) >> PTI_SHIFT) 03401 03402 #if 1 03403 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 03404 (OUTPTE).u.Long = 0; \ 03405 (OUTPTE).u.Hard.Valid = 1; \ 03406 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 03407 (OUTPTE).u.Hard.Exception = 1; \ 03408 (OUTPTE).u.Hard.PageFrameNumber = FRAME; \ 03409 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 03410 { \ 03411 PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; \ 03412 if ((_Wow64Process != NULL) && \ 03413 ((PPTE >= (PMMPTE)PTE_UBASE) && \ 03414 (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { \ 03415 if (MI_CHECK_BIT(_Wow64Process->AltPermBitmap, \ 03416 ((ULONG_PTR)PPTE >> PTE_SHIFT) & _ALTPERM_BITMAP_MASK) != 0) { \ 03417 (OUTPTE).u.Long |= (MmProtectToPteMaskForSplit[PMASK]); \ 03418 } else { \ 03419 (OUTPTE).u.Long |= (MmProtectToPteMaskForIA32[PMASK]); \ 03420 (OUTPTE).u.Hard.Accessed = 1; \ 03421 } \ 03422 } else { \ 03423 (OUTPTE).u.Hard.Accessed = 1; \ 03424 (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]);\ 03425 }\ 03426 } 03427 03428 03429 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 03430 ASSERT (((PPTE)->u.Hard.Valid == 0) && \ 03431 ((PPTE)->u.Trans.Prototype == 0) && \ 03432 ((PPTE)->u.Trans.Transition == 1)); \ 03433 (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000; \ 03434 (OUTPTE).u.Hard.Valid = 1; \ 03435 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 03436 (OUTPTE).u.Hard.Exception = 1; \ 03437 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 03438 { \ 03439 PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; \ 03440 if ((_Wow64Process != NULL) && \ 03441 ((PPTE >= (PMMPTE)PTE_UBASE) && \ 03442 (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { \ 03443 if (MI_CHECK_BIT(_Wow64Process->AltPermBitmap, \ 03444 ((ULONG_PTR)PPTE >> PTE_SHIFT) & _ALTPERM_BITMAP_MASK) != 0) { \ 03445 (OUTPTE).u.Long |= (MmProtectToPteMaskForSplit[(PPTE)->u.Trans.Protection]); \ 03446 } else { \ 03447 (OUTPTE).u.Long |= (MmProtectToPteMaskForIA32[(PPTE)->u.Trans.Protection]); \ 03448 (OUTPTE).u.Hard.Accessed = 1; \ 03449 } \ 03450 } else { \ 03451 (OUTPTE).u.Hard.Accessed = 1; \ 03452 (OUTPTE).u.Long |=(MmProtectToPteMask[(PPTE)->u.Trans.Protection]);\ 03453 }\ 03454 } 03455 #else 03456 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 03457 (OUTPTE).u.Long = 0; \ 03458 (OUTPTE).u.Hard.Valid = 1; \ 03459 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 03460 (OUTPTE).u.Hard.Exception = 1; \ 03461 (OUTPTE).u.Hard.PageFrameNumber = FRAME; \ 03462 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 03463 { \ 03464 PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; \ 03465 if ((_Wow64Process != NULL) && \ 03466 ((PPTE >= (PMMPTE)PTE_UBASE) && \ 03467 (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { \ 03468 (OUTPTE).u.Long |= MM_PTE_READONLY; \ 03469 } else { \ 03470 (OUTPTE).u.Hard.Accessed = 1; \ 03471 (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]);\ 03472 }\ 03473 } 03474 03475 03476 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 03477 ASSERT (((PPTE)->u.Hard.Valid == 0) && \ 03478 ((PPTE)->u.Trans.Prototype == 0) && \ 03479 ((PPTE)->u.Trans.Transition == 1)); \ 03480 (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000; \ 03481 (OUTPTE).u.Hard.Valid = 1; \ 03482 (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED; \ 03483 (OUTPTE).u.Hard.Exception = 1; \ 03484 (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \ 03485 { \ 03486 PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; \ 03487 if ((_Wow64Process != NULL) && \ 03488 ((PPTE >= (PMMPTE)PTE_UBASE) && \ 03489 (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { \ 03490 (OUTPTE).u.Long |= MM_PTE_READONLY; \ 03491 } else { \ 03492 (OUTPTE).u.Hard.Accessed = 1; \ 03493 (OUTPTE).u.Long |=(MmProtectToPteMask[(PPTE)->u.Trans.Protection]);\ 03494 }\ 03495 } 03496 #endif 03497 03498 #define LOCK_ALTERNATE_TABLE(PWOW64) \ 03499 ExAcquireFastMutex( &(PWOW64)->AlternateTableLock) 03500 03501 #define UNLOCK_ALTERNATE_TABLE(PWOW64) \ 03502 ExReleaseFastMutex(&(PWOW64)->AlternateTableLock) 03503 03504 #define MI_IS_ALT_PAGE_TABLE_ADDRESS(PPTE) \ 03505 (((PPTE) >= (PMMPTE)ALT4KB_PERMISSION_TABLE_START) && \ 03506 ((PPTE) < (PMMPTE)ALT4KB_PERMISSION_TABLE_END)) 03507 03508 #endif 03509 03510 //++ 03511 //VOID 03512 //MI_BARRIER_SYNCHRONIZE ( 03513 // IN ULONG TimeStamp 03514 // ); 03515 // 03516 // Routine Description: 03517 // 03518 // MI_BARRIER_SYNCHRONIZE compares the argument timestamp against the 03519 // current IPI barrier sequence stamp. When equal, all processors will 03520 // issue memory barriers to ensure that newly created pages remain coherent. 03521 // 03522 // When a page is put in the zeroed or free page list the current 03523 // barrier sequence stamp is read (interlocked - this is necessary 03524 // to get the correct value - memory barriers won't do the trick) 03525 // and stored in the pfn entry for the page. The current barrier 03526 // sequence stamp is maintained by the IPI send logic and is 03527 // incremented (interlocked) when the target set of an IPI send 03528 // includes all processors, but the one doing the send. When a page 03529 // is needed its sequence number is compared against the current 03530 // barrier sequence number. If it is equal, then the contents of 03531 // the page may not be coherent on all processors, and an IPI must 03532 // be sent to all processors to ensure a memory barrier is 03533 // executed (generic call can be used for this). Sending the IPI 03534 // automatically updates the barrier sequence number. The compare 03535 // is for equality as this is the only value that requires the IPI 03536 // (i.e., the sequence number wraps, values in both directions are 03537 // older). When a page is removed in this fashion and either found 03538 // to be coherent or made coherent, it cannot be modified between 03539 // that time and writing the PTE. If the page is modified between 03540 // these times, then an IPI must be sent. 03541 // 03542 // Arguments 03543 // 03544 // TimeStamp - Supplies the timestamp at the time when the page was zeroed. 03545 // 03546 // Return Value: 03547 // 03548 // None. 03549 // 03550 //-- 03551 03552 // currently does nothing on MERCED. 03553 03554 #define MI_BARRIER_SYNCHRONIZE(TimeStamp) 03555 03556 //++ 03557 //VOID 03558 //MI_BARRIER_STAMP_ZEROED_PAGE ( 03559 // IN PULONG PointerTimeStamp 03560 // ); 03561 // 03562 // Routine Description: 03563 // 03564 // MI_BARRIER_STAMP_ZEROED_PAGE issues an interlocked read to get the 03565 // current IPI barrier sequence stamp. This is called AFTER a page is 03566 // zeroed. 03567 // 03568 // Arguments 03569 // 03570 // PointerTimeStamp - Supplies a timestamp pointer to fill with the 03571 // current IPI barrier sequence stamp. 03572 // 03573 // Return Value: 03574 // 03575 // None. 03576 // 03577 //-- 03578 03579 // currently does nothing on MERCED. 03580 03581 #define MI_BARRIER_STAMP_ZEROED_PAGE(PointerTimeStamp) 03582 03583 //++ 03584 //VOID 03585 //MI_FLUSH_SINGLE_SESSION_TB ( 03586 // IN PVOID Virtual, 03587 // IN ULONG Invalid, 03588 // IN LOGICAL AllProcessors, 03589 // IN PMMPTE PtePointer, 03590 // IN MMPTE PteValue, 03591 // IN MMPTE PreviousPte 03592 // ); 03593 // 03594 // Routine Description: 03595 // 03596 // MI_FLUSH_SINGLE_SESSION_TB flushes the requested single address 03597 // translation from the TB. 03598 // 03599 // Since IA64 supports ASNs and session space doesn't have one, the entire 03600 // TB needs to be flushed. 03601 // 03602 // Arguments 03603 // 03604 // Virtual - Supplies the virtual address to invalidate. 03605 // 03606 // Invalid - TRUE if invalidating. 03607 // 03608 // AllProcessors - TRUE if all processors need to be IPI'd. 03609 // 03610 // PtePointer - Supplies the PTE to invalidate. 03611 // 03612 // PteValue - Supplies the new PTE value. 03613 // 03614 // PreviousPte - The previous PTE value is returned here. 03615 // 03616 // Return Value: 03617 // 03618 // None. 03619 // 03620 //-- 03621 03622 #define MI_FLUSH_SINGLE_SESSION_TB(Virtual, Invalid, AllProcessors, PtePointer, PteValue, PreviousPte) \ 03623 PreviousPte.u.Flush = *PtePointer; \ 03624 *PtePointer = PteValue; \ 03625 KeFlushEntireTb (TRUE, TRUE); 03626 03627 03628 //++ 03629 //VOID 03630 //MI_FLUSH_ENTIRE_SESSION_TB ( 03631 // IN ULONG Invalid, 03632 // IN LOGICAL AllProcessors 03633 // ); 03634 // 03635 // Routine Description: 03636 // 03637 // MI_FLUSH_ENTIRE_SESSION_TB flushes the entire TB on IA64 since 03638 // the IA64 supports ASNs. 03639 // 03640 // Arguments 03641 // 03642 // Invalid - TRUE if invalidating. 03643 // 03644 // AllProcessors - TRUE if all processors need to be IPI'd. 03645 // 03646 // Return Value: 03647 // 03648 // None. 03649 // 03650 03651 #define MI_FLUSH_ENTIRE_SESSION_TB(Invalid, AllProcessors) \ 03652 KeFlushEntireTb (Invalid, AllProcessors); 03653 03654 VOID 03655 MiSweepCacheMachineDependent( 03656 IN PVOID VirtualAddress, 03657 IN SIZE_T Size, 03658 IN MEMORY_CACHING_TYPE CacheType 03659 ); 03660 03661 #define MI_IS_PCR_PAGE(Va) (((PVOID)PCR <= Va) && (Va < (PVOID)(PCR+PAGE_SIZE))) 03662 03663 //++ 03664 //BOOLEAN 03665 //MI_IS_ADDRESS_VALID_FOR_KD ( 03666 // IN PVOID VirtualAddress 03667 // ); 03668 // 03669 // Routine Description: 03670 // 03671 // This macro deterines if a give virtual address is really a valid 03672 // virtual address for the kerenl debugger memory references 03673 // 03674 // Argments 03675 // 03676 // VirtualAddress - Supplies the virtual address. 03677 // 03678 // Return Value: 03679 // 03680 // FALSE if it is not a physical address, TRUE if it is. 03681 // 03682 //-- 03683 03684 03685 #define MI_IS_ADDRESS_VALID_FOR_KD(VirtualAddress) \ 03686 ((VirtualAddress <= (PVOID)(HYPER_SPACE_END)) || \ 03687 (MI_IS_PTE_ADDRESS((PMMPTE)VirtualAddress)) || \ 03688 (MI_IS_PAGE_DIRECTORY_ADDRESS((PMMPTE)VirtualAddress)) || \ 03689 (MI_IS_PPE_ADDRESS((PMMPTE)VirtualAddress)) || \ 03690 ((VirtualAddress >= MM_SYSTEM_RANGE_START) && \ 03691 (VirtualAddress < (PVOID)MM_SYSTEM_SPACE_END)) || \ 03692 (MI_IS_SESSION_ADDRESS(VirtualAddress)) || \ 03693 (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) || \ 03694 (MI_IS_PCR_PAGE(VirtualAddress)))

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