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

mir4000.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 mir4000.h 00008 00009 Abstract: 00010 00011 This module contains the private data structures and procedure 00012 prototypes for the hardware dependent portion of the 00013 memory management system. 00014 00015 It is specifically tailored for the MIPS R4000 machine. 00016 00017 Author: 00018 00019 Lou Perazzoli (loup) 9-Jan-1991 00020 00021 Revision History: 00022 00023 --*/ 00024 00025 #define HEADER_FILE 00026 #include <kxmips.h> 00027 00028 #define VLM_SUPPORT 1 00029 00030 // 00031 // Define base of kernel segment 0. 00032 // 00033 00034 #if defined(VLM_SUPPORT) 00035 #define MM_KSEG0_BASE KSEG0_BASE64 00036 #define MM_HIGHEST_USER_ADDRESSxx MM_HIGHEST_USER_ADDRESS64 00037 #else 00038 #define MM_KSEG0_BASE KSEG0_BASE 00039 #define MM_HIGHEST_USER_ADDRESSxx MM_HIGHEST_USER_ADDRESS 00040 #endif 00041 00042 // 00043 // The R4000 requires colored page support. 00044 // 00045 00046 // 00047 // The R4000 supports large pages. 00048 // 00049 00050 #define LARGE_PAGES 1 00051 00052 00053 /*++ 00054 00055 Virtual Memory Layout on the R4000 is: 00056 00057 +------------------------------------+ 00058 00000000 | | 00059 | | 00060 | | 00061 | User Mode Addresses | 00062 | | 00063 | All pages within this range | 00064 | are potentially accessable while | 00065 | the CPU is in USER mode. | 00066 | | 00067 | | 00068 +------------------------------------+ 00069 7ffff000 | 64k No Access Area | 00070 +------------------------------------+ 00071 80000000 | | KSEG_0 00072 | HAL loads kernel and initial | 00073 | boot drivers in first 16mb | 00074 | of this region. | 00075 | Kernel mode access only. | 00076 | | 00077 | Initial NonPaged Pool is within | 00078 | KEG_0 | 00079 | | 00080 +------------------------------------+ 00081 A0000000 | | KSEG_1 00082 | | 00083 | | 00084 | | 00085 +------------------------------------+ 00086 C0000000 | Page Table Pages mapped through | 00087 | this 4mb region | 00088 | Kernel mode access only. | 00089 | | 00090 +------------------------------------+ 00091 C2400000 | HyperSpace - working set lists | 00092 | and per process memory mangement | 00093 | structures mapped in this 4mb | 00094 | region. | 00095 | Kernel mode access only. | 00096 +------------------------------------+ 00097 C2800000 | System Cache Structures | 00098 | reside in this 4mb region | 00099 | Kernel mode access only. | 00100 +------------------------------------+ 00101 C2C00000 | System cache resides here. | 00102 | Kernel mode access only. | 00103 | | 00104 | | 00105 +------------------------------------+ 00106 DE000000 | System mapped views | 00107 | | 00108 | | 00109 +------------------------------------+ 00110 E1000000 | Start of paged system area | 00111 | Kernel mode access only. | 00112 | | 00113 | | 00114 +------------------------------------+ 00115 | | 00116 | Kernel mode access only. | 00117 | | 00118 | | 00119 FFBFFFFF | NonPaged System area | 00120 +------------------------------------+ 00121 FFC00000 | Last 4mb reserved for HAL usage | 00122 +------------------------------------+ 00123 00124 --*/ 00125 00126 // 00127 // PAGE_SIZE for MIPS r4000 is 4k, virtual page is 20 bits with a PAGE_SHIFT 00128 // byte offset. 00129 // 00130 00131 #define MM_VIRTUAL_PAGE_SHIFT 20 00132 00133 // 00134 // Address space layout definitions. 00135 // 00136 00137 //#define PDE_BASE ((ULONG)0xC0300000) 00138 #define PDE_BASE64 ((ULONG)0xC0302000) 00139 00140 //#define PTE_BASE ((ULONG)0xC0000000) 00141 #define PTE_BASE64 ((ULONG)0xC0800000) 00142 00143 #define MM_SYSTEM_SPACE_START (0xC2800000) 00144 00145 #define MM_SYSTEM_SPACE_END (0xFFFFFFFF) 00146 00147 #define MM_NONPAGED_SYSTEM_SPACE_START (0xF0000000) 00148 00149 #define PDE_TOP 0xC03FFFFF 00150 00151 #define MM_PAGES_IN_KSEG0 (((ULONG)KSEG1_BASE - (ULONG)KSEG0_BASE) >> PAGE_SHIFT) 00152 00153 #define HYPER_SPACE ((PVOID)0xC0400000) 00154 00155 #define HYPER_SPACE_END 0xC07fffff 00156 00157 // 00158 // Define the start and maximum size for the system cache. 00159 // Maximum size 436MB. 00160 // 00161 00162 #define MM_SYSTEM_CACHE_WORKING_SET (0xC2800000) 00163 00164 #define MM_SYSTEM_CACHE_START (0xC2C00000) 00165 00166 #define MM_SYSTEM_CACHE_END (0xDE000000) 00167 00168 #define MM_MAXIMUM_SYSTEM_CACHE_SIZE \ 00169 (((ULONG)MM_SYSTEM_CACHE_END - (ULONG)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT) 00170 00171 // 00172 // Define area for mapping views into system space. 00173 // 00174 00175 #define MM_SYSTEM_VIEW_START (0xDE000000) 00176 00177 #define MM_SYSTEM_VIEW_SIZE (48*1024*1024) 00178 00179 #define MM_PAGED_POOL_START ((PVOID)(0xE1000000)) 00180 00181 #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(0xEB000000)) 00182 00183 #define MmProtopte_Base ((ULONG)0xE1000000) 00184 00185 #define MM_NONPAGED_POOL_END ((PVOID)(0xFFBE0000)) 00186 00187 #define NON_PAGED_SYSTEM_END ((ULONG)0xFFFFFFF0) //quadword aligned. 00188 00189 // 00190 // Define absolute minumum and maximum count for system ptes. 00191 // 00192 00193 #define MM_MINIMUM_SYSTEM_PTES 9000 00194 00195 #define MM_MAXIMUM_SYSTEM_PTES 50000 00196 00197 #define MM_DEFAULT_SYSTEM_PTES 15000 00198 00199 // 00200 // Pool limits 00201 // 00202 00203 // 00204 // The maximim amount of nonpaged pool that can be initially created. 00205 // 00206 00207 #define MM_MAX_INITIAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) 00208 00209 // 00210 // The total amount of nonpaged pool (initial pool + expansion). 00211 // 00212 00213 #define MM_MAX_ADDITIONAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) 00214 00215 // 00216 // The maximum amount of paged pool that can be created. 00217 // 00218 00219 #define MM_MAX_PAGED_POOL ((ULONG)(192*1024*1024)) 00220 00221 #define MM_MAX_TOTAL_POOL (((ULONG)MM_NONPAGED_POOL_END) - ((ULONG)(MM_PAGED_POOL_START))) 00222 00223 00224 // 00225 // Structure layout defintions. 00226 // 00227 00228 #define PAGE_DIRECTORY_MASK ((ULONG)0x003FFFFF) 00229 00230 #define MM_VA_MAPPED_BY_PDE (0x400000) 00231 00232 #define LOWEST_IO_ADDRESS (0x40000000) 00233 00234 #define PTE_SHIFT (2) 00235 00236 // 00237 // 64-bit VA support. 00238 // 00239 00240 #define MM_HIGHEST_VAD_ADDRESS64 ((PVOID64)(0x800000000)) 00241 00242 // 00243 // The number of bits in a physical address. 00244 // 00245 00246 #define PHYSICAL_ADDRESS_BITS (36) 00247 00248 #define MM_MAXIMUM_NUMBER_OF_COLORS (8) 00249 00250 #define MM_PROTO_PTE_ALIGNMENT ((ULONG)MM_MAXIMUM_NUMBER_OF_COLORS * (ULONG)PAGE_SIZE) 00251 00252 // 00253 // Maximum number of paging files. 00254 // 00255 00256 #define MAX_PAGE_FILES 8 00257 00258 // 00259 // Hyper space definitions. 00260 // 00261 00262 #define HYPER_SPACE ((PVOID)0xC0400000) 00263 #define FIRST_MAPPING_PTE ((ULONG)0xC0400000) 00264 00265 // 00266 // On R4000 number of mapping PTEs must be a mulitple of 16 for alignment. 00267 // 00268 00269 #define NUMBER_OF_MAPPING_PTES 255 00270 #define LAST_MAPPING_PTE \ 00271 ((ULONG)((ULONG)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE))) 00272 00273 // 00274 // On R4000 this must be on a 64k virtual address boundary. 00275 // 00276 00277 #define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG)LAST_MAPPING_PTE + PAGE_SIZE)) 00278 00279 #define ZEROING_PAGE_PTE ((PMMPTE)((ULONG)IMAGE_MAPPING_PTE + PAGE_SIZE)) 00280 00281 #define WORKING_SET_LIST ((PVOID)((ULONG)ZEROING_PAGE_PTE + PAGE_SIZE)) 00282 00283 #define MM_MAXIMUM_WORKING_SET \ 00284 ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb 00285 00286 #define MM_WORKING_SET_END ((ULONG)0xC07FF000) 00287 00288 #define MM_PTE_GLOBAL_MASK 0x1 00289 #define MM_PTE_PROTOTYPE_MASK 0x4 00290 #define MM_PTE_VALID_MASK 0x2 00291 #define MM_PTE_DIRTY_MASK 0x4 00292 #define MM_PTE_CACHE_DISABLE_MASK 0x10 00293 #define MM_PTE_TRANSITION_MASK 0x100 00294 #define MM_PTE_WRITE_MASK 0x40000000 00295 #define MM_PTE_COPY_ON_WRITE_MASK 0x80000000 00296 #define MM_PTE_CACHE_ENABLE_MASK 0x0 // (PCR->AlignedCachePolicy) 00297 00298 // 00299 // Bit fields to or into PTE to make a PTE valid based on the 00300 // protection field of the invalid PTE. 00301 // 00302 00303 #define MM_PTE_NOACCESS 0x0 // not expressable on R4000 00304 #define MM_PTE_READONLY 0x0 00305 #define MM_PTE_READWRITE MM_PTE_WRITE_MASK 00306 #define MM_PTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) 00307 #define MM_PTE_EXECUTE 0x0 // read-only on R4000 00308 #define MM_PTE_EXECUTE_READ 0x0 00309 #define MM_PTE_EXECUTE_READWRITE MM_PTE_WRITE_MASK 00310 #define MM_PTE_EXECUTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) 00311 #define MM_PTE_NOCACHE (MM_PTE_CACHE_DISABLE_MASK) 00312 #define MM_PTE_GUARD 0x0 // not expressable on R4000 00313 #define MM_PTE_CACHE MM_PTE_CACHE_ENABLE_MASK 00314 00315 #define MM_PROTECT_FIELD_SHIFT 3 00316 00317 // 00318 // Zero PTE 00319 // 00320 00321 #define MM_ZERO_PTE 0 00322 00323 // 00324 // Zero Kernel PTE 00325 // 00326 00327 #define MM_ZERO_KERNEL_PTE MM_PTE_GLOBAL_MASK 00328 00329 00330 // 00331 // A demand zero PTE with a protection or PAGE_READWRITE. 00332 // 00333 00334 #define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 00335 00336 // 00337 // A demand zero PTE with a protection or PAGE_READWRITE for system space. 00338 // 00339 00340 #define MM_KERNEL_DEMAND_ZERO_PTE ((MM_READWRITE << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) 00341 00342 // 00343 // A no access PTE for system space. 00344 // 00345 00346 #define MM_KERNEL_NOACCESS_PTE ((MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) 00347 00348 // 00349 // Dirty bit definitions for clean and dirty. 00350 // 00351 00352 #define MM_PTE_CLEAN 0 00353 00354 #define MM_PTE_DIRTY 1 00355 00356 00357 00358 #define MM_STACK_ALIGNMENT 0x2000 //8k 00359 #define MM_STACK_OFFSET 0x1000 //align guard page on 4k offset 00360 00361 // 00362 // System process definitions 00363 // 00364 00365 #define PDE_PER_PAGE ((ULONG)1024) 00366 00367 #define PTE_PER_PAGE ((ULONG)1024) 00368 00369 // 00370 // Number of page table pages for user addresses. 00371 // 00372 00373 #define MM_USER_PAGE_TABLE_PAGES (512) 00374 00375 // 00376 // R4000 has 8 colors. 00377 // 00378 00379 #define MM_NUMBER_OF_COLORS 8 00380 00381 // 00382 // Mask for obtaining color from a physical page number. 00383 // 00384 00385 #define MM_COLOR_MASK 7 00386 00387 // 00388 // Define secondary color stride. 00389 // 00390 00391 #define MM_COLOR_STRIDE 11 00392 00393 // 00394 // Boundary for aligned pages of like color upon. 00395 // 00396 00397 #define MM_COLOR_ALIGNMENT 0x8000 00398 00399 // 00400 // Mask for isolating color from virtual address. 00401 // 00402 00403 #define MM_COLOR_MASK_VIRTUAL 0x7000 00404 00405 // 00406 // Define 1mb worth of secondary colors 00407 // 00408 00409 #define MM_SECONDARY_COLORS_DEFAULT (256) 00410 00411 #define MM_SECONDARY_COLORS_MIN (2) 00412 00413 #define MM_SECONDARY_COLORS_MAX (2048) 00414 00415 // 00416 // Mask for isolating secondary color from physical page number; 00417 // 00418 00419 extern ULONG MmSecondaryColorMask; 00420 00421 00422 00423 //++ 00424 //VOID 00425 //MI_MAKE_VALID_PTE ( 00426 // OUT OUTPTE, 00427 // IN FRAME, 00428 // IN PMASK, 00429 // IN OWNER 00430 // ); 00431 // 00432 // Routine Description: 00433 // 00434 // This macro makes a valid PTE from a page frame number, protection mask, 00435 // and owner. 00436 // 00437 // Argments 00438 // 00439 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00440 // 00441 // FRAME - Supplies the page frame number for the PTE. 00442 // 00443 // PMASK - Supplies the protection to set in the transition PTE. 00444 // 00445 // PPTE - Supplies a pointer to the PTE which is being made valid. 00446 // For prototype PTEs NULL should be specified. 00447 // 00448 // Return Value: 00449 // 00450 // None. 00451 // 00452 //-- 00453 00454 #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ 00455 { \ 00456 (OUTPTE).u.Long = ((FRAME << 6) | \ 00457 (MmProtectToPteMask[PMASK]) | \ 00458 MM_PTE_VALID_MASK); \ 00459 if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ 00460 (OUTPTE).u.Hard.Global = 1; \ 00461 } \ 00462 } 00463 00464 //++ 00465 //VOID 00466 //MI_MAKE_VALID_PTE_TRANSITION ( 00467 // IN OUT OUTPTE 00468 // IN PROTECT 00469 // ); 00470 // 00471 // Routine Description: 00472 // 00473 // This macro takes a valid pte and turns it into a transition PTE. 00474 // 00475 // Argments 00476 // 00477 // OUTPTE - Supplies the current valid PTE. This PTE is then 00478 // modified to become a transition PTE. 00479 // 00480 // PROTECT - Supplies the protection to set in the transition PTE. 00481 // 00482 // Return Value: 00483 // 00484 // None. 00485 // 00486 //-- 00487 00488 #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \ 00489 (OUTPTE).u.Long = ((((OUTPTE).u.Long & 0xffffffc0) << 3) | \ 00490 (((PROTECT) << MM_PROTECT_FIELD_SHIFT)) | \ 00491 ((OUTPTE).u.Long & MM_PTE_GLOBAL_MASK) | \ 00492 MM_PTE_TRANSITION_MASK); 00493 00494 00495 //++ 00496 //VOID 00497 //MI_MAKE_TRANSITION_PTE ( 00498 // OUT OUTPTE, 00499 // IN PAGE, 00500 // IN PROTECT, 00501 // IN PPTE 00502 // ); 00503 // 00504 // Routine Description: 00505 // 00506 // This macro takes a valid pte and turns it into a transition PTE. 00507 // 00508 // Argments 00509 // 00510 // OUTPTE - Supplies the PTE in which to build the transition PTE. 00511 // 00512 // PAGE - Supplies the page frame number for the PTE. 00513 // 00514 // PROTECT - Supplies the protection to set in the transition PTE. 00515 // 00516 // PPTE - Supplies a pointer to the PTE, this is used to determine 00517 // the owner of the PTE. 00518 // 00519 // Return Value: 00520 // 00521 // None. 00522 // 00523 //-- 00524 00525 #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \ 00526 (OUTPTE).u.Long = 0; \ 00527 (OUTPTE).u.Trans.PageFrameNumber = PAGE; \ 00528 (OUTPTE).u.Trans.Transition = 1; \ 00529 (OUTPTE).u.Trans.Protection = PROTECT; \ 00530 if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) {\ 00531 (OUTPTE).u.Hard.Global = 1; \ 00532 } 00533 00534 00535 //++ 00536 //VOID 00537 //MI_MAKE_TRANSITION_PTE_VALID ( 00538 // OUT OUTPTE, 00539 // IN PPTE 00540 // ); 00541 // 00542 // Routine Description: 00543 // 00544 // This macro takes a transition pte and makes it a valid PTE. 00545 // 00546 // Argments 00547 // 00548 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00549 // 00550 // PPTE - Supplies a pointer to the transition PTE. 00551 // 00552 // Return Value: 00553 // 00554 // None. 00555 // 00556 //-- 00557 00558 #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ 00559 (OUTPTE).u.Long = ((((PPTE)->u.Long >> 3) & 0xffffffc0) | \ 00560 (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) | \ 00561 MM_PTE_VALID_MASK); \ 00562 if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ 00563 (OUTPTE).u.Hard.Global = 1; \ 00564 } 00565 00566 00567 //++ 00568 //VOID 00569 //MI_SET_GLOBAL_BIT_IF_SYSTEM ( 00570 // OUT OUTPTE, 00571 // IN PPTE 00572 // ); 00573 // 00574 // Routine Description: 00575 // 00576 // This macro sets the global bit if the pointer PTE is within 00577 // system space. 00578 // 00579 // Argments 00580 // 00581 // OUTPTE - Supplies the PTE in which to build the valid PTE. 00582 // 00583 // PPTE - Supplies a pointer to the PTE becoming valid. 00584 // 00585 // Return Value: 00586 // 00587 // None. 00588 // 00589 //-- 00590 00591 #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE) \ 00592 if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ 00593 (OUTPTE).u.Hard.Global = 1; \ 00594 } 00595 00596 00597 //++ 00598 //VOID 00599 //MI_SET_PTE_DIRTY ( 00600 // IN MMPTE PTE 00601 // ); 00602 // 00603 // Routine Description: 00604 // 00605 // This macro sets the dirty bit(s) in the specified PTE. 00606 // 00607 // Argments 00608 // 00609 // PTE - Supplies the PTE to set dirty. 00610 // 00611 // Return Value: 00612 // 00613 // None. 00614 // 00615 //-- 00616 00617 #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Long |= HARDWARE_PTE_DIRTY_MASK 00618 00619 00620 //++ 00621 //VOID 00622 //MI_SET_PTE_CLEAN ( 00623 // IN MMPTE PTE 00624 // ); 00625 // 00626 // Routine Description: 00627 // 00628 // This macro clears the dirty bit(s) in the specified PTE. 00629 // 00630 // Argments 00631 // 00632 // PTE - Supplies the PTE to set clear. 00633 // 00634 // Return Value: 00635 // 00636 // None. 00637 // 00638 //-- 00639 00640 #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Long &= ~HARDWARE_PTE_DIRTY_MASK 00641 00642 00643 00644 //++ 00645 //VOID 00646 //MI_IS_PTE_DIRTY ( 00647 // IN MMPTE PTE 00648 // ); 00649 // 00650 // Routine Description: 00651 // 00652 // This macro checks the dirty bit(s) in the specified PTE. 00653 // 00654 // Argments 00655 // 00656 // PTE - Supplies the PTE to check. 00657 // 00658 // Return Value: 00659 // 00660 // TRUE if the page is dirty (modified), FALSE otherwise. 00661 // 00662 //-- 00663 00664 #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) 00665 00666 00667 //++ 00668 //VOID 00669 //MI_SET_GLOBAL_STATE ( 00670 // IN MMPTE PTE, 00671 // IN ULONG STATE 00672 // ); 00673 // 00674 // Routine Description: 00675 // 00676 // This macro sets the global bit in the PTE. if the pointer PTE is within 00677 // 00678 // Argments 00679 // 00680 // PTE - Supplies the PTE to set global state into. 00681 // 00682 // Return Value: 00683 // 00684 // None. 00685 // 00686 //-- 00687 00688 #define MI_SET_GLOBAL_STATE(PTE,STATE) \ 00689 (PTE).u.Hard.Global = STATE; 00690 00691 00692 00693 //++ 00694 //VOID 00695 //MI_ENABLE_CACHING ( 00696 // IN MMPTE PTE 00697 // ); 00698 // 00699 // Routine Description: 00700 // 00701 // This macro takes a valid PTE and sets the caching state to be 00702 // enabled. 00703 // 00704 // Argments 00705 // 00706 // PTE - Supplies a valid PTE. 00707 // 00708 // Return Value: 00709 // 00710 // None. 00711 // 00712 //-- 00713 00714 #define MI_ENABLE_CACHING(PTE) ((PTE).u.Hard.CachePolicy = PCR->CachePolicy) 00715 00716 00717 00718 //++ 00719 //VOID 00720 //MI_DISABLE_CACHING ( 00721 // IN MMPTE PTE 00722 // ); 00723 // 00724 // Routine Description: 00725 // 00726 // This macro takes a valid PTE and sets the caching state to be 00727 // disabled. 00728 // 00729 // Argments 00730 // 00731 // PTE - Supplies a valid PTE. 00732 // 00733 // Return Value: 00734 // 00735 // None. 00736 // 00737 //-- 00738 00739 #define MI_DISABLE_CACHING(PTE) ((PTE).u.Hard.CachePolicy = UNCACHED_POLICY) 00740 00741 //++ 00742 //BOOLEAN 00743 //MI_IS_CACHING_DISABLED ( 00744 // IN PMMPTE PPTE 00745 // ); 00746 // 00747 // Routine Description: 00748 // 00749 // This macro takes a valid PTE and returns TRUE if caching is 00750 // disabled. 00751 // 00752 // Argments 00753 // 00754 // PPTE - Supplies a pointer to the valid PTE. 00755 // 00756 // Return Value: 00757 // 00758 // TRUE if caching is disabled, FALSE if it is enabled. 00759 // 00760 //-- 00761 00762 #define MI_IS_CACHING_DISABLED(PPTE) \ 00763 ((PPTE)->u.Hard.CachePolicy == UNCACHED_POLICY) 00764 00765 //++ 00766 //VOID 00767 //MI_IS_PTE_DIRTY ( 00768 // IN MMPTE PTE 00769 // ); 00770 // 00771 // Routine Description: 00772 // 00773 // This macro checks the dirty bit(s) in the specified PTE. 00774 // 00775 // Argments 00776 // 00777 // PTE - Supplies the PTE to check. 00778 // 00779 // Return Value: 00780 // 00781 // TRUE if the page is dirty (modified), FALSE otherwise. 00782 // 00783 //-- 00784 00785 #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) 00786 00787 00788 //++ 00789 //VOID 00790 //MI_SET_PFN_DELETED ( 00791 // IN PMMPFN PPFN 00792 // ); 00793 // 00794 // Routine Description: 00795 // 00796 // This macro takes a pointer to a PFN element and indicates that 00797 // the PFN is no longer in use. 00798 // 00799 // Argments 00800 // 00801 // PPTE - Supplies a pointer to the PFN element. 00802 // 00803 // Return Value: 00804 // 00805 // none. 00806 // 00807 //-- 00808 00809 #define MI_SET_PFN_DELETED(PPFN) (((ULONG)(PPFN)->PteAddress &= 0x7FFFFFFF )) 00810 00811 00812 //++ 00813 //BOOLEAN 00814 //MI_IS_PFN_DELETED ( 00815 // IN PMMPFN PPFN 00816 // ); 00817 // 00818 // Routine Description: 00819 // 00820 // This macro takes a pointer to a PFN element a determines if 00821 // the PFN is no longer in use. 00822 // 00823 // Argments 00824 // 00825 // PPTE - Supplies a pointer to the PFN element. 00826 // 00827 // Return Value: 00828 // 00829 // TRUE if PFN is no longer used, FALSE if it is still being used. 00830 // 00831 //-- 00832 00833 #define MI_IS_PFN_DELETED(PPFN) \ 00834 (((ULONG)(PPFN)->PteAddress & 0x80000000) == 0) 00835 00836 00837 //++ 00838 //VOID 00839 //MI_CHECK_PAGE_ALIGNMENT ( 00840 // IN ULONG PAGE, 00841 // IN ULONG COLOR 00842 // ); 00843 // 00844 // Routine Description: 00845 // 00846 // This macro takes a PFN element number (Page) and checks to see 00847 // if the virtual alignment for the previous address of the page 00848 // is compatable with the new address of the page. If they are 00849 // not compatable, the D cache is flushed. 00850 // 00851 // Argments 00852 // 00853 // PAGE - Supplies the PFN element. 00854 // PPTE - Supplies a pointer to the new PTE which will contain the page. 00855 // 00856 // Return Value: 00857 // 00858 // none. 00859 // 00860 //-- 00861 00862 #define MI_CHECK_PAGE_ALIGNMENT(PAGE,COLOR) \ 00863 { \ 00864 PMMPFN PPFN; \ 00865 ULONG OldColor; \ 00866 PPFN = MI_PFN_ELEMENT(PAGE); \ 00867 OldColor = PPFN->u3.e1.PageColor; \ 00868 if ((COLOR) != OldColor) { \ 00869 KeChangeColorPage((PVOID)((ULONG)(COLOR) << PAGE_SHIFT), \ 00870 (PVOID)((ULONG)(OldColor << PAGE_SHIFT)), \ 00871 Page); \ 00872 PPFN->u3.e1.PageColor = COLOR; \ 00873 } \ 00874 } 00875 00876 00877 //++ 00878 //VOID 00879 //MI_INITIALIZE_HYPERSPACE_MAP ( 00880 // HYPER_PAGE 00881 // ); 00882 // 00883 // Routine Description: 00884 // 00885 // This macro initializes the PTEs reserved for double mapping within 00886 // hyperspace. 00887 // 00888 // Argments 00889 // 00890 // HYPER_PAGE - Phyical page number for the page to become hyperspace. 00891 // 00892 // Return Value: 00893 // 00894 // None. 00895 // 00896 //-- 00897 00898 #define MI_INITIALIZE_HYPERSPACE_MAP(HYPER_PAGE) \ 00899 { \ 00900 PMMPTE NextPte; \ 00901 ULONG LastEntry; \ 00902 PMMPTE Base; \ 00903 ULONG i; \ 00904 KIRQL OldIrql; \ 00905 Base = MiMapPageInHyperSpace (HYPER_PAGE, &OldIrql); \ 00906 LastEntry = NUMBER_OF_MAPPING_PTES - MM_COLOR_MASK; \ 00907 NextPte = (PMMPTE)((PCHAR)Base + BYTE_OFFSET(MmFirstReservedMappingPte));\ 00908 for (i = 0; i < MM_NUMBER_OF_COLORS; i++ ) { \ 00909 NextPte->u.Hard.PageFrameNumber = LastEntry; \ 00910 NextPte += 1; \ 00911 } \ 00912 MiUnmapPageInHyperSpace (OldIrql); \ 00913 } 00914 00915 00916 00917 //++ 00918 //ULONG 00919 //MI_GET_PAGE_COLOR_FROM_PTE ( 00920 // IN PMMPTE PTEADDRESS 00921 // ); 00922 // 00923 // Routine Description: 00924 // 00925 // This macro determines the pages color based on the PTE address 00926 // that maps the page. 00927 // 00928 // Argments 00929 // 00930 // PTEADDRESS - Supplies the PTE address the page is (or was) mapped at. 00931 // 00932 // Return Value: 00933 // 00934 // The pages color. 00935 // 00936 //-- 00937 00938 #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \ 00939 ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ 00940 MmSecondaryColorMask) | \ 00941 ((((ULONG)(PTEADDRESS)) >> 2) & MM_COLOR_MASK)) 00942 00943 //++ 00944 //ULONG 00945 //MI_GET_PAGE_COLOR_FROM_VA ( 00946 // IN PVOID ADDRESS 00947 // ); 00948 // 00949 // Routine Description: 00950 // 00951 // This macro determines the pages color based on the PTE address 00952 // that maps the page. 00953 // 00954 // Argments 00955 // 00956 // ADDRESS - Supplies the address the page is (or was) mapped at. 00957 // 00958 // Return Value: 00959 // 00960 // The pages color. 00961 // 00962 //-- 00963 00964 #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \ 00965 ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ 00966 MmSecondaryColorMask) | \ 00967 ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) 00968 00969 00970 //++ 00971 //ULONG 00972 //MI_PAGE_COLOR_PTE_PROCESS ( 00973 // IN PCHAR COLOR, 00974 // IN PMMPTE PTE 00975 // ); 00976 // 00977 // Routine Description: 00978 // 00979 // This macro determines the pages color based on the PTE address 00980 // that maps the page. 00981 // 00982 // Argments 00983 // 00984 // 00985 // Return Value: 00986 // 00987 // The pages color. 00988 // 00989 //-- 00990 00991 00992 #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \ 00993 ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ 00994 MmSecondaryColorMask) | \ 00995 ((((ULONG)(PTE)) >> 2) & MM_COLOR_MASK)) 00996 00997 00998 //++ 00999 //ULONG 01000 //MI_PAGE_COLOR_VA_PROCESS ( 01001 // IN PVOID ADDRESS, 01002 // IN PEPROCESS COLOR 01003 // ); 01004 // 01005 // Routine Description: 01006 // 01007 // This macro determines the pages color based on the PTE address 01008 // that maps the page. 01009 // 01010 // Argments 01011 // 01012 // ADDRESS - Supplies the address the page is (or was) mapped at. 01013 // 01014 // Return Value: 01015 // 01016 // The pages color. 01017 // 01018 //-- 01019 01020 #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \ 01021 ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ 01022 MmSecondaryColorMask) | \ 01023 ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) 01024 01025 01026 //++ 01027 //ULONG 01028 //MI_GET_NEXT_COLOR ( 01029 // IN ULONG COLOR 01030 // ); 01031 // 01032 // Routine Description: 01033 // 01034 // This macro returns the next color in the sequence. 01035 // 01036 // Argments 01037 // 01038 // COLOR - Supplies the color to return the next of. 01039 // 01040 // Return Value: 01041 // 01042 // Next color in sequence. 01043 // 01044 //-- 01045 01046 #define MI_GET_NEXT_COLOR(COLOR) ((COLOR + 1) & MM_COLOR_MASK) 01047 01048 01049 //++ 01050 //ULONG 01051 //MI_GET_PREVIOUS_COLOR ( 01052 // IN ULONG COLOR 01053 // ); 01054 // 01055 // Routine Description: 01056 // 01057 // This macro returns the previous color in the sequence. 01058 // 01059 // Argments 01060 // 01061 // COLOR - Supplies the color to return the previous of. 01062 // 01063 // Return Value: 01064 // 01065 // Previous color in sequence. 01066 // 01067 //-- 01068 01069 #define MI_GET_PREVIOUS_COLOR(COLOR) ((COLOR - 1) & MM_COLOR_MASK) 01070 01071 #define MI_GET_COLOR_FROM_SECONDARY(COLOR) ((COLOR) & MM_COLOR_MASK) 01072 01073 // 01074 // The top bits of the prototype PTE tracks the secondary color, 01075 // the primary color may NOT match the lower bits of the prototype PTE 01076 // in the case of fork. 01077 // 01078 01079 #define MI_GET_SECONDARY_COLOR(PAGE,PFN) \ 01080 ((((ULONG)(PAGE) & MmSecondaryColorMask)) | (PFN)->u3.e1.PageColor) 01081 01082 01083 01084 //++ 01085 //VOID 01086 //MI_GET_MODIFIED_PAGE_BY_COLOR ( 01087 // OUT ULONG PAGE, 01088 // IN ULONG COLOR 01089 // ); 01090 // 01091 // Routine Description: 01092 // 01093 // This macro returns the first page destined for a paging 01094 // file with the desired color. It does NOT remove the page 01095 // from its list. 01096 // 01097 // Argments 01098 // 01099 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01100 // returned if there is no page of the specified color. 01101 // 01102 // COLOR - Supplies the color of page to locate. 01103 // 01104 // Return Value: 01105 // 01106 // none. 01107 // 01108 //-- 01109 01110 #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \ 01111 PAGE = MmModifiedPageListByColor[COLOR].Flink 01112 01113 01114 //++ 01115 //VOID 01116 //MI_GET_MODIFIED_PAGE_ANY_COLOR ( 01117 // OUT ULONG PAGE, 01118 // IN OUT ULONG COLOR 01119 // ); 01120 // 01121 // Routine Description: 01122 // 01123 // This macro returns the first page destined for a paging 01124 // file with the desired color. If not page of the desired 01125 // color exists, all colored lists are searched for a page. 01126 // It does NOT remove the page from its list. 01127 // 01128 // Argments 01129 // 01130 // PAGE - Returns the page located, the value MM_EMPTY_LIST is 01131 // returned if there is no page of the specified color. 01132 // 01133 // COLOR - Supplies the color of page to locate and returns the 01134 // color of the page located. 01135 // 01136 // Return Value: 01137 // 01138 // none. 01139 // 01140 //-- 01141 01142 #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \ 01143 { \ 01144 if (MmTotalPagesForPagingFile == 0) { \ 01145 PAGE = MM_EMPTY_LIST; \ 01146 } else { \ 01147 while (MmModifiedPageListByColor[COLOR].Flink == \ 01148 MM_EMPTY_LIST) { \ 01149 COLOR = MI_GET_NEXT_COLOR(COLOR); \ 01150 } \ 01151 PAGE = MmModifiedPageListByColor[COLOR].Flink; \ 01152 } \ 01153 } 01154 01155 01156 //++ 01157 //VOID 01158 //MI_MAKE_VALID_PTE_WRITE_COPY ( 01159 // IN OUT PMMPTE PTE 01160 // ); 01161 // 01162 // Routine Description: 01163 // 01164 // This macro checks to see if the PTE indicates that the 01165 // page is writable and if so it clears the write bit and 01166 // sets the copy-on-write bit. 01167 // 01168 // Argments 01169 // 01170 // PTE - Supplies the PTE to operate upon. 01171 // 01172 // Return Value: 01173 // 01174 // None. 01175 // 01176 //-- 01177 01178 #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ 01179 if ((PPTE)->u.Hard.Write == 1) { \ 01180 (PPTE)->u.Hard.CopyOnWrite = 1; \ 01181 (PPTE)->u.Hard.Dirty = MM_PTE_CLEAN; \ 01182 } 01183 01184 01185 //++ 01186 //ULONG 01187 //MI_DETERMINE_OWNER ( 01188 // IN MMPTE PPTE 01189 // ); 01190 // 01191 // Routine Description: 01192 // 01193 // This macro examines the virtual address of the PTE and determines 01194 // if the PTE resides in system space or user space. 01195 // 01196 // Argments 01197 // 01198 // PTE - Supplies the PTE to operate upon. 01199 // 01200 // Return Value: 01201 // 01202 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01203 // 01204 //-- 01205 01206 #define MI_DETERMINE_OWNER(PPTE) \ 01207 ((((PPTE) <= MiGetPteAddress(MM_HIGHEST_USER_ADDRESS)) || \ 01208 ((PPTE) >= MiGetPdeAddress(NULL) && \ 01209 ((PPTE) <= MiGetPdeAddress(MM_HIGHEST_USER_ADDRESS)))) ? 1 : 0) 01210 01211 01212 //++ 01213 //VOID 01214 //MI_SET_ACCESSED_IN_PTE ( 01215 // IN OUT MMPTE PPTE 01216 // ); 01217 // 01218 // Routine Description: 01219 // 01220 // This macro sets the ACCESSED field in the PTE. 01221 // 01222 // Argments 01223 // 01224 // PTE - Supplies the PTE to operate upon. 01225 // 01226 // Return Value: 01227 // 01228 // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. 01229 // 01230 //-- 01231 01232 // not implemented on mips r4000. 01233 #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) 01234 01235 01236 //++ 01237 //ULONG 01238 //MI_GET_ACCESSED_IN_PTE ( 01239 // IN OUT MMPTE PPTE 01240 // ); 01241 // 01242 // Routine Description: 01243 // 01244 // This macro returns the state of the ACCESSED field in the PTE. 01245 // 01246 // Argments 01247 // 01248 // PTE - Supplies the PTE to operate upon. 01249 // 01250 // Return Value: 01251 // 01252 // The state of the ACCESSED field. 01253 // 01254 //-- 01255 01256 #define MI_GET_ACCESSED_IN_PTE(PPTE) 0 01257 01258 01259 01260 //++ 01261 //VOID 01262 //MI_SET_OWNER_IN_PTE ( 01263 // IN PMMPTE PPTE 01264 // IN ULONG OWNER 01265 // ); 01266 // 01267 // Routine Description: 01268 // 01269 // This macro sets the owner field in the PTE. 01270 // 01271 // Argments 01272 // 01273 // PTE - Supplies the PTE to operate upon. 01274 // 01275 // Return Value: 01276 // 01277 // None. 01278 // 01279 //-- 01280 01281 // not implemented on r4000. 01282 #define MI_SET_OWNER_IN_PTE(PPTE,OWNER) 01283 01284 01285 01286 //++ 01287 //ULONG 01288 //MI_GET_OWNER_IN_PTE ( 01289 // IN PMMPTE PPTE 01290 // ); 01291 // 01292 // Routine Description: 01293 // 01294 // This macro gets the owner field from the PTE. 01295 // 01296 // Argments 01297 // 01298 // PTE - Supplies the PTE to operate upon. 01299 // 01300 // Return Value: 01301 // 01302 // The state of the OWNER field. 01303 // 01304 //-- 01305 01306 // always kernel mode on r4000. 01307 #define MI_GET_OWNER_IN_PTE(PPTE) KernelMode 01308 01309 // 01310 // bit mask to clear out fields in a PTE to or in prototype pte offset. 01311 // 01312 01313 #define CLEAR_FOR_PROTO_PTE_ADDRESS ((ULONG)0xf) 01314 01315 01316 // bit mask to clear out fields in a PTE to or in paging file location. 01317 01318 #define CLEAR_FOR_PAGE_FILE ((ULONG)(0x0F9)) 01319 01320 //++ 01321 //VOID 01322 //MI_SET_PAGING_FILE_INFO ( 01323 // IN OUT MMPTE PPTE, 01324 // IN ULONG FILEINFO, 01325 // IN ULONG OFFSET 01326 // ); 01327 // 01328 // Routine Description: 01329 // 01330 // This macro sets into the specified PTE the supplied information 01331 // to indicate where the backing store for the page is located. 01332 // 01333 // Argments 01334 // 01335 // PTE - Supplies the PTE to operate upon. 01336 // 01337 // FILEINFO - Supplies the number of the paging file. 01338 // 01339 // OFFSET - Supplies the offset into the paging file. 01340 // 01341 // Return Value: 01342 // 01343 // None. 01344 // 01345 //-- 01346 01347 #define SET_PAGING_FILE_INFO(PTE,FILEINFO,OFFSET) \ 01348 ((((PTE).u.Long & CLEAR_FOR_PAGE_FILE) | \ 01349 (((FILEINFO) << 9) | \ 01350 (OFFSET << 12)))) 01351 01352 //++ 01353 //PMMPTE 01354 //MiPteToProto ( 01355 // IN OUT MMPTE PPTE, 01356 // IN ULONG FILEINFO, 01357 // IN ULONG OFFSET 01358 // ); 01359 // 01360 // Routine Description: 01361 // 01362 // This macro returns the address of the corresponding prototype which 01363 // was encoded earlier into the supplied PTE. 01364 // 01365 // NOTE THAT AS PROTOPTE CAN ONLY RESIDE IN PAGED POOL!!!!!! 01366 // 01367 // MAX SIZE = 2^(2+7+21) = 2^30 = 1GB. 01368 // 01369 // NOTE, that the valid bit must be zero! 01370 // 01371 // Argments 01372 // 01373 // lpte - Supplies the PTE to operate upon. 01374 // 01375 // Return Value: 01376 // 01377 // Pointer to the prototype PTE that backs this PTE. 01378 // 01379 //-- 01380 // 01381 // MiPteToProtoPte returns the address of the corresponding prototype 01382 // PTE 01383 // 01384 // 01385 // 01386 01387 #define MiPteToProto(lpte) \ 01388 ((PMMPTE)((((lpte)->u.Long >> 1) & 0x3FFFFFFC) + \ 01389 MmProtopte_Base)) 01390 01391 01392 //++ 01393 //ULONG 01394 //MiProtoAddressForPte ( 01395 // IN PMMPTE proto_va 01396 // ); 01397 // 01398 // Routine Description: 01399 // 01400 // This macro sets into the specified PTE the supplied information 01401 // to indicate where the backing store for the page is located. 01402 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01403 // reference a prototype PTE. And set the protoPTE bit, 01404 // MM_PTE_PROTOTYPE_MASK. 01405 // 01406 // Argments 01407 // 01408 // proto_va - Supplies the address of the prototype PTE. 01409 // 01410 // Return Value: 01411 // 01412 // Mask to set into the PTE. 01413 // 01414 //-- 01415 01416 #define MiProtoAddressForPte(proto_va) \ 01417 ((ULONG)((((ULONG)proto_va - MmProtopte_Base) << 1) | MM_PTE_PROTOTYPE_MASK)) 01418 01419 01420 01421 //++ 01422 //ULONG 01423 //MiProtoAddressForKernelPte ( 01424 // IN PMMPTE proto_va 01425 // ); 01426 // 01427 // Routine Description: 01428 // 01429 // This macro sets into the specified PTE the supplied information 01430 // to indicate where the backing store for the page is located. 01431 // MiProtoAddressForPte returns the bit field to OR into the PTE to 01432 // reference a prototype PTE. And set the protoPTE bit, 01433 // MM_PTE_PROTOTYPE_MASK. 01434 // 01435 // This macro also sets any other information (such as global bits) 01436 // required for kernel mode PTEs. 01437 // 01438 // Argments 01439 // 01440 // proto_va - Supplies the address of the prototype PTE. 01441 // 01442 // Return Value: 01443 // 01444 // Mask to set into the PTE. 01445 // 01446 //-- 01447 01448 #define MiProtoAddressForKernelPte(proto_va) \ 01449 (((ULONG)(proto_va) < (ULONG)KSEG1_BASE) ? \ 01450 ((ULONG)((((ULONG)proto_va - (ULONG)MmNonPagedPoolStart) << 1) | MM_PTE_PROTOTYPE_MASK | \ 01451 0x40000000 | MM_PTE_GLOBAL_MASK)) \ 01452 : ((ULONG)((((ULONG)proto_va - MmProtopte_Base) << 1) | MM_PTE_PROTOTYPE_MASK | \ 01453 MM_PTE_GLOBAL_MASK))) 01454 01455 01456 01457 #define MM_SUBSECTION_MAP (128*1024*1024) 01458 01459 01460 //++ 01461 //PSUBSECTION 01462 //MiGetSubsectionAddress ( 01463 // IN PMMPTE lpte 01464 // ); 01465 // 01466 // Routine Description: 01467 // 01468 // This macro takes a PTE and returns the address of the subsection that 01469 // the PTE refers to. Subsections are quadword structures allocated 01470 // from nonpaged pool. 01471 // 01472 // NOTE THIS MACRO LIMITS THE SIZE OF NONPAGED POOL! 01473 // MAXIMUM NONPAGED POOL = 2^(24+3) = 2^27 = 128mb in KSEG_0 POOL AND 01474 // 128 MB IN EXPANDED POOL. 01475 // 01476 // Argments 01477 // 01478 // lpte - Supplies the PTE to operate upon. 01479 // 01480 // Return Value: 01481 // 01482 // A pointer to the subsection referred to by the supplied PTE. 01483 // 01484 //-- 01485 01486 #define MiGetSubsectionAddress(lpte) \ 01487 (((lpte)->u.Long & 0x1) ? \ 01488 ((PSUBSECTION)(((((lpte)->u.Long >> 8) << 3) + (ULONG)MmSubsectionBase))) \ 01489 : ((PSUBSECTION)((ULONG)MM_NONPAGED_POOL_END - ((((lpte)->u.Long) >> 8) << 3)))) 01490 01491 01492 01493 //++ 01494 //ULONG 01495 //MiGetSubsectionAddressForPte ( 01496 // IN PSUBSECTION VA 01497 // ); 01498 // 01499 // Routine Description: 01500 // 01501 // This macro takes the address of a subsection and encodes it for use 01502 // in a PTE. 01503 // 01504 // NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED! 01505 // 01506 // Argments 01507 // 01508 // VA - Supplies a pointer to the subsection to encode. 01509 // 01510 // Return Value: 01511 // 01512 // The mask to set into the PTE to make it reference the supplied 01513 // subsetion. 01514 // 01515 //-- 01516 01517 #define MiGetSubsectionAddressForPte(VA) \ 01518 (((ULONG)(VA) < (ULONG)KSEG1_BASE) ? \ 01519 ((((ULONG)(VA) - (ULONG)MmSubsectionBase) << 5) | 0x1) \ 01520 : (((ULONG)MM_NONPAGED_POOL_END - (ULONG)VA) << 5)) 01521 01522 01523 01524 //++ 01525 //PMMPTE 01526 //MiGetPdeAddress ( 01527 // IN PVOID va 01528 // ); 01529 // 01530 // Routine Description: 01531 // 01532 // MiGetPdeAddress returns the address of the PDE which maps the 01533 // given virtual address. 01534 // 01535 // Argments 01536 // 01537 // Va - Supplies the virtual address to locate the PDE for. 01538 // 01539 // Return Value: 01540 // 01541 // The address of the PDE. 01542 // 01543 //-- 01544 01545 #define MiGetPdeAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE)) 01546 01547 #define MiGetPdeAddress64(va) ((PMMPTE)((ULONG)((((ULONGLONG)(va)) >> 22) << 2) + PDE_BASE64)) 01548 01549 01550 01551 //++ 01552 //PMMPTE 01553 //MiGetPteAddress ( 01554 // IN PVOID va 01555 // ); 01556 // 01557 // Routine Description: 01558 // 01559 // MiGetPteAddress returns the address of the PTE which maps the 01560 // given virtual address. 01561 // 01562 // Argments 01563 // 01564 // Va - Supplies the virtual address to locate the PTE for. 01565 // 01566 // Return Value: 01567 // 01568 // The address of the PTE. 01569 // 01570 //-- 01571 01572 #define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE)) 01573 01574 #define MiGetPteAddress64(va) ((PMMPTE)((ULONG)((((ULONGLONG)(va)) >> 12) << 2) + PTE_BASE64)) 01575 01576 01577 //++ 01578 //ULONG 01579 //MiGetPdeOffset ( 01580 // IN PVOID va 01581 // ); 01582 // 01583 // Routine Description: 01584 // 01585 // MiGetPdeOffset returns the offset into a page directory 01586 // for a given virtual address. 01587 // 01588 // Argments 01589 // 01590 // Va - Supplies the virtual address to locate the offset for. 01591 // 01592 // Return Value: 01593 // 01594 // The offset into the page directory table the corresponding PDE is at. 01595 // 01596 //-- 01597 01598 #define MiGetPdeOffset(va) (((ULONG)(va)) >> 22) 01599 01600 01601 //++ 01602 //ULONG 01603 //MiGetPteOffset ( 01604 // IN PVOID va 01605 // ); 01606 // 01607 // Routine Description: 01608 // 01609 // MiGetPteOffset returns the offset into a page table page 01610 // for a given virtual address. 01611 // 01612 // Argments 01613 // 01614 // Va - Supplies the virtual address to locate the offset for. 01615 // 01616 // Return Value: 01617 // 01618 // The offset into the page table page table the corresponding PTE is at. 01619 // 01620 //-- 01621 01622 #define MiGetPteOffset(va) ((((ULONG)(va)) << 10) >> 22) 01623 01624 01625 //++ 01626 //PVOID 01627 //MiGetVirtualAddressMappedByPte ( 01628 // IN PMMPTE PTE 01629 // ); 01630 // 01631 // Routine Description: 01632 // 01633 // MiGetVirtualAddressMappedByPte returns the virtual address 01634 // which is mapped by a given PTE address. 01635 // 01636 // Argments 01637 // 01638 // PTE - Supplies the PTE to get the virtual address for. 01639 // 01640 // Return Value: 01641 // 01642 // Virtual address mapped by the PTE. 01643 // 01644 //-- 01645 01646 #define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG)(PTE) << 10)) 01647 01648 #define MiGetVirtualAddressMappedByPte64(PTE) \ 01649 ((PVOID64)(((ULONGLONG)((ULONG)(PTE) - PTE_BASE64)) << 10)) 01650 01651 #define MiGetVirtualPageNumberMappedByPte64(PTE) \ 01652 (((ULONG)(PTE) - PTE_BASE64) >> 2) 01653 01654 01655 //++ 01656 //ULONG 01657 //GET_PAGING_FILE_NUMBER ( 01658 // IN MMPTE PTE 01659 // ); 01660 // 01661 // Routine Description: 01662 // 01663 // This macro extracts the paging file number from a PTE. 01664 // 01665 // Argments 01666 // 01667 // PTE - Supplies the PTE to operate upon. 01668 // 01669 // Return Value: 01670 // 01671 // The paging file number. 01672 // 01673 //-- 01674 01675 #define GET_PAGING_FILE_NUMBER(PTE) ((((PTE).u.Long) >> 9) & 0x7) 01676 01677 01678 //++ 01679 //ULONG 01680 //GET_PAGING_FILE_OFFSET ( 01681 // IN MMPTE PTE 01682 // ); 01683 // 01684 // Routine Description: 01685 // 01686 // This macro extracts the offset into the paging file from a PTE. 01687 // 01688 // Argments 01689 // 01690 // PTE - Supplies the PTE to operate upon. 01691 // 01692 // Return Value: 01693 // 01694 // The paging file offset. 01695 // 01696 //-- 01697 01698 #define GET_PAGING_FILE_OFFSET(PTE) ((((PTE).u.Long) >> 12) & 0x000FFFFF) 01699 01700 //++ 01701 //ULONG 01702 //IS_PTE_NOT_DEMAND_ZERO ( 01703 // IN PMMPTE PPTE 01704 // ); 01705 // 01706 // Routine Description: 01707 // 01708 // This macro checks to see if a given PTE is NOT a demand zero PTE. 01709 // 01710 // Argments 01711 // 01712 // PTE - Supplies the PTE to operate upon. 01713 // 01714 // Return Value: 01715 // 01716 // Returns 0 if the PTE is demand zero, non-zero otherwise. 01717 // 01718 //-- 01719 01720 #define IS_PTE_NOT_DEMAND_ZERO(PTE) ((PTE).u.Long & (ULONG)0xFFFFF107) 01721 #define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) 01722 01723 #define MM_KERNEL_DEMAND_ZERO_PTE ((MM_READWRITE << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) 01724 01725 #define MM_KERNEL_NOACCESS_PTE ((MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) 01726 01727 01728 01729 //++ 01730 //VOID 01731 //MI_MAKING_VALID_PTE_INVALID( 01732 // IN PMMPTE PPTE 01733 // ); 01734 // 01735 // Routine Description: 01736 // 01737 // Prepare to make a single valid PTE invalid. 01738 // No action is required on x86. 01739 // 01740 // Argments 01741 // 01742 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 01743 // 01744 // Return Value: 01745 // 01746 // None. 01747 // 01748 //-- 01749 01750 // not implemented on r4000. 01751 #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE) 01752 01753 01754 01755 //++ 01756 //VOID 01757 //MI_MAKING_VALID_MULTIPLE_PTES_INVALID( 01758 // IN PMMPTE PPTE 01759 // ); 01760 // 01761 // Routine Description: 01762 // 01763 // Prepare to make multiple valid PTEs invalid. 01764 // No action is required on x86. 01765 // 01766 // Argments 01767 // 01768 // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. 01769 // 01770 // Return Value: 01771 // 01772 // None. 01773 // 01774 //-- 01775 01776 // not implemented on r4000. 01777 #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE) 01778 01779 // 01780 // Make a writable PTE, writeable-copy PTE. This takes advantage of 01781 // the fact that the protection field in the PTE (5 bit protection) is 01782 // set up such that write is a bit. 01783 // 01784 01785 #define MI_MAKE_PROTECT_WRITE_COPY(PTE) \ 01786 if ((PTE).u.Long & 0x20) { \ 01787 ((PTE).u.Long |= 0x8); \ 01788 } 01789 01790 01791 //++ 01792 //VOID 01793 //MI_SET_PAGE_DIRTY( 01794 // IN PMMPTE PPTE, 01795 // IN PVOID VA, 01796 // IN PVOID PFNHELD 01797 // ); 01798 // 01799 // Routine Description: 01800 // 01801 // This macro sets the dirty bit (and release page file space). 01802 // 01803 // Argments 01804 // 01805 // TEMP - Supplies a temporary for usage. 01806 // 01807 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 01808 // 01809 // VA - Supplies a the virtual address of the page fault. 01810 // 01811 // PFNHELD - Supplies TRUE if the PFN lock is held. 01812 // 01813 // Return Value: 01814 // 01815 // None. 01816 // 01817 //-- 01818 01819 #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \ 01820 if ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN) { \ 01821 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 01822 } 01823 01824 01825 01826 //++ 01827 //VOID 01828 //MI_NO_FAULT_FOUND( 01829 // IN TEMP, 01830 // IN PMMPTE PPTE, 01831 // IN PVOID VA, 01832 // IN PVOID PFNHELD 01833 // ); 01834 // 01835 // Routine Description: 01836 // 01837 // This macro handles the case when a page fault is taken and no 01838 // PTE with the valid bit clear is found. 01839 // 01840 // Argments 01841 // 01842 // TEMP - Supplies a temporary for usage. 01843 // 01844 // PPTE - Supplies a pointer to the PTE that corresponds to VA. 01845 // 01846 // VA - Supplies a the virtual address of the page fault. 01847 // 01848 // PFNHELD - Supplies TRUE if the PFN lock is held. 01849 // 01850 // Return Value: 01851 // 01852 // None. 01853 // 01854 //-- 01855 01856 #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \ 01857 if (StoreInstruction && ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN)) { \ 01858 MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ 01859 } else { \ 01860 KeFillEntryTb ((PHARDWARE_PTE)PPTE, VA, FALSE); \ 01861 } 01862 // KeFillEntryTb((PHARDWARE_PTE)(MiGetPdeAddress(VA)),(PVOID)PPTE,FALSE); 01863 // 01864 // If the PTE was already valid, assume that the PTE 01865 // in the TB is stall and just reload the PTE. 01866 // 01867 01868 01869 //++ 01870 //ULONG 01871 //MI_CAPTURE_DIRTY_BIT_TO_PFN ( 01872 // IN PMMPTE PPTE, 01873 // IN PMMPFN PPFN 01874 // ); 01875 // 01876 // Routine Description: 01877 // 01878 // This macro gets captures the state of the dirty bit to the PFN 01879 // and frees any associated page file space if the PTE has been 01880 // modified element. 01881 // 01882 // NOTE - THE PFN LOCK MUST BE HELD! 01883 // 01884 // Argments 01885 // 01886 // PPTE - Supplies the PTE to operate upon. 01887 // 01888 // PPFN - Supplies a pointer to the PFN database element that corresponds 01889 // to the page mapped by the PTE. 01890 // 01891 // Return Value: 01892 // 01893 // None. 01894 // 01895 //-- 01896 01897 #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \ 01898 if (((PPFN)->u3.e1.Modified == 0) && \ 01899 ((PPTE)->u.Hard.Dirty == MM_PTE_DIRTY)) { \ 01900 (PPFN)->u3.e1.Modified = 1; \ 01901 if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \ 01902 ((PPFN)->u3.e1.WriteInProgress == 0)) { \ 01903 MiReleasePageFileSpace ((PPFN)->OriginalPte); \ 01904 (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \ 01905 } \ 01906 } 01907 01908 01909 01910 //++ 01911 //BOOLEAN 01912 //MI_IS_PHYSICAL_ADDRESS ( 01913 // IN PVOID VA 01914 // ); 01915 // 01916 // Routine Description: 01917 // 01918 // This macro deterines if a give virtual address is really a 01919 // physical address. 01920 // 01921 // Argments 01922 // 01923 // VA - Supplies the virtual address. 01924 // 01925 // Return Value: 01926 // 01927 // FALSE if it is not a physical address, TRUE if it is. 01928 // 01929 //-- 01930 01931 #define MI_IS_PHYSICAL_ADDRESS(Va) \ 01932 (((ULONG)Va >= KSEG0_BASE) && ((ULONG)Va < KSEG2_BASE)) 01933 01934 01935 01936 01937 //++ 01938 //ULONG 01939 //MI_CONVERT_PHYSICAL_TO_PFN ( 01940 // IN PVOID VA 01941 // ); 01942 // 01943 // Routine Description: 01944 // 01945 // This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS) 01946 // to its corresponding physical frame number. 01947 // 01948 // Argments 01949 // 01950 // VA - Supplies a pointer to the physical address. 01951 // 01952 // Return Value: 01953 // 01954 // Returns the PFN for the page. 01955 // 01956 //-- 01957 01958 #define MI_CONVERT_PHYSICAL_TO_PFN(Va) (((ULONG)Va << 3) >> 15) 01959 01960 01961 01962 01963 typedef struct _MMCOLOR_TABLES { 01964 ULONG Flink; 01965 PVOID Blink; 01966 } MMCOLOR_TABLES, *PMMCOLOR_TABLES; 01967 01968 typedef struct _MMPRIMARY_COLOR_TABLES { 01969 LIST_ENTRY ListHead; 01970 } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES; 01971 01972 01973 #if MM_MAXIMUM_NUMBER_OF_COLORS > 1 01974 extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS]; 01975 #endif 01976 01977 extern PMMCOLOR_TABLES MmFreePagesByColor[2]; 01978 01979 extern ULONG MmTotalPagesForPagingFile; 01980 01981 // 01982 // The hardware PTE is defined in ../inc/mips.h 01983 // 01984 01985 // 01986 // Invalid PTEs have the following defintion. 01987 // 01988 01989 typedef struct _MMPTE_SOFTWARE { 01990 ULONG Global : 1; 01991 ULONG Valid : 1; 01992 ULONG Prototype : 1; 01993 ULONG Protection : 5; 01994 ULONG Transition : 1; 01995 ULONG PageFileLow : 3; 01996 ULONG PageFileHigh : 20; 01997 } MMPTE_SOFTWARE; 01998 01999 02000 typedef struct _MMPTE_TRANSITION { 02001 ULONG Global : 1; 02002 ULONG Valid : 1; 02003 ULONG Prototype : 1; 02004 ULONG Protection : 5; 02005 ULONG Transition : 1; 02006 ULONG PageFrameNumber : 23; 02007 } MMPTE_TRANSITION; 02008 02009 02010 typedef struct _MMPTE_PROTOTYPE { 02011 ULONG Global : 1; 02012 ULONG Valid : 1; 02013 ULONG Prototype : 1; 02014 ULONG ProtoAddressLow : 6; 02015 ULONG ProtoAddressHigh : 22; 02016 ULONG ReadOnly : 1; 02017 } MMPTE_PROTOTYPE; 02018 02019 typedef struct _MMPTE_SUBSECTION { 02020 ULONG WhichPool : 1; 02021 ULONG Valid : 1; 02022 ULONG Prototype : 1; 02023 ULONG Protection : 5; 02024 ULONG SubsectionAddressLow : 4; 02025 ULONG SubsectionAddressHigh : 20; 02026 } MMPTE_SUBSECTION; 02027 02028 typedef struct _MMPTE_LIST { 02029 ULONG filler01 : 1; 02030 ULONG Valid : 1; 02031 ULONG filler0 : 9; 02032 ULONG OneEntry : 1; 02033 ULONG NextEntry : 20; 02034 } MMPTE_LIST; 02035 02036 02037 // typedef struct _HARDWARE_PTE { 02038 // ULONG Global : 1; 02039 // ULONG Valid : 1; 02040 // ULONG Dirty : 1; 02041 // ULONG CachePolicy : 3; 02042 // ULONG PageFrameNumber : 24; 02043 // ULONG Write : 1; 02044 // ULONG CopyOnWrite : 1; 02045 // } HARDWARE_PTE, *PHARDWARE_PTE; 02046 02047 02048 // 02049 // A Page Table Entry on a MIPS R4000 has the following definition. 02050 // 02051 02052 typedef struct _MMPTE { 02053 union { 02054 ULONG Long; 02055 HARDWARE_PTE Hard; 02056 HARDWARE_PTE Flush; 02057 MMPTE_PROTOTYPE Proto; 02058 MMPTE_SOFTWARE Soft; 02059 MMPTE_TRANSITION Trans; 02060 MMPTE_SUBSECTION Subsect; 02061 MMPTE_LIST List; 02062 } u; 02063 } MMPTE; 02064 02065 typedef MMPTE *PMMPTE;

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