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