diff options
Diffstat (limited to 'private/ntos/mm/mips/mir4000.h')
-rw-r--r-- | private/ntos/mm/mips/mir4000.h | 2075 |
1 files changed, 2075 insertions, 0 deletions
diff --git a/private/ntos/mm/mips/mir4000.h b/private/ntos/mm/mips/mir4000.h new file mode 100644 index 000000000..6a4682b55 --- /dev/null +++ b/private/ntos/mm/mips/mir4000.h @@ -0,0 +1,2075 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + mir4000.h + +Abstract: + + This module contains the private data structures and procedure + prototypes for the hardware dependent portion of the + memory management system. + + It is specifically tailored for the MIPS R4000 machine. + +Author: + + Lou Perazzoli (loup) 9-Jan-1991 + +Revision History: + +--*/ + +#define HEADER_FILE +#include <kxmips.h> + +// +// The R4000 requires colored page support. +// + +// +// The R4000 supports large pages. +// + +#define LARGE_PAGES 1 + + +/*++ + + Virtual Memory Layout on the R4000 is: + + +------------------------------------+ + 00000000 | | + | | + | | + | User Mode Addresses | + | | + | All pages within this range | + | are potentially accessable while | + | the CPU is in USER mode. | + | | + | | + +------------------------------------+ + 7ffff000 | 64k No Access Area | + +------------------------------------+ + 80000000 | | KSEG_0 + | HAL loads kernel and initial | + | boot drivers in first 16mb | + | of this region. | + | Kernel mode access only. | + | | + | Initial NonPaged Pool is within | + | KEG_0 | + | | + +------------------------------------+ + A0000000 | | KSEG_1 + | | + | | + | | + +------------------------------------+ + C0000000 | Page Table Pages mapped through | + | this 4mb region | + | Kernel mode access only. | + | | + +------------------------------------+ + C0400000 | HyperSpace - working set lists | + | and per process memory mangement | + | structures mapped in this 4mb | + | region. | + | Kernel mode access only. | + +------------------------------------+ + C0800000 | NO ACCESS AREA (4MB) | + | | + +------------------------------------+ + C0C00000 | System Cache Structures | + | reside in this 4mb region | + | Kernel mode access only. | + +------------------------------------+ + C1000000 | System cache resides here. | + | Kernel mode access only. | + | | + | | + +------------------------------------+ + DE000000 | System mapped views | + | | + | | + +------------------------------------+ + E1000000 | Start of paged system area | + | Kernel mode access only. | + | | + | | + +------------------------------------+ + | | + | Kernel mode access only. | + | | + | | + FFBFFFFF | NonPaged System area | + +------------------------------------+ + FFC00000 | Last 4mb reserved for HAL usage | + +------------------------------------+ + +--*/ + +// +// PAGE_SIZE for MIPS r4000 is 4k, virtual page is 20 bits with a PAGE_SHIFT +// byte offset. +// + +#define MM_VIRTUAL_PAGE_SHIFT 20 + +// +// Address space layout definitions. +// + +//#define PDE_BASE ((ULONG)0xC0300000) + +//#define PTE_BASE ((ULONG)0xC0000000) + +#define MM_SYSTEM_RANGE_START (0x80000000) + +#define MM_SYSTEM_SPACE_START (0xC0800000) + +#define MM_SYSTEM_SPACE_END (0xFFFFFFFF) + +#define MM_NONPAGED_SYSTEM_SPACE_START (0xF0000000) + +#define PDE_TOP 0xC03FFFFF + +#define MM_PAGES_IN_KSEG0 (((ULONG)KSEG1_BASE - (ULONG)KSEG0_BASE) >> PAGE_SHIFT) + +#define HYPER_SPACE ((PVOID)0xC0400000) + +#define HYPER_SPACE_END 0xC07fffff + +// +// Define the start and maximum size for the system cache. +// Maximum size 464MB. +// + +#define MM_SYSTEM_CACHE_START (0xC1000000) + +#define MM_SYSTEM_CACHE_WORKING_SET (0xC0C00000) + +#define MM_SYSTEM_CACHE_START (0xC1000000) + +#define MM_SYSTEM_CACHE_END (0xDE000000) + +#define MM_MAXIMUM_SYSTEM_CACHE_SIZE \ + (((ULONG)MM_SYSTEM_CACHE_END - (ULONG)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT) + +// +// Define area for mapping views into system space. +// + +#define MM_SYSTEM_VIEW_START (0xDE000000) + +#define MM_SYSTEM_VIEW_SIZE (48*1024*1024) + +#define MM_PAGED_POOL_START ((PVOID)(0xE1000000)) + +#define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(0xEB000000)) + +#define MmProtopte_Base ((ULONG)0xE1000000) + +#define MM_NONPAGED_POOL_END ((PVOID)(0xFFBE0000)) + +#define NON_PAGED_SYSTEM_END ((ULONG)0xFFFFFFF0) //quadword aligned. + +// +// Define absolute minumum and maximum count for system ptes. +// + +#define MM_MINIMUM_SYSTEM_PTES 9000 + +#define MM_MAXIMUM_SYSTEM_PTES 50000 + +#define MM_DEFAULT_SYSTEM_PTES 15000 + +// +// Pool limits +// + +// +// The maximim amount of nonpaged pool that can be initially created. +// + +#define MM_MAX_INITIAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) + +// +// The total amount of nonpaged pool (initial pool + expansion). +// + +#define MM_MAX_ADDITIONAL_NONPAGED_POOL ((ULONG)(128*1024*1024)) + +// +// The maximum amount of paged pool that can be created. +// + +#define MM_MAX_PAGED_POOL ((ULONG)(192*1024*1024)) + +#define MM_MAX_TOTAL_POOL (((ULONG)MM_NONPAGED_POOL_END) - ((ULONG)(MM_PAGED_POOL_START))) + + +// +// Structure layout defintions. +// + +#define PAGE_DIRECTORY_MASK ((ULONG)0x003FFFFF) + +#define MM_VA_MAPPED_BY_PDE (0x400000) + +#define LOWEST_IO_ADDRESS (0x40000000) + +#define PTE_SHIFT (2) + +// +// The number of bits in a physical address. +// + +#define PHYSICAL_ADDRESS_BITS (36) + +#define MM_MAXIMUM_NUMBER_OF_COLORS (8) + +#define MM_PROTO_PTE_ALIGNMENT ((ULONG)MM_MAXIMUM_NUMBER_OF_COLORS * (ULONG)PAGE_SIZE) + +// +// Maximum number of paging files. +// + +#define MAX_PAGE_FILES 8 + +// +// Hyper space definitions. +// + +#define HYPER_SPACE ((PVOID)0xC0400000) +#define FIRST_MAPPING_PTE ((ULONG)0xC0400000) + +// +// On R4000 number of mapping PTEs must be a mulitple of 16 for alignment. +// + +#define NUMBER_OF_MAPPING_PTES 255 +#define LAST_MAPPING_PTE \ + ((ULONG)((ULONG)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE))) + +// +// On R4000 this must be on a 64k virtual address boundary. +// + +#define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG)LAST_MAPPING_PTE + PAGE_SIZE)) + +#define ZEROING_PAGE_PTE ((PMMPTE)((ULONG)IMAGE_MAPPING_PTE + PAGE_SIZE)) + +#define WORKING_SET_LIST ((PVOID)((ULONG)ZEROING_PAGE_PTE + PAGE_SIZE)) + +#define MM_MAXIMUM_WORKING_SET \ + ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb + +#define MM_WORKING_SET_END ((ULONG)0xC07FF000) + +#define MM_PTE_GLOBAL_MASK 0x1 +#define MM_PTE_PROTOTYPE_MASK 0x4 +#define MM_PTE_VALID_MASK 0x2 +#define MM_PTE_DIRTY_MASK 0x4 +#define MM_PTE_CACHE_DISABLE_MASK 0x10 +#define MM_PTE_TRANSITION_MASK 0x100 +#define MM_PTE_WRITE_MASK 0x40000000 +#define MM_PTE_COPY_ON_WRITE_MASK 0x80000000 +#define MM_PTE_CACHE_ENABLE_MASK 0x0 // (PCR->AlignedCachePolicy) + +// +// Bit fields to or into PTE to make a PTE valid based on the +// protection field of the invalid PTE. +// + +#define MM_PTE_NOACCESS 0x0 // not expressable on R4000 +#define MM_PTE_READONLY 0x0 +#define MM_PTE_READWRITE MM_PTE_WRITE_MASK +#define MM_PTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) +#define MM_PTE_EXECUTE 0x0 // read-only on R4000 +#define MM_PTE_EXECUTE_READ 0x0 +#define MM_PTE_EXECUTE_READWRITE MM_PTE_WRITE_MASK +#define MM_PTE_EXECUTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK) +#define MM_PTE_NOCACHE (MM_PTE_CACHE_DISABLE_MASK) +#define MM_PTE_GUARD 0x0 // not expressable on R4000 +#define MM_PTE_CACHE MM_PTE_CACHE_ENABLE_MASK + +#define MM_PROTECT_FIELD_SHIFT 3 + +// +// Zero PTE +// + +#define MM_ZERO_PTE 0 + +// +// Zero Kernel PTE +// + +#define MM_ZERO_KERNEL_PTE MM_PTE_GLOBAL_MASK + + +// +// A demand zero PTE with a protection or PAGE_READWRITE. +// + +#define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) + +// +// A demand zero PTE with a protection or PAGE_READWRITE for system space. +// + +#define MM_KERNEL_DEMAND_ZERO_PTE ((MM_READWRITE << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) + +// +// A no access PTE for system space. +// + +#define MM_KERNEL_NOACCESS_PTE ((MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) + +// +// Dirty bit definitions for clean and dirty. +// + +#define MM_PTE_CLEAN 0 + +#define MM_PTE_DIRTY 1 + + + +#define MM_STACK_ALIGNMENT 0x2000 //8k +#define MM_STACK_OFFSET 0x1000 //align guard page on 4k offset + +// +// System process definitions +// + +#define PDE_PER_PAGE ((ULONG)1024) + +#define PTE_PER_PAGE ((ULONG)1024) + +// +// Number of page table pages for user addresses. +// + +#define MM_USER_PAGE_TABLE_PAGES (512) + +// +// R4000 has 8 colors. +// + +#define MM_NUMBER_OF_COLORS 8 + +// +// Mask for obtaining color from a physical page number. +// + +#define MM_COLOR_MASK 7 + +// +// Define secondary color stride. +// + +#define MM_COLOR_STRIDE 11 + +// +// Boundary for aligned pages of like color upon. +// + +#define MM_COLOR_ALIGNMENT 0x8000 + +// +// Mask for isolating color from virtual address. +// + +#define MM_COLOR_MASK_VIRTUAL 0x7000 + +// +// Define 1mb worth of secondary colors +// + +#define MM_SECONDARY_COLORS_DEFAULT (256) + +#define MM_SECONDARY_COLORS_MIN (2) + +#define MM_SECONDARY_COLORS_MAX (2048) + +// +// Mask for isolating secondary color from physical page number; +// + +extern ULONG MmSecondaryColorMask; + + + +//++ +//VOID +//MI_MAKE_VALID_PTE ( +// OUT OUTPTE, +// IN FRAME, +// IN PMASK, +// IN OWNER +// ); +// +// Routine Description: +// +// This macro makes a valid PTE from a page frame number, protection mask, +// and owner. +// +// Argments +// +// OUTPTE - Supplies the PTE in which to build the transition PTE. +// +// FRAME - Supplies the page frame number for the PTE. +// +// PMASK - Supplies the protection to set in the transition PTE. +// +// PPTE - Supplies a pointer to the PTE which is being made valid. +// For prototype PTEs NULL should be specified. +// +// Return Value: +// +// None. +// +//-- + +#define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \ + { \ + (OUTPTE).u.Long = ((FRAME << 6) | \ + (MmProtectToPteMask[PMASK]) | \ + MM_PTE_VALID_MASK); \ + if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ + (OUTPTE).u.Hard.Global = 1; \ + } \ + } + +//++ +//VOID +//MI_MAKE_VALID_PTE_TRANSITION ( +// IN OUT OUTPTE +// IN PROTECT +// ); +// +// Routine Description: +// +// This macro takes a valid pte and turns it into a transition PTE. +// +// Argments +// +// OUTPTE - Supplies the current valid PTE. This PTE is then +// modified to become a transition PTE. +// +// PROTECT - Supplies the protection to set in the transition PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \ + (OUTPTE).u.Long = ((((OUTPTE).u.Long & 0xffffffc0) << 3) | \ + (((PROTECT) << MM_PROTECT_FIELD_SHIFT)) | \ + ((OUTPTE).u.Long & MM_PTE_GLOBAL_MASK) | \ + MM_PTE_TRANSITION_MASK); + + +//++ +//VOID +//MI_MAKE_TRANSITION_PTE ( +// OUT OUTPTE, +// IN PAGE, +// IN PROTECT, +// IN PPTE +// ); +// +// Routine Description: +// +// This macro takes a valid pte and turns it into a transition PTE. +// +// Argments +// +// OUTPTE - Supplies the PTE in which to build the transition PTE. +// +// PAGE - Supplies the page frame number for the PTE. +// +// PROTECT - Supplies the protection to set in the transition PTE. +// +// PPTE - Supplies a pointer to the PTE, this is used to determine +// the owner of the PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \ + (OUTPTE).u.Long = 0; \ + (OUTPTE).u.Trans.PageFrameNumber = PAGE; \ + (OUTPTE).u.Trans.Transition = 1; \ + (OUTPTE).u.Trans.Protection = PROTECT; \ + if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) {\ + (OUTPTE).u.Hard.Global = 1; \ + } + + +//++ +//VOID +//MI_MAKE_TRANSITION_PTE_VALID ( +// OUT OUTPTE, +// IN PPTE +// ); +// +// Routine Description: +// +// This macro takes a transition pte and makes it a valid PTE. +// +// Argments +// +// OUTPTE - Supplies the PTE in which to build the valid PTE. +// +// PPTE - Supplies a pointer to the transition PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \ + (OUTPTE).u.Long = ((((PPTE)->u.Long >> 3) & 0xffffffc0) | \ + (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) | \ + MM_PTE_VALID_MASK); \ + if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ + (OUTPTE).u.Hard.Global = 1; \ + } + + +//++ +//VOID +//MI_SET_GLOBAL_BIT_IF_SYSTEM ( +// OUT OUTPTE, +// IN PPTE +// ); +// +// Routine Description: +// +// This macro sets the global bit if the pointer PTE is within +// system space. +// +// Argments +// +// OUTPTE - Supplies the PTE in which to build the valid PTE. +// +// PPTE - Supplies a pointer to the PTE becoming valid. +// +// Return Value: +// +// None. +// +//-- + +#define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE) \ + if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \ + (OUTPTE).u.Hard.Global = 1; \ + } + + +//++ +//VOID +//MI_SET_PTE_DIRTY ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro sets the dirty bit(s) in the specified PTE. +// +// Argments +// +// PTE - Supplies the PTE to set dirty. +// +// Return Value: +// +// None. +// +//-- + +#define MI_SET_PTE_DIRTY(PTE) (PTE).u.Long |= HARDWARE_PTE_DIRTY_MASK + + +//++ +//VOID +//MI_SET_PTE_CLEAN ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro clears the dirty bit(s) in the specified PTE. +// +// Argments +// +// PTE - Supplies the PTE to set clear. +// +// Return Value: +// +// None. +// +//-- + +#define MI_SET_PTE_CLEAN(PTE) (PTE).u.Long &= ~HARDWARE_PTE_DIRTY_MASK + + + +//++ +//VOID +//MI_IS_PTE_DIRTY ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro checks the dirty bit(s) in the specified PTE. +// +// Argments +// +// PTE - Supplies the PTE to check. +// +// Return Value: +// +// TRUE if the page is dirty (modified), FALSE otherwise. +// +//-- + +#define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) + + +//++ +//VOID +//MI_SET_GLOBAL_STATE ( +// IN MMPTE PTE, +// IN ULONG STATE +// ); +// +// Routine Description: +// +// This macro sets the global bit in the PTE. if the pointer PTE is within +// +// Argments +// +// PTE - Supplies the PTE to set global state into. +// +// Return Value: +// +// None. +// +//-- + +#define MI_SET_GLOBAL_STATE(PTE,STATE) \ + (PTE).u.Hard.Global = STATE; + + + +//++ +//VOID +//MI_ENABLE_CACHING ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro takes a valid PTE and sets the caching state to be +// enabled. +// +// Argments +// +// PTE - Supplies a valid PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_ENABLE_CACHING(PTE) ((PTE).u.Hard.CachePolicy = PCR->CachePolicy) + + + +//++ +//VOID +//MI_DISABLE_CACHING ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro takes a valid PTE and sets the caching state to be +// disabled. +// +// Argments +// +// PTE - Supplies a valid PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_DISABLE_CACHING(PTE) ((PTE).u.Hard.CachePolicy = UNCACHED_POLICY) + +//++ +//BOOLEAN +//MI_IS_CACHING_DISABLED ( +// IN PMMPTE PPTE +// ); +// +// Routine Description: +// +// This macro takes a valid PTE and returns TRUE if caching is +// disabled. +// +// Argments +// +// PPTE - Supplies a pointer to the valid PTE. +// +// Return Value: +// +// TRUE if caching is disabled, FALSE if it is enabled. +// +//-- + +#define MI_IS_CACHING_DISABLED(PPTE) \ + ((PPTE)->u.Hard.CachePolicy == UNCACHED_POLICY) + +//++ +//VOID +//MI_IS_PTE_DIRTY ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro checks the dirty bit(s) in the specified PTE. +// +// Argments +// +// PTE - Supplies the PTE to check. +// +// Return Value: +// +// TRUE if the page is dirty (modified), FALSE otherwise. +// +//-- + +#define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0) + + +//++ +//VOID +//MI_SET_PFN_DELETED ( +// IN PMMPFN PPFN +// ); +// +// Routine Description: +// +// This macro takes a pointer to a PFN element and indicates that +// the PFN is no longer in use. +// +// Argments +// +// PPTE - Supplies a pointer to the PFN element. +// +// Return Value: +// +// none. +// +//-- + +#define MI_SET_PFN_DELETED(PPFN) (((ULONG)(PPFN)->PteAddress &= 0x7FFFFFFF )) + + +//++ +//BOOLEAN +//MI_IS_PFN_DELETED ( +// IN PMMPFN PPFN +// ); +// +// Routine Description: +// +// This macro takes a pointer to a PFN element a determines if +// the PFN is no longer in use. +// +// Argments +// +// PPTE - Supplies a pointer to the PFN element. +// +// Return Value: +// +// TRUE if PFN is no longer used, FALSE if it is still being used. +// +//-- + +#define MI_IS_PFN_DELETED(PPFN) \ + (((ULONG)(PPFN)->PteAddress & 0x80000000) == 0) + + +//++ +//VOID +//MI_CHECK_PAGE_ALIGNMENT ( +// IN ULONG PAGE, +// IN ULONG COLOR +// ); +// +// Routine Description: +// +// This macro takes a PFN element number (Page) and checks to see +// if the virtual alignment for the previous address of the page +// is compatable with the new address of the page. If they are +// not compatable, the D cache is flushed. +// +// Argments +// +// PAGE - Supplies the PFN element. +// PPTE - Supplies a pointer to the new PTE which will contain the page. +// +// Return Value: +// +// none. +// +//-- + +#define MI_CHECK_PAGE_ALIGNMENT(PAGE,COLOR) \ +{ \ + PMMPFN PPFN; \ + ULONG OldColor; \ + PPFN = MI_PFN_ELEMENT(PAGE); \ + OldColor = PPFN->u3.e1.PageColor; \ + if ((COLOR) != OldColor) { \ + KeChangeColorPage((PVOID)((ULONG)(COLOR) << PAGE_SHIFT), \ + (PVOID)((ULONG)(OldColor << PAGE_SHIFT)), \ + Page); \ + PPFN->u3.e1.PageColor = COLOR; \ + } \ +} + + +//++ +//VOID +//MI_INITIALIZE_HYPERSPACE_MAP ( +// HYPER_PAGE +// ); +// +// Routine Description: +// +// This macro initializes the PTEs reserved for double mapping within +// hyperspace. +// +// Argments +// +// HYPER_PAGE - Phyical page number for the page to become hyperspace. +// +// Return Value: +// +// None. +// +//-- + +#define MI_INITIALIZE_HYPERSPACE_MAP(HYPER_PAGE) \ + { \ + PMMPTE NextPte; \ + ULONG LastEntry; \ + PMMPTE Base; \ + ULONG i; \ + KIRQL OldIrql; \ + Base = MiMapPageInHyperSpace (HYPER_PAGE, &OldIrql); \ + LastEntry = NUMBER_OF_MAPPING_PTES - MM_COLOR_MASK; \ + NextPte = (PMMPTE)((PCHAR)Base + BYTE_OFFSET(MmFirstReservedMappingPte));\ + for (i = 0; i < MM_NUMBER_OF_COLORS; i++ ) { \ + NextPte->u.Hard.PageFrameNumber = LastEntry; \ + NextPte += 1; \ + } \ + MiUnmapPageInHyperSpace (OldIrql); \ + } + + + +//++ +//ULONG +//MI_GET_PAGE_COLOR_FROM_PTE ( +// IN PMMPTE PTEADDRESS +// ); +// +// Routine Description: +// +// This macro determines the pages color based on the PTE address +// that maps the page. +// +// Argments +// +// PTEADDRESS - Supplies the PTE address the page is (or was) mapped at. +// +// Return Value: +// +// The pages color. +// +//-- + +#define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \ + ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ + MmSecondaryColorMask) | \ + ((((ULONG)(PTEADDRESS)) >> 2) & MM_COLOR_MASK)) + +//++ +//ULONG +//MI_GET_PAGE_COLOR_FROM_VA ( +// IN PVOID ADDRESS +// ); +// +// Routine Description: +// +// This macro determines the pages color based on the PTE address +// that maps the page. +// +// Argments +// +// ADDRESS - Supplies the address the page is (or was) mapped at. +// +// Return Value: +// +// The pages color. +// +//-- + +#define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \ + ((ULONG)((MmSystemPageColor += MM_COLOR_STRIDE) & \ + MmSecondaryColorMask) | \ + ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) + + +//++ +//ULONG +//MI_PAGE_COLOR_PTE_PROCESS ( +// IN PCHAR COLOR, +// IN PMMPTE PTE +// ); +// +// Routine Description: +// +// This macro determines the pages color based on the PTE address +// that maps the page. +// +// Argments +// +// +// Return Value: +// +// The pages color. +// +//-- + + +#define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \ + ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ + MmSecondaryColorMask) | \ + ((((ULONG)(PTE)) >> 2) & MM_COLOR_MASK)) + + +//++ +//ULONG +//MI_PAGE_COLOR_VA_PROCESS ( +// IN PVOID ADDRESS, +// IN PEPROCESS COLOR +// ); +// +// Routine Description: +// +// This macro determines the pages color based on the PTE address +// that maps the page. +// +// Argments +// +// ADDRESS - Supplies the address the page is (or was) mapped at. +// +// Return Value: +// +// The pages color. +// +//-- + +#define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \ + ((ULONG)(((*(COLOR)) += MM_COLOR_STRIDE) & \ + MmSecondaryColorMask) | \ + ((((ULONG)(ADDRESS)) >> PAGE_SHIFT) & MM_COLOR_MASK)) + + +//++ +//ULONG +//MI_GET_NEXT_COLOR ( +// IN ULONG COLOR +// ); +// +// Routine Description: +// +// This macro returns the next color in the sequence. +// +// Argments +// +// COLOR - Supplies the color to return the next of. +// +// Return Value: +// +// Next color in sequence. +// +//-- + +#define MI_GET_NEXT_COLOR(COLOR) ((COLOR + 1) & MM_COLOR_MASK) + + +//++ +//ULONG +//MI_GET_PREVIOUS_COLOR ( +// IN ULONG COLOR +// ); +// +// Routine Description: +// +// This macro returns the previous color in the sequence. +// +// Argments +// +// COLOR - Supplies the color to return the previous of. +// +// Return Value: +// +// Previous color in sequence. +// +//-- + +#define MI_GET_PREVIOUS_COLOR(COLOR) ((COLOR - 1) & MM_COLOR_MASK) + +#define MI_GET_COLOR_FROM_SECONDARY(COLOR) ((COLOR) & MM_COLOR_MASK) + +// +// The top bits of the prototype PTE tracks the secondary color, +// the primary color may NOT match the lower bits of the prototype PTE +// in the case of fork. +// + +#define MI_GET_SECONDARY_COLOR(PAGE,PFN) \ + ((((ULONG)(PAGE) & MmSecondaryColorMask)) | (PFN)->u3.e1.PageColor) + + + +//++ +//VOID +//MI_GET_MODIFIED_PAGE_BY_COLOR ( +// OUT ULONG PAGE, +// IN ULONG COLOR +// ); +// +// Routine Description: +// +// This macro returns the first page destined for a paging +// file with the desired color. It does NOT remove the page +// from its list. +// +// Argments +// +// PAGE - Returns the page located, the value MM_EMPTY_LIST is +// returned if there is no page of the specified color. +// +// COLOR - Supplies the color of page to locate. +// +// Return Value: +// +// none. +// +//-- + +#define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \ + PAGE = MmModifiedPageListByColor[COLOR].Flink + + +//++ +//VOID +//MI_GET_MODIFIED_PAGE_ANY_COLOR ( +// OUT ULONG PAGE, +// IN OUT ULONG COLOR +// ); +// +// Routine Description: +// +// This macro returns the first page destined for a paging +// file with the desired color. If not page of the desired +// color exists, all colored lists are searched for a page. +// It does NOT remove the page from its list. +// +// Argments +// +// PAGE - Returns the page located, the value MM_EMPTY_LIST is +// returned if there is no page of the specified color. +// +// COLOR - Supplies the color of page to locate and returns the +// color of the page located. +// +// Return Value: +// +// none. +// +//-- + +#define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \ + { \ + if (MmTotalPagesForPagingFile == 0) { \ + PAGE = MM_EMPTY_LIST; \ + } else { \ + while (MmModifiedPageListByColor[COLOR].Flink == \ + MM_EMPTY_LIST) { \ + COLOR = MI_GET_NEXT_COLOR(COLOR); \ + } \ + PAGE = MmModifiedPageListByColor[COLOR].Flink; \ + } \ + } + + +//++ +//VOID +//MI_MAKE_VALID_PTE_WRITE_COPY ( +// IN OUT PMMPTE PTE +// ); +// +// Routine Description: +// +// This macro checks to see if the PTE indicates that the +// page is writable and if so it clears the write bit and +// sets the copy-on-write bit. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// None. +// +//-- + +#define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \ + if ((PPTE)->u.Hard.Write == 1) { \ + (PPTE)->u.Hard.CopyOnWrite = 1; \ + (PPTE)->u.Hard.Dirty = MM_PTE_CLEAN; \ + } + + +//++ +//ULONG +//MI_DETERMINE_OWNER ( +// IN MMPTE PPTE +// ); +// +// Routine Description: +// +// This macro examines the virtual address of the PTE and determines +// if the PTE resides in system space or user space. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. +// +//-- + +#define MI_DETERMINE_OWNER(PPTE) \ + ((((PPTE) <= MiGetPteAddress(MM_HIGHEST_USER_ADDRESS)) || \ + ((PPTE) >= MiGetPdeAddress(NULL) && \ + ((PPTE) <= MiGetPdeAddress(MM_HIGHEST_USER_ADDRESS)))) ? 1 : 0) + + +//++ +//VOID +//MI_SET_ACCESSED_IN_PTE ( +// IN OUT MMPTE PPTE +// ); +// +// Routine Description: +// +// This macro sets the ACCESSED field in the PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE. +// +//-- + +// not implemented on mips r4000. +#define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED) + + +//++ +//ULONG +//MI_GET_ACCESSED_IN_PTE ( +// IN OUT MMPTE PPTE +// ); +// +// Routine Description: +// +// This macro returns the state of the ACCESSED field in the PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// The state of the ACCESSED field. +// +//-- + +#define MI_GET_ACCESSED_IN_PTE(PPTE) 0 + + + +//++ +//VOID +//MI_SET_OWNER_IN_PTE ( +// IN PMMPTE PPTE +// IN ULONG OWNER +// ); +// +// Routine Description: +// +// This macro sets the owner field in the PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// None. +// +//-- + +// not implemented on r4000. +#define MI_SET_OWNER_IN_PTE(PPTE,OWNER) + + + +//++ +//ULONG +//MI_GET_OWNER_IN_PTE ( +// IN PMMPTE PPTE +// ); +// +// Routine Description: +// +// This macro gets the owner field from the PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// The state of the OWNER field. +// +//-- + +// always kernel mode on r4000. +#define MI_GET_OWNER_IN_PTE(PPTE) KernelMode + +// +// bit mask to clear out fields in a PTE to or in prototype pte offset. +// + +#define CLEAR_FOR_PROTO_PTE_ADDRESS ((ULONG)0xf) + + +// bit mask to clear out fields in a PTE to or in paging file location. + +#define CLEAR_FOR_PAGE_FILE ((ULONG)(0x0F9)) + +//++ +//VOID +//MI_SET_PAGING_FILE_INFO ( +// IN OUT MMPTE PPTE, +// IN ULONG FILEINFO, +// IN ULONG OFFSET +// ); +// +// Routine Description: +// +// This macro sets into the specified PTE the supplied information +// to indicate where the backing store for the page is located. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// FILEINFO - Supplies the number of the paging file. +// +// OFFSET - Supplies the offset into the paging file. +// +// Return Value: +// +// None. +// +//-- + +#define SET_PAGING_FILE_INFO(PTE,FILEINFO,OFFSET) \ + ((((PTE).u.Long & CLEAR_FOR_PAGE_FILE) | \ + (((FILEINFO) << 9) | \ + (OFFSET << 12)))) + +//++ +//PMMPTE +//MiPteToProto ( +// IN OUT MMPTE PPTE, +// IN ULONG FILEINFO, +// IN ULONG OFFSET +// ); +// +// Routine Description: +// +// This macro returns the address of the corresponding prototype which +// was encoded earlier into the supplied PTE. +// +// NOTE THAT AS PROTOPTE CAN ONLY RESIDE IN PAGED POOL!!!!!! +// +// MAX SIZE = 2^(2+7+21) = 2^30 = 1GB. +// +// NOTE, that the valid bit must be zero! +// +// Argments +// +// lpte - Supplies the PTE to operate upon. +// +// Return Value: +// +// Pointer to the prototype PTE that backs this PTE. +// +//-- +// +// MiPteToProtoPte returns the address of the corresponding prototype +// PTE +// +// +// + +#define MiPteToProto(lpte) \ + ((PMMPTE)((((lpte)->u.Long >> 1) & 0x3FFFFFFC) + \ + MmProtopte_Base)) + + +//++ +//ULONG +//MiProtoAddressForPte ( +// IN PMMPTE proto_va +// ); +// +// Routine Description: +// +// This macro sets into the specified PTE the supplied information +// to indicate where the backing store for the page is located. +// MiProtoAddressForPte returns the bit field to OR into the PTE to +// reference a prototype PTE. And set the protoPTE bit, +// MM_PTE_PROTOTYPE_MASK. +// +// Argments +// +// proto_va - Supplies the address of the prototype PTE. +// +// Return Value: +// +// Mask to set into the PTE. +// +//-- + +#define MiProtoAddressForPte(proto_va) \ + ((ULONG)((((ULONG)proto_va - MmProtopte_Base) << 1) | MM_PTE_PROTOTYPE_MASK)) + + + +//++ +//ULONG +//MiProtoAddressForKernelPte ( +// IN PMMPTE proto_va +// ); +// +// Routine Description: +// +// This macro sets into the specified PTE the supplied information +// to indicate where the backing store for the page is located. +// MiProtoAddressForPte returns the bit field to OR into the PTE to +// reference a prototype PTE. And set the protoPTE bit, +// MM_PTE_PROTOTYPE_MASK. +// +// This macro also sets any other information (such as global bits) +// required for kernel mode PTEs. +// +// Argments +// +// proto_va - Supplies the address of the prototype PTE. +// +// Return Value: +// +// Mask to set into the PTE. +// +//-- + +#define MiProtoAddressForKernelPte(proto_va) \ + (((ULONG)(proto_va) < (ULONG)KSEG1_BASE) ? \ + ((ULONG)((((ULONG)proto_va - (ULONG)MmNonPagedPoolStart) << 1) | MM_PTE_PROTOTYPE_MASK | \ + 0x40000000 | MM_PTE_GLOBAL_MASK)) \ + : ((ULONG)((((ULONG)proto_va - MmProtopte_Base) << 1) | MM_PTE_PROTOTYPE_MASK | \ + MM_PTE_GLOBAL_MASK))) + + + +#define MM_SUBSECTION_MAP (128*1024*1024) + + +//++ +//PSUBSECTION +//MiGetSubsectionAddress ( +// IN PMMPTE lpte +// ); +// +// Routine Description: +// +// This macro takes a PTE and returns the address of the subsection that +// the PTE refers to. Subsections are quadword structures allocated +// from nonpaged pool. +// +// NOTE THIS MACRO LIMITS THE SIZE OF NONPAGED POOL! +// MAXIMUM NONPAGED POOL = 2^(24+3) = 2^27 = 128mb in KSEG_0 POOL AND +// 128 MB IN EXPANDED POOL. +// +// Argments +// +// lpte - Supplies the PTE to operate upon. +// +// Return Value: +// +// A pointer to the subsection referred to by the supplied PTE. +// +//-- + +#define MiGetSubsectionAddress(lpte) \ + (((lpte)->u.Long & 0x1) ? \ + ((PSUBSECTION)(((((lpte)->u.Long >> 8) << 3) + (ULONG)MmSubsectionBase))) \ + : ((PSUBSECTION)((ULONG)MM_NONPAGED_POOL_END - ((((lpte)->u.Long) >> 8) << 3)))) + + + +//++ +//ULONG +//MiGetSubsectionAddressForPte ( +// IN PSUBSECTION VA +// ); +// +// Routine Description: +// +// This macro takes the address of a subsection and encodes it for use +// in a PTE. +// +// NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED! +// +// Argments +// +// VA - Supplies a pointer to the subsection to encode. +// +// Return Value: +// +// The mask to set into the PTE to make it reference the supplied +// subsetion. +// +//-- + +#define MiGetSubsectionAddressForPte(VA) \ + (((ULONG)(VA) < (ULONG)KSEG1_BASE) ? \ + ((((ULONG)(VA) - (ULONG)MmSubsectionBase) << 5) | 0x1) \ + : (((ULONG)MM_NONPAGED_POOL_END - (ULONG)VA) << 5)) + + + +//++ +//PMMPTE +//MiGetPdeAddress ( +// IN PVOID va +// ); +// +// Routine Description: +// +// MiGetPdeAddress returns the address of the PDE which maps the +// given virtual address. +// +// Argments +// +// Va - Supplies the virtual address to locate the PDE for. +// +// Return Value: +// +// The address of the PDE. +// +//-- + +#define MiGetPdeAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE)) + + + +//++ +//PMMPTE +//MiGetPteAddress ( +// IN PVOID va +// ); +// +// Routine Description: +// +// MiGetPteAddress returns the address of the PTE which maps the +// given virtual address. +// +// Argments +// +// Va - Supplies the virtual address to locate the PTE for. +// +// Return Value: +// +// The address of the PTE. +// +//-- + +#define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE)) + + +//++ +//ULONG +//MiGetPdeOffset ( +// IN PVOID va +// ); +// +// Routine Description: +// +// MiGetPdeOffset returns the offset into a page directory +// for a given virtual address. +// +// Argments +// +// Va - Supplies the virtual address to locate the offset for. +// +// Return Value: +// +// The offset into the page directory table the corresponding PDE is at. +// +//-- + +#define MiGetPdeOffset(va) (((ULONG)(va)) >> 22) + + +//++ +//ULONG +//MiGetPteOffset ( +// IN PVOID va +// ); +// +// Routine Description: +// +// MiGetPteOffset returns the offset into a page table page +// for a given virtual address. +// +// Argments +// +// Va - Supplies the virtual address to locate the offset for. +// +// Return Value: +// +// The offset into the page table page table the corresponding PTE is at. +// +//-- + +#define MiGetPteOffset(va) ((((ULONG)(va)) << 10) >> 22) + + +//++ +//PMMPTE +//MiGetProtoPteAddress ( +// IN PMMPTE VAD, +// IN PVOID VA +// ); +// +// Routine Description: +// +// MiGetProtoPteAddress returns a pointer to the prototype PTE which +// is mapped by the given virtual address descriptor and address within +// the virtual address descriptor. +// +// Argments +// +// VAD - Supplies a pointer to the virtual address descriptor that contains +// the VA. +// +// VA - Supplies the virtual address. +// +// Return Value: +// +// A pointer to the proto PTE which corresponds to the VA. +// +//-- + +#define MiGetProtoPteAddress(VAD,VA) \ + (((((((ULONG)(VA) - (ULONG)(VAD)->StartingVa) >> PAGE_SHIFT) << PTE_SHIFT) + \ + (ULONG)(VAD)->FirstPrototypePte) <= (ULONG)(VAD)->LastContiguousPte) ? \ + ((PMMPTE)(((((ULONG)(VA) - (ULONG)(VAD)->StartingVa) >> PAGE_SHIFT) << PTE_SHIFT) + \ + (ULONG)(VAD)->FirstPrototypePte)) : \ + MiGetProtoPteAddressExtended ((VAD),(VA))) + + + +//++ +//PVOID +//MiGetVirtualAddressMappedByPte ( +// IN PMMPTE PTE +// ); +// +// Routine Description: +// +// MiGetVirtualAddressMappedByPte returns the virtual address +// which is mapped by a given PTE address. +// +// Argments +// +// PTE - Supplies the PTE to get the virtual address for. +// +// Return Value: +// +// Virtual address mapped by the PTE. +// +//-- + +#define MiGetVirtualAddressMappedByPte(va) ((PVOID)((ULONG)(va) << 10)) + + +//++ +//ULONG +//GET_PAGING_FILE_NUMBER ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro extracts the paging file number from a PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// The paging file number. +// +//-- + +#define GET_PAGING_FILE_NUMBER(PTE) ((((PTE).u.Long) >> 9) & 0x7) + + +//++ +//ULONG +//GET_PAGING_FILE_OFFSET ( +// IN MMPTE PTE +// ); +// +// Routine Description: +// +// This macro extracts the offset into the paging file from a PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// The paging file offset. +// +//-- + +#define GET_PAGING_FILE_OFFSET(PTE) ((((PTE).u.Long) >> 12) & 0x000FFFFF) + +//++ +//ULONG +//IS_PTE_NOT_DEMAND_ZERO ( +// IN PMMPTE PPTE +// ); +// +// Routine Description: +// +// This macro checks to see if a given PTE is NOT a demand zero PTE. +// +// Argments +// +// PTE - Supplies the PTE to operate upon. +// +// Return Value: +// +// Returns 0 if the PTE is demand zero, non-zero otherwise. +// +//-- + +#define IS_PTE_NOT_DEMAND_ZERO(PTE) ((PTE).u.Long & (ULONG)0xFFFFF107) +#define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT) + +#define MM_KERNEL_DEMAND_ZERO_PTE ((MM_READWRITE << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) + +#define MM_KERNEL_NOACCESS_PTE ((MM_NOACCESS << MM_PROTECT_FIELD_SHIFT) | MM_PTE_GLOBAL_MASK) + + + +//++ +//VOID +//MI_MAKING_VALID_PTE_INVALID( +// IN PMMPTE PPTE +// ); +// +// Routine Description: +// +// Prepare to make a single valid PTE invalid. +// No action is required on x86. +// +// Argments +// +// SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. +// +// Return Value: +// +// None. +// +//-- + +// not implemented on r4000. +#define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE) + + + +//++ +//VOID +//MI_MAKING_VALID_MULTIPLE_PTES_INVALID( +// IN PMMPTE PPTE +// ); +// +// Routine Description: +// +// Prepare to make multiple valid PTEs invalid. +// No action is required on x86. +// +// Argments +// +// SYSTEM_WIDE - Supplies TRUE if this will happen on all processors. +// +// Return Value: +// +// None. +// +//-- + +// not implemented on r4000. +#define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE) + +// +// Make a writable PTE, writeable-copy PTE. This takes advantage of +// the fact that the protection field in the PTE (5 bit protection) is +// set up such that write is a bit. +// + +#define MI_MAKE_PROTECT_WRITE_COPY(PTE) \ + if ((PTE).u.Long & 0x20) { \ + ((PTE).u.Long |= 0x8); \ + } + + +//++ +//VOID +//MI_SET_PAGE_DIRTY( +// IN PMMPTE PPTE, +// IN PVOID VA, +// IN PVOID PFNHELD +// ); +// +// Routine Description: +// +// This macro sets the dirty bit (and release page file space). +// +// Argments +// +// TEMP - Supplies a temporary for usage. +// +// PPTE - Supplies a pointer to the PTE that corresponds to VA. +// +// VA - Supplies a the virtual address of the page fault. +// +// PFNHELD - Supplies TRUE if the PFN lock is held. +// +// Return Value: +// +// None. +// +//-- + +#define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \ + if ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN) { \ + MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ + } + + + +//++ +//VOID +//MI_NO_FAULT_FOUND( +// IN TEMP, +// IN PMMPTE PPTE, +// IN PVOID VA, +// IN PVOID PFNHELD +// ); +// +// Routine Description: +// +// This macro handles the case when a page fault is taken and no +// PTE with the valid bit clear is found. +// +// Argments +// +// TEMP - Supplies a temporary for usage. +// +// PPTE - Supplies a pointer to the PTE that corresponds to VA. +// +// VA - Supplies a the virtual address of the page fault. +// +// PFNHELD - Supplies TRUE if the PFN lock is held. +// +// Return Value: +// +// None. +// +//-- + +#define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \ + if (StoreInstruction && ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN)) { \ + MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \ + } else { \ + KeFillEntryTb ((PHARDWARE_PTE)PPTE, VA, FALSE); \ + } +// KeFillEntryTb((PHARDWARE_PTE)(MiGetPdeAddress(VA)),(PVOID)PPTE,FALSE); + // + // If the PTE was already valid, assume that the PTE + // in the TB is stall and just reload the PTE. + // + + +//++ +//ULONG +//MI_CAPTURE_DIRTY_BIT_TO_PFN ( +// IN PMMPTE PPTE, +// IN PMMPFN PPFN +// ); +// +// Routine Description: +// +// This macro gets captures the state of the dirty bit to the PFN +// and frees any associated page file space if the PTE has been +// modified element. +// +// NOTE - THE PFN LOCK MUST BE HELD! +// +// Argments +// +// PPTE - Supplies the PTE to operate upon. +// +// PPFN - Supplies a pointer to the PFN database element that corresponds +// to the page mapped by the PTE. +// +// Return Value: +// +// None. +// +//-- + +#define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \ + if (((PPFN)->u3.e1.Modified == 0) && \ + ((PPTE)->u.Hard.Dirty == MM_PTE_DIRTY)) { \ + (PPFN)->u3.e1.Modified = 1; \ + if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \ + ((PPFN)->u3.e1.WriteInProgress == 0)) { \ + MiReleasePageFileSpace ((PPFN)->OriginalPte); \ + (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \ + } \ + } + + + +//++ +//BOOLEAN +//MI_IS_PHYSICAL_ADDRESS ( +// IN PVOID VA +// ); +// +// Routine Description: +// +// This macro deterines if a give virtual address is really a +// physical address. +// +// Argments +// +// VA - Supplies the virtual address. +// +// Return Value: +// +// FALSE if it is not a physical address, TRUE if it is. +// +//-- + +#define MI_IS_PHYSICAL_ADDRESS(Va) \ + (((ULONG)Va >= KSEG0_BASE) && ((ULONG)Va < KSEG2_BASE)) + + + + +//++ +//ULONG +//MI_CONVERT_PHYSICAL_TO_PFN ( +// IN PVOID VA +// ); +// +// Routine Description: +// +// This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS) +// to its corresponding physical frame number. +// +// Argments +// +// VA - Supplies a pointer to the physical address. +// +// Return Value: +// +// Returns the PFN for the page. +// +//-- + +#define MI_CONVERT_PHYSICAL_TO_PFN(Va) (((ULONG)Va << 3) >> 15) + + + + +typedef struct _MMCOLOR_TABLES { + ULONG Flink; + PVOID Blink; +} MMCOLOR_TABLES, *PMMCOLOR_TABLES; + +typedef struct _MMPRIMARY_COLOR_TABLES { + LIST_ENTRY ListHead; +} MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES; + + +#if MM_MAXIMUM_NUMBER_OF_COLORS > 1 +extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS]; +#endif + +extern PMMCOLOR_TABLES MmFreePagesByColor[2]; + +extern ULONG MmTotalPagesForPagingFile; + +// +// The hardware PTE is defined in ../inc/mips.h +// + +// +// Invalid PTEs have the following defintion. +// + +typedef struct _MMPTE_SOFTWARE { + ULONG Global : 1; + ULONG Valid : 1; + ULONG Prototype : 1; + ULONG Protection : 5; + ULONG Transition : 1; + ULONG PageFileLow : 3; + ULONG PageFileHigh : 20; +} MMPTE_SOFTWARE; + + +typedef struct _MMPTE_TRANSITION { + ULONG Global : 1; + ULONG Valid : 1; + ULONG Prototype : 1; + ULONG Protection : 5; + ULONG Transition : 1; + ULONG PageFrameNumber : 23; +} MMPTE_TRANSITION; + + +typedef struct _MMPTE_PROTOTYPE { + ULONG Global : 1; + ULONG Valid : 1; + ULONG Prototype : 1; + ULONG ProtoAddressLow : 6; + ULONG ProtoAddressHigh : 22; + ULONG ReadOnly : 1; +} MMPTE_PROTOTYPE; + +typedef struct _MMPTE_SUBSECTION { + ULONG WhichPool : 1; + ULONG Valid : 1; + ULONG Prototype : 1; + ULONG Protection : 5; + ULONG SubsectionAddressLow : 4; + ULONG SubsectionAddressHigh : 20; +} MMPTE_SUBSECTION; + +typedef struct _MMPTE_LIST { + ULONG filler01 : 1; + ULONG Valid : 1; + ULONG filler0 : 9; + ULONG OneEntry : 1; + ULONG NextEntry : 20; +} MMPTE_LIST; + + +// typedef struct _HARDWARE_PTE { +// ULONG Global : 1; +// ULONG Valid : 1; +// ULONG Dirty : 1; +// ULONG CachePolicy : 3; +// ULONG PageFrameNumber : 24; +// ULONG Write : 1; +// ULONG CopyOnWrite : 1; +// } HARDWARE_PTE, *PHARDWARE_PTE; + + +// +// A Page Table Entry on a MIPS R4000 has the following definition. +// + +typedef struct _MMPTE { + union { + ULONG Long; + HARDWARE_PTE Hard; + HARDWARE_PTE Flush; + MMPTE_PROTOTYPE Proto; + MMPTE_SOFTWARE Soft; + MMPTE_TRANSITION Trans; + MMPTE_SUBSECTION Subsect; + MMPTE_LIST List; + } u; +} MMPTE; + +typedef MMPTE *PMMPTE; |