1 /* 2 * kernel internal memory managment definitions for amd64 3 */ 4 #pragma once 5 6 /* Memory layout base addresses */ 7 #define MI_LOWEST_VAD_ADDRESS (PVOID)0x000000007FF00000ULL 8 #define MI_HIGHEST_USER_ADDRESS (PVOID)0x000007FFFFFEFFFFULL 9 #define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL 10 #define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL 11 #define MI_REAL_SYSTEM_RANGE_START 0xFFFF800000000000ULL 12 #define MI_PAGE_TABLE_BASE 0xFFFFF68000000000ULL 13 #define HYPER_SPACE 0xFFFFF70000000000ULL 14 #define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL 15 #define MI_SHARED_SYSTEM_PAGE 0xFFFFF78000000000ULL 16 #define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL 17 #define MI_LOADER_MAPPINGS 0xFFFFF80000000000ULL 18 #define MI_PAGED_SYSTEM_START 0xFFFFF88000000000ULL 19 #define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL 20 #define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL 21 #define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL 22 #define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL 23 #define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL 24 #define MM_SYSTEM_SPACE_START 0xFFFFF98000000000ULL 25 #define MI_PFN_DATABASE 0xFFFFFA8000000000ULL 26 #define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL 27 28 /* WOW64 address definitions */ 29 #define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF 30 #define MM_SYSTEM_RANGE_START_WOW64 0x80000000 31 32 #define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME 33 #define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME 34 #define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START 35 #define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1) 36 #define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE) 37 #define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) 38 #define MI_MAPPING_RANGE_START HYPER_SPACE 39 #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE) 40 #define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE) 41 #define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE) 42 #define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE) 43 #define MI_NONPAGED_POOL_END 0 44 45 /* Memory sizes */ 46 #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255*1024*1024) >> PAGE_SHIFT) 47 #define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19*1024*1024) >> PAGE_SHIFT) 48 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32*1024*1024) >> PAGE_SHIFT) 49 #define MI_MIN_PAGES_FOR_SYSPTE_BOOST_BOOST ((256*1024*1024) >> PAGE_SHIFT) 50 #define MI_MIN_INIT_PAGED_POOLSIZE (32 * 1024 * 1024) 51 #define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) 52 #define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) 53 #define MI_SYSTEM_VIEW_SIZE (16 * 1024 * 1024) 54 #define MI_MIN_SECONDARY_COLORS 8 55 #define MI_SECONDARY_COLORS 64 56 #define MI_MAX_SECONDARY_COLORS 1024 57 #define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB) 58 #define MI_ALLOCATION_FRAGMENT (64 * _1KB) 59 #define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB) 60 #define MI_SESSION_WORKING_SET_SIZE (4 * 1024 * 1024) 61 #define MI_SESSION_VIEW_SIZE (20 * 1024 * 1024) 62 #define MI_SESSION_POOL_SIZE (16 * 1024 * 1024) 63 #define MI_SESSION_IMAGE_SIZE (8 * 1024 * 1024) 64 #define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \ 65 MI_SESSION_POOL_SIZE + \ 66 MI_SESSION_IMAGE_SIZE + \ 67 MI_SESSION_WORKING_SET_SIZE) 68 69 #define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START) 70 71 /* Misc constants */ 72 #define _MI_PAGING_LEVELS 4 73 #define MI_NUMBER_SYSTEM_PTES 22000 74 #define MI_MAX_FREE_PAGE_LISTS 4 75 #define NR_SECTION_PAGE_TABLES 1024 76 #define NR_SECTION_PAGE_ENTRIES 1024 77 #define MI_HYPERSPACE_PTES (256 - 1) 78 #define MI_ZERO_PTES (32) 79 /* FIXME - different architectures have different cache line sizes... */ 80 #define MM_CACHE_LINE_SIZE 32 81 82 /* Helper macros */ 83 #define PAGE_MASK(x) ((x)&(~0xfff)) 84 #define PAE_PAGE_MASK(x) ((x)&(~0xfffLL)) 85 #define IS_ALIGNED(addr, align) (((ULONG64)(addr) & (align - 1)) == 0) 86 #define IS_PAGE_ALIGNED(addr) IS_ALIGNED(addr, PAGE_SIZE) 87 88 #define MiIsPteOnPdeBoundary(PointerPte) \ 89 ((((ULONG_PTR)PointerPte) & (PAGE_SIZE - 1)) == 0) 90 #define MiIsPteOnPpeBoundary(PointerPte) \ 91 ((((ULONG_PTR)PointerPte) & (PDE_PER_PAGE * PAGE_SIZE - 1)) == 0) 92 #define MiIsPteOnPxeBoundary(PointerPte) \ 93 ((((ULONG_PTR)PointerPte) & (PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1)) == 0) 94 95 /* MMPTE related defines */ 96 #define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF) 97 #define MM_EMPTY_LIST ((ULONG_PTR)-1) 98 99 #define ADDR_TO_PAGE_TABLE(v) ((ULONG)(((ULONG_PTR)(v)) / (512 * PAGE_SIZE))) 100 #define ADDR_TO_PDE_OFFSET(v) ((ULONG)((((ULONG_PTR)(v)) / (512 * PAGE_SIZE)))) 101 #define ADDR_TO_PTE_OFFSET(v) ((ULONG)((((ULONG_PTR)(v)) % (512 * PAGE_SIZE)) / PAGE_SIZE)) 102 103 #define MiGetPdeOffset ADDR_TO_PDE_OFFSET 104 105 #define VAtoPXI(va) ((((ULONG64)va) >> PXI_SHIFT) & 0x1FF) 106 #define VAtoPPI(va) ((((ULONG64)va) >> PPI_SHIFT) & 0x1FF) 107 #define VAtoPDI(va) ((((ULONG64)va) >> PDI_SHIFT) & 0x1FF) 108 #define VAtoPTI(va) ((((ULONG64)va) >> PTI_SHIFT) & 0x1FF) 109 110 /* Easy accessing PFN in PTE */ 111 #define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber) 112 #define PFN_FROM_PDE(v) ((v)->u.Hard.PageFrameNumber) 113 #define PFN_FROM_PPE(v) ((v)->u.Hard.PageFrameNumber) 114 #define PFN_FROM_PXE(v) ((v)->u.Hard.PageFrameNumber) 115 116 // FIXME, only copied from x86 117 #define MI_MAKE_LOCAL_PAGE(x) ((x)->u.Hard.Global = 0) 118 #define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1) 119 #define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1) 120 #define MI_PAGE_DISABLE_CACHE(x) ((x)->u.Hard.CacheDisable = 1) 121 #define MI_PAGE_WRITE_THROUGH(x) ((x)->u.Hard.WriteThrough = 1) 122 #define MI_PAGE_WRITE_COMBINED(x) ((x)->u.Hard.WriteThrough = 0) 123 #define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1) 124 #if !defined(CONFIG_SMP) 125 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1) 126 #else 127 #define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1) 128 #endif 129 #define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1) 130 #define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1) 131 #define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1) 132 #if !defined(CONFIG_SMP) 133 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1) 134 #else 135 #define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1) 136 #endif 137 138 // FIXME!!! 139 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \ 140 ((x) / (4*1024*1024)) 141 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \ 142 ((((x)) % (4*1024*1024)) / (4*1024)) 143 144 //#define TEB_BASE 0x7FFDE000 145 146 /* On x86, these two are the same */ 147 #define MMPDE MMPTE 148 #define PMMPDE PMMPTE 149 #define MMPPE MMPTE 150 #define PMMPPE PMMPTE 151 #define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE 152 153 #define ValidKernelPpe ValidKernelPde 154 155 PULONG64 156 FORCEINLINE 157 MmGetPageDirectory(VOID) 158 { 159 return (PULONG64)__readcr3(); 160 } 161 162 PMMPTE 163 FORCEINLINE 164 MiAddressToPxe(PVOID Address) 165 { 166 ULONG64 Offset = (ULONG64)Address >> (PXI_SHIFT - 3); 167 Offset &= PXI_MASK << 3; 168 return (PMMPTE)(PXE_BASE + Offset); 169 } 170 171 PMMPTE 172 FORCEINLINE 173 MiAddressToPpe(PVOID Address) 174 { 175 ULONG64 Offset = (ULONG64)Address >> (PPI_SHIFT - 3); 176 Offset &= 0x3FFFF << 3; 177 return (PMMPTE)(PPE_BASE + Offset); 178 } 179 180 PMMPTE 181 FORCEINLINE 182 _MiAddressToPde(PVOID Address) 183 { 184 ULONG64 Offset = (ULONG64)Address >> (PDI_SHIFT - 3); 185 Offset &= 0x7FFFFFF << 3; 186 return (PMMPTE)(PDE_BASE + Offset); 187 } 188 #define MiAddressToPde(x) _MiAddressToPde((PVOID)(x)) 189 190 PMMPTE 191 FORCEINLINE 192 _MiAddressToPte(PVOID Address) 193 { 194 ULONG64 Offset = (ULONG64)Address >> (PTI_SHIFT - 3); 195 Offset &= 0xFFFFFFFFFULL << 3; 196 return (PMMPTE)(PTE_BASE + Offset); 197 } 198 #define MiAddressToPte(x) _MiAddressToPte((PVOID)(x)) 199 200 ULONG 201 FORCEINLINE 202 MiAddressToPti(PVOID Address) 203 { 204 return ((((ULONG64)Address) >> PTI_SHIFT) & 0x1FF); 205 } 206 #define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name 207 208 ULONG 209 FORCEINLINE 210 MiAddressToPxi(PVOID Address) 211 { 212 return ((((ULONG64)Address) >> PXI_SHIFT) & 0x1FF); 213 } 214 215 216 /* Convert a PTE into a corresponding address */ 217 PVOID 218 FORCEINLINE 219 MiPteToAddress(PMMPTE PointerPte) 220 { 221 /* Use signed math */ 222 return (PVOID)(((LONG64)PointerPte << 25) >> 16); 223 } 224 225 PVOID 226 FORCEINLINE 227 MiPdeToAddress(PMMPTE PointerPde) 228 { 229 /* Use signed math */ 230 return (PVOID)(((LONG64)PointerPde << 34) >> 16); 231 } 232 233 PVOID 234 FORCEINLINE 235 MiPpeToAddress(PMMPTE PointerPpe) 236 { 237 /* Use signed math */ 238 return (PVOID)(((LONG64)PointerPpe << 43) >> 16); 239 } 240 241 PVOID 242 FORCEINLINE 243 MiPxeToAddress(PMMPTE PointerPxe) 244 { 245 /* Use signed math */ 246 return (PVOID)(((LONG64)PointerPxe << 52) >> 16); 247 } 248 249 BOOLEAN 250 FORCEINLINE 251 MiIsPdeForAddressValid(PVOID Address) 252 { 253 return ((MiAddressToPxe(Address)->u.Hard.Valid) && 254 (MiAddressToPpe(Address)->u.Hard.Valid) && 255 (MiAddressToPde(Address)->u.Hard.Valid)); 256 } 257 258 #define MiPdeToPte(PDE) ((PMMPTE)MiPteToAddress(PDE)) 259 #define MiPteToPde(PTE) ((PMMPDE)MiAddressToPte(PTE)) 260 #define MiPdeToPpe(Pde) ((PMMPPE)MiAddressToPte(Pde)) 261 262 /* Sign extend 48 bits */ 263 #define MiProtoPteToPte(x) (PMMPTE)(((LONG64)(x)->u.Long) >> 16) 264 265 FORCEINLINE 266 VOID 267 MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, 268 IN PMMPTE PointerPte) 269 { 270 /* Store the Address */ 271 NewPte->u.Long = (ULONG64)PointerPte << 16; 272 273 /* Mark this as a prototype PTE */ 274 NewPte->u.Proto.Prototype = 1; 275 276 ASSERT(MiProtoPteToPte(NewPte) == PointerPte); 277 } 278 279 VOID 280 FORCEINLINE 281 MmInitGlobalKernelPageDirectory(VOID) 282 { 283 /* Nothing to do */ 284 } 285 286