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

mialpha.h

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

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