miia64.h
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 90k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /*++
  2. Copyright (c) 1990  Microsoft Corporation
  3. Copyright (c) 1995  Intel Corporation
  4. Module Name:
  5.     miia64.h
  6. Abstract:
  7.     This module contains the private data structures and procedure
  8.     prototypes for the hardware dependent portion of the
  9.     memory management system.
  10.     This module is specifically tailored for the Intel MERCED,
  11. Author:
  12.     Lou Perazzoli (loup) 6-Jan-1990
  13. Revision History:
  14. --*/
  15. /*++
  16.     Virtual Memory Layout on MERCED is:
  17. /*++
  18.     Virtual Memory Layout for the initial Merced port is:
  19.                  +------------------------------------+
  20. 0000000000000000 | User mode addresses - 8tb minus 8gb| UADDRESS_BASE
  21.                  |                                    |
  22.                  |                                    |
  23. 000003FFFFFEFFFF |                                    | MM_HIGHEST_USER_ADDRESS
  24.                  +------------------------------------+
  25. 000003FFFFFF0000 | 64k No Access Region               | MM_USER_PROBE_ADDRESS
  26.                  +------------------------------------+
  27. 0000040000000000 | HyperSpace - working set lists     | HYPER_SPACE
  28.                  |  and per process memory management |
  29.                  |  structures mapped in this 8gb     |
  30. 00000401FFFFFFFF |  region.                           | HYPER_SPACE_END
  31.                  +------------------------------------+
  32. 0000040200000000 | Remaining per process addresses for|
  33.                  | eventual 43-bit address space.     |
  34.                  |                                    |
  35.                  |                                    |
  36. 000007FFFFFFFFFF |                                    |
  37.                  +------------------------------------+
  38.                                    .
  39.                                    .
  40.                  +------------------------------------+
  41. 1FFFFF0000000000 | 8gb leaf level page table map      | PTE_UBASE
  42.                  |        for user space              |
  43. 1FFFFF01FFFFFFFF |                                    | PTE_UTOP
  44.                  +------------------------------------+
  45.                  +------------------------------------+
  46. 1FFFFFFFC0000000 | 8mb page directory (2nd level)     | PDE_UBASE
  47.                  | table map for user space           |
  48. 1FFFFFFFC07FFFFF |                                    | PDE_UTOP
  49.                  +------------------------------------+
  50.                  +------------------------------------+
  51. 1FFFFFFFFFF00000 | 8KB parent directory (1st level)   | PDE_UTBASE
  52.                  +------------------------------------+
  53.                                    .
  54.                                    .
  55.                  +------------------------------------+
  56. 2000000000000000 |  Hydra - 8gb                       | MM_SESSION_SPACE_DEFAULT
  57.                  |  and per process memory management |
  58.                  |  structures mapped in this 8gb     |
  59.                  |  region.                           |
  60.                  +------------------------------------+
  61.                                    .
  62.                  +------------------------------------+
  63. 3FFFFF0000000000 | 8gb leaf level page table map      | PTE_SBASE
  64.                  |        for session space           |
  65. 3FFFFF01FFFFFFFF |                                    | PTE_STOP
  66.                  +------------------------------------+
  67.                  +------------------------------------+
  68. 3FFFFFFFC0000000 | 8mb page directory (2nd level)     | PDE_SBASE
  69.                  | table map for session space        |
  70. 3FFFFFFFC07FFFFF |                                    | PDE_STOP
  71.                  +------------------------------------+
  72.                  +------------------------------------+
  73. 3FFFFFFFFFF00000 | 8KB parent directory (1st level)   | PDE_STBASE
  74.                  +------------------------------------+
  75.                                    .
  76.                  +------------------------------------+ 
  77. 8000000000000000 |   physical addressable memory      | KSEG3_BASE
  78.                  |   for 44-bit of address space      | 
  79. 80000FFFFFFFFFFF |   mapped by VHPT 64KB page         | KSEG3_LIMIT
  80.                  +------------------------------------+
  81.                                    .
  82.                  +------------------------------------+
  83. 9FFFFF00000000000| vhpt 64kb page for KSEG3 space     |
  84.                  |            (not used)              |
  85.                  +------------------------------------+
  86.                                    .
  87.                                    .
  88.                  +------------------------------------+ MM_SYSTEM_RANGE_START
  89. E000000000000000 |                                    | KADDRESS_BASE
  90.                  +------------------------------------+
  91. E000000080000000 | The HAL, kernel, initial drivers,  | KSEG0_BASE
  92.                  | NLS data, and registry load in the |
  93.                  | first 16mb of this region which    |
  94.                  | physically addresses memory.       |
  95.                  |                                    |
  96.                  | Kernel mode access only.           |
  97.                  |                                    |
  98.                  | Initial NonPaged Pool is within    |
  99.                  | KSEG0                              |
  100.                  |                                    | KSEG2_BASE
  101.                  +------------------------------------+
  102. E0000000A0000000 | System mapped views                | MM_SYSTEM_VIEW_START
  103.                  |   Win32k.sys                       |     MM_SYSTEM_CACHE_END
  104.                  |                                    |
  105.                  +------------------------------------+
  106. E0000000FF000000 | Shared system page                 | KI_USER_SHARED_DATA
  107.                  +------------------------------------+
  108. E0000000FF002000 |   Reserved for the HAL.            |
  109.                  |                                    |
  110.                  |                                    |
  111. E0000000FFFFFFFF |                                    | 
  112.                  +------------------------------------+
  113.                                    .
  114.                                    .
  115.                  +------------------------------------+
  116. E000000200000000 |                                    |
  117.                  |                                    |
  118.                  |                                    |
  119.                  |                                    |
  120.                  +------------------------------------+
  121. E000000400000000 |   The system cache working set     | MM_SYSTEM_CACHE_WORKING_SET
  122.                  |                                    | MM_SYSTEM_SPACE_START
  123.                  |   information resides in this 8gb  |
  124.                  |   region.                          |
  125.                  +------------------------------------+
  126. E000000600000000 | System cache resides here.         | MM_SYSTEM_CACHE_START
  127.                  |  Kernel mode access only.          |
  128.                  |  1tb.                              |
  129.                  +------------------------------------+
  130. E000010600000000 | Start of paged system area.        | MM_PAGED_POOL_START
  131.                  |  Kernel mode access only.          |
  132.                  |  128gb.                            |
  133.                  +------------------------------------+
  134.                  |                                    |
  135.                                    .
  136.                                    .
  137. In general, the next two areas (system PTE pool and nonpaged pool) will both
  138. be shifted upwards to conserve a PPE...
  139.                                    .
  140.                                    .
  141.                  +------------------------------------+
  142. E000012600000000 | System PTE pool.                   | MM_LOWEST_NONPAGED_SYSTEM_START
  143.                  |  Kernel mode access only.          |
  144.                  |  128gb.                            |
  145.                  +------------------------------------+
  146. E000014600000000 | NonPaged pool.                     | MM_NON_PAGED_POOL_START
  147.                  |  Kernel mode access only.          |
  148.                  |  128gb.                            |
  149.                  |                                    |
  150. E0000165FFFFFFFF |  NonPaged System area              | MM_NONPAGED_POOL_END
  151.                  +------------------------------------+ 
  152.                                    .
  153.                                    .
  154. E000040000000000 +------------------------------------+ MM_PFN_DATABASE_START
  155.                  | PFN Database space                 |
  156.                  |  Kernel mode access only.          |
  157.                  |  2tb.                              |
  158. E000060000000000 +------------------------------------+ MM_PFN_DATABASE_END
  159.                                    .                    MM_SYSTEM_SPACE_END
  160.                                    .
  161.                                    .
  162.                  +------------------------------------+
  163. FFFFFF0000000000 | 8gb leaf level page table map      | PTE_KBASE
  164.                  |       for kernel space             |
  165. FFFFFF01FFFFFFFF |                                    | PTE_KTOP
  166.                  +------------------------------------+
  167.                  +------------------------------------+
  168. FFFFFFFFC0000000 | 8mb page directory (2nd level)     | PDE_KBASE
  169.                  | table map for kernel space         |
  170. FFFFFFFFC07FFFFF |                                    | PDE_KTOP
  171.                  +------------------------------------+
  172.                  +------------------------------------+
  173. FFFFFFFFFFF00000 | 8KB parent directory (1st level)   | PDE_KTBASE
  174.                  +------------------------------------+
  175. --*/
  176. #define _MM64_ 1
  177. #define _MIALT4K_ 1
  178. // #define HYPERMAP 1
  179. //
  180. // Define empty list markers.
  181. //
  182. #define MM_EMPTY_LIST ((ULONG)0xFFFFFFFF) //
  183. #define MM_EMPTY_PTE_LIST ((ULONG)0xFFFFFFFF) // N.B. tied to MMPTE definition
  184. #define MI_PTE_BASE_FOR_LOWEST_KERNEL_ADDRESS ((PMMPTE)PTE_KBASE)
  185. //
  186. // 43-Bit virtual address mask.
  187. //
  188. #define MASK_43 0x7FFFFFFFFFFUI64       //
  189. //
  190. // 44-Bit Physical address mask.
  191. //
  192. #define MASK_44 0xFFFFFFFFFFFUI64       
  193. #define MM_PAGES_IN_KSEG0 ((ULONG)((KSEG2_BASE - KSEG0_BASE) >> PAGE_SHIFT))
  194. extern ULONG_PTR MmKseg2Frame;
  195. extern ULONGLONG MmPageSizeInfo;
  196. #define MM_USER_ADDRESS_RANGE_LIMIT (0xFFFFFFFFFFFFFFFFUI64) // user address range limit
  197. #define MM_MAXIMUM_ZERO_BITS 53         // maximum number of zero bits
  198. //
  199. // PAGE_SIZE for Intel MERCED is 8k, virtual page is 20 bits with a PAGE_SHIFT
  200. // byte offset.
  201. //
  202. #define MM_VIRTUAL_PAGE_FILLER (PAGE_SHIFT - 12)
  203. #define MM_VIRTUAL_PAGE_SIZE (64-PAGE_SHIFT)
  204. //
  205. // Address space layout definitions.
  206. //
  207. #define CODE_START KSEG0_BASE
  208. #define CODE_END   KSEG2_BASE
  209. #define MM_SYSTEM_SPACE_START (KADDRESS_BASE + 0x400000000UI64)
  210. #define MM_SYSTEM_SPACE_END (KADDRESS_BASE + 0x60000000000UI64)
  211. #define PDE_TOP PDE_UTOP
  212. //
  213. // Define Althernate 4KB permission table space for X86
  214. //
  215. #define ALT4KB_PERMISSION_TABLE_START (UADDRESS_BASE + 0x40000000000)
  216. #define ALT4KB_PERMISSION_TABLE_END   (UADDRESS_BASE + 0x40000400000)
  217. //
  218. // Define hyper space 
  219. //
  220. #define HYPER_SPACE ((PVOID)(UADDRESS_BASE + 0x40000800000))
  221. #define HYPER_SPACE_END (UADDRESS_BASE + 0x401FFFFFFFF)
  222. //
  223. // Define area for mapping views into system space
  224. //
  225. #define MM_SYSTEM_VIEW_START (KADDRESS_BASE + 0xA0000000)
  226. #define MM_SYSTEM_VIEW_SIZE (48*1024*1024)
  227. #define MM_SESSION_SPACE_DEFAULT (0x2000000000000000UI64)  // make it the region 1 space
  228. #define MM_SYSTEM_VIEW_START_IF_HYDRA MM_SYSTEM_VIEW_START
  229. #define MM_SYSTEM_VIEW_SIZE_IF_HYDRA MM_SYSTEM_VIEW_SIZE
  230. //
  231. // Define the start and maximum size for the system cache.
  232. // Maximum size 512MB.
  233. //
  234. #define MM_SYSTEM_CACHE_WORKING_SET (KADDRESS_BASE + 0x400000000UI64)
  235. #define MM_SYSTEM_CACHE_START (KADDRESS_BASE + 0x600000000UI64)
  236. #define MM_SYSTEM_CACHE_END (KADDRESS_BASE + 0x1005FFFFFFFFUI64)
  237. #define MM_MAXIMUM_SYSTEM_CACHE_SIZE     
  238.    (((ULONG_PTR)MM_SYSTEM_CACHE_END - (ULONG_PTR)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT)
  239. #define MM_PAGED_POOL_START ((PVOID)(KADDRESS_BASE + 0x10600000000UI64))
  240. #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)(KADDRESS_BASE + 0x12600000000UI64))
  241. #define MmProtopte_Base (KADDRESS_BASE)
  242. #define MM_NONPAGED_POOL_END ((PVOID)(KADDRESS_BASE + 0x16600000000UI64 - (16 * PAGE_SIZE)))
  243. #define MM_CRASH_DUMP_VA ((PVOID)(KADDRESS_BASE + 0xFF800000))
  244. // EPC VA at 0xFFA00000 (see ntia64.h)
  245. #define MM_DEBUG_VA  ((PVOID)(KADDRESS_BASE + 0xFF900000))
  246. #define NON_PAGED_SYSTEM_END   (KADDRESS_BASE + 0x16600000000UI64)  //quadword aligned.
  247. #define MM_PFN_DATABASE_START (KADDRESS_BASE + 0x40000000000UI64)
  248. #define MM_PFN_DATABASE_END (KADDRESS_BASE + 0x60000000000UI64)
  249. extern ULONG MiMaximumSystemCacheSize;
  250. //
  251. // Define absolute minumum and maximum count for system ptes.
  252. //
  253. #define MM_MINIMUM_SYSTEM_PTES 7000
  254. #define MM_MAXIMUM_SYSTEM_PTES 50000
  255. #define MM_DEFAULT_SYSTEM_PTES 11000
  256. //
  257. // Pool limits
  258. //
  259. //
  260. // The maximim amount of nonpaged pool that can be initially created.
  261. //
  262. #define MM_MAX_INITIAL_NONPAGED_POOL ((SIZE_T)(128 * 1024 * 1024))
  263. //
  264. // The total amount of nonpaged pool (initial pool + expansion + system PTEs).
  265. //
  266. #define MM_MAX_ADDITIONAL_NONPAGED_POOL (((SIZE_T)128 * 1024 * 1024 * 1024) - 16)
  267. //
  268. // The maximum amount of paged pool that can be created.
  269. //
  270. #define MM_MAX_PAGED_POOL ((SIZE_T)128 * 1024 * 1024 * 1024)
  271. //
  272. // Define the maximum default for pool (user specified 0 in registry).
  273. //
  274. #define MM_MAX_DEFAULT_NONPAGED_POOL ((SIZE_T)8 * 1024 * 1024 * 1024)
  275. //
  276. // Structure layout defintions.
  277. //
  278. #define MM_PROTO_PTE_ALIGNMENT ((ULONG)PAGE_SIZE)
  279. //
  280. // Define the address bits mapped by PPE and PDE entries.
  281. //
  282. // A PPE entry maps 10+10+13 = 33 bits of address space.
  283. // A PDE entry maps 10+13 = 23 bits of address space.
  284. //
  285. #define PAGE_DIRECTORY1_MASK (((ULONG_PTR)1 << PDI1_SHIFT) - 1)
  286. #define PAGE_DIRECTORY2_MASK (((ULONG_PTR)1 << PDI_SHIFT) -1)
  287. #define MM_VA_MAPPED_BY_PDE ((ULONG_PTR)1 << PDI_SHIFT)
  288. #define LOWEST_IO_ADDRESS 0xa0000
  289. //
  290. // The number of bits in a physical address.
  291. //
  292. #define PHYSICAL_ADDRESS_BITS 44
  293. #define MM_MAXIMUM_NUMBER_OF_COLORS (1)
  294. //
  295. // MERCED does not require support for colored pages.
  296. //
  297. #define MM_NUMBER_OF_COLORS (1)
  298. //
  299. // Mask for obtaining color from a physical page number.
  300. //
  301. #define MM_COLOR_MASK (0)
  302. //
  303. // Boundary for aligned pages of like color upon.
  304. //
  305. #define MM_COLOR_ALIGNMENT (0)
  306. //
  307. // Mask for isolating color from virtual address.
  308. //
  309. #define MM_COLOR_MASK_VIRTUAL (0)
  310. //
  311. //  Define 256k worth of secondary colors.
  312. //
  313. #define MM_SECONDARY_COLORS_DEFAULT (64)
  314. #define MM_SECONDARY_COLORS_MIN (2)
  315. #define MM_SECONDARY_COLORS_MAX (1024)
  316. //
  317. // Mask for isolating secondary color from physical page number;
  318. //
  319. extern ULONG MmSecondaryColorMask;
  320. //
  321. // Maximum number of paging files.
  322. //
  323. #define MAX_PAGE_FILES 16
  324. //
  325. // Hyper space definitions.
  326. //
  327. #define FIRST_MAPPING_PTE   ((PMMPTE)HYPER_SPACE)
  328. #define NUMBER_OF_MAPPING_PTES 255
  329. #define LAST_MAPPING_PTE   
  330.      ((ULONG_PTR)((ULONG_PTR)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE)))
  331. #define IMAGE_MAPPING_PTE   ((PMMPTE)((ULONG_PTR)LAST_MAPPING_PTE + PAGE_SIZE))
  332. #define ZEROING_PAGE_PTE    ((PMMPTE)((ULONG_PTR)IMAGE_MAPPING_PTE + PAGE_SIZE))
  333. #define WORKING_SET_LIST   ((PVOID)((ULONG_PTR)ZEROING_PAGE_PTE + PAGE_SIZE))
  334. #define MM_MAXIMUM_WORKING_SET 
  335.        ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb
  336. #define MM_WORKING_SET_END (UADDRESS_BASE + 0x3FFFFFFFFFFUI64)
  337. //
  338. // Define memory attributes fields within PTE
  339. //
  340. #define MM_PTE_TB_MA_WB         (0x0 << 2) // cacheable, write-back
  341. #define MM_PTE_TB_MA_UC         (0x4 << 2) // uncheable
  342. #define MM_PTE_TB_MA_UCE        (0x5 << 2) // uncheable, exporting fetchadd
  343. #define MM_PTE_TB_MA_WC         (0x6 << 2) // uncheable, coalesing
  344. #define MM_PTE_TB_MA_NATPAGE    (0x7 << 2) // Nat Page
  345. //
  346. // Define masks for the PTE cache attributes
  347. //
  348. #define MM_PTE_CACHE_ENABLED     0     // WB
  349. #define MM_PTE_CACHE_DISABLED    4     // UC
  350. #define MM_PTE_CACHE_DISPLAY     6     // WC
  351. #define MM_PTE_CACHE_RESERVED    1     // special encoding to cause a TLB miss
  352. //
  353. // Define masks for fields within the PTE.
  354. //
  355. #define MM_PTE_OWNER_MASK         0x0180
  356. #define MM_PTE_VALID_MASK         1
  357. #define MM_PTE_CACHE_DISABLE_MASK MM_PTE_TB_MA_UC
  358. #define MM_PTE_ACCESS_MASK        0x0020
  359. #define MM_PTE_DIRTY_MASK         0x0040
  360. #define MM_PTE_EXECUTE_MASK       0x0200
  361. #define MM_PTE_WRITE_MASK         0x0400
  362. #define MM_PTE_LARGE_PAGE_MASK    0
  363. #define MM_PTE_COPY_ON_WRITE_MASK ((ULONG)1 << (PAGE_SHIFT-1))
  364. #define MM_PTE_PROTOTYPE_MASK     0x0002
  365. #define MM_PTE_TRANSITION_MASK    0x0080
  366. //
  367. // Bit fields to or into PTE to make a PTE valid based on the
  368. // protection field of the invalid PTE.
  369. //
  370. #define MM_PTE_NOACCESS          0x0
  371. #define MM_PTE_READONLY          0x0
  372. #define MM_PTE_READWRITE         MM_PTE_WRITE_MASK
  373. #define MM_PTE_WRITECOPY         MM_PTE_COPY_ON_WRITE_MASK
  374. #define MM_PTE_EXECUTE           MM_PTE_EXECUTE_MASK
  375. #define MM_PTE_EXECUTE_READ      MM_PTE_EXECUTE_MASK
  376. #define MM_PTE_EXECUTE_READWRITE MM_PTE_EXECUTE_MASK | MM_PTE_WRITE_MASK
  377. #define MM_PTE_EXECUTE_WRITECOPY MM_PTE_EXECUTE_MASK | MM_PTE_COPY_ON_WRITE_MASK
  378. #define MM_PTE_GUARD             0x0
  379. #define MM_PTE_CACHE             MM_PTE_TB_MA_WB
  380. #define MM_PTE_NOCACHE           MM_PTE_CACHE     // PAGE_NOCACHE is cached
  381. #define MM_PTE_EXC_DEFER         0x10000000000000 // defer exception
  382. #define MM_PROTECT_FIELD_SHIFT 2
  383. //
  384. // Define masks for fields within the EM TB entry
  385. //
  386. #define MM_PTE_TB_VALID          0x0001
  387. #define MM_PTE_TB_ACCESSED       0x0020
  388. #define MM_PTE_TB_MODIFIED       0x0040
  389. #define MM_PTE_TB_WRITE          0x0400
  390. #define MM_PTE_TB_EXECUTE        0x0200  // read/execute on EM
  391. #define MM_PTE_TB_EXC_DEFER      0x10000000000000 // defer exception
  392. //
  393. // Define masks for PTE PageSize field
  394. //
  395. #define MM_PTE_1MB_PAGE          20
  396. #define MM_PTE_2MB_PAGE          21
  397. #define MM_PTE_4MB_PAGE          22
  398. #define MM_PTE_16MB_PAGE         24
  399. #define MM_PTE_64MB_PAGE         26
  400. #define MM_PTE_256MB_PAGE        28
  401. //
  402. // Define the number of VHPT pages
  403. //
  404. #define MM_VHPT_PAGES           32
  405. //
  406. // Bits available for the software working set index within the hardware PTE.
  407. //
  408. #define MI_MAXIMUM_PTE_WORKING_SET_INDEX (1 << _HARDWARE_PTE_WORKING_SET_BITS)
  409. //
  410. // Zero PTE
  411. //
  412. #define MM_ZERO_PTE 0
  413. //
  414. // Zero Kernel PTE
  415. //
  416. #define MM_ZERO_KERNEL_PTE 0
  417. //
  418. // A demand zero PTE with a protection or PAGE_READWRITE.
  419. //
  420. #define MM_DEMAND_ZERO_WRITE_PTE ((ULONGLONG)MM_READWRITE << MM_PROTECT_FIELD_SHIFT)
  421. //
  422. // A demand zero PTE with a protection or PAGE_READWRITE for system space.
  423. //
  424. #define MM_KERNEL_DEMAND_ZERO_PTE ((ULONGLONG)MM_READWRITE << MM_PROTECT_FIELD_SHIFT)
  425. //
  426. // A no access PTE for system space.
  427. //
  428. #define MM_KERNEL_NOACCESS_PTE ((ULONGLONG)MM_NOACCESS << MM_PROTECT_FIELD_SHIFT)
  429. extern ULONG_PTR MmPteGlobal; // One if processor supports Global Page, else zero.
  430. //
  431. // Kernel stack alignment requirements.
  432. //
  433. #define MM_STACK_ALIGNMENT 0x0
  434. #define MM_STACK_OFFSET 0x0
  435. //
  436. // System process definitions
  437. //
  438. #define PDE_PER_PAGE ((ULONG)(PAGE_SIZE/(1 << PTE_SHIFT)))
  439.  
  440. #define PTE_PER_PAGE ((ULONG)(PAGE_SIZE/(1 << PTE_SHIFT)))
  441. #define PTE_PER_PAGE_BITS 11    // This handles the case where the page is full
  442. #if PTE_PER_PAGE_BITS > 32
  443. error - too many bits to fit into MMPTE_SOFTWARE or MMPFN.u1
  444. #endif
  445. //
  446. // Number of page table pages for user addresses.
  447. //
  448. #define MM_USER_PAGE_TABLE_PAGES PTE_PER_PAGE
  449. //++
  450. //VOID
  451. //MI_MAKE_VALID_PTE (
  452. //    OUT OUTPTE,
  453. //    IN FRAME,
  454. //    IN PMASK,
  455. //    IN PPTE
  456. //    );
  457. //
  458. // Routine Description:
  459. //
  460. //    This macro makes a valid PTE from a page frame number, protection mask,
  461. //    and owner.
  462. //
  463. // Argments
  464. //
  465. //    OUTPTE - Supplies the PTE in which to build the transition PTE.
  466. //
  467. //    FRAME - Supplies the page frame number for the PTE.
  468. //
  469. //    PMASK - Supplies the protection to set in the transition PTE.
  470. //
  471. //    PPTE - Supplies a pointer to the PTE which is being made valid.
  472. //           For prototype PTEs NULL should be specified.
  473. //
  474. // Return Value:
  475. //
  476. //     None.
  477. //
  478. //--
  479. #if !defined(_MIALT4K_)
  480. #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE)                            
  481.        (OUTPTE).u.Long = 0;                                                   
  482.        (OUTPTE).u.Hard.Valid = 1;                                             
  483.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                          
  484.        (OUTPTE).u.Hard.Accessed = 1;                                          
  485.        (OUTPTE).u.Hard.Exception = 1;                                         
  486.        (OUTPTE).u.Hard.PageFrameNumber = FRAME;                               
  487.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                      
  488.        (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]);
  489. #endif
  490. //++
  491. //VOID
  492. //MI_MAKE_VALID_PTE_TRANSITION (
  493. //    IN OUT OUTPTE
  494. //    IN PROTECT
  495. //    );
  496. //
  497. // Routine Description:
  498. //
  499. //    This macro takes a valid pte and turns it into a transition PTE.
  500. //
  501. // Argments
  502. //
  503. //    OUTPTE - Supplies the current valid PTE.  This PTE is then
  504. //             modified to become a transition PTE.
  505. //
  506. //    PROTECT - Supplies the protection to set in the transition PTE.
  507. //
  508. // Return Value:
  509. //
  510. //     None.
  511. //
  512. //--
  513. #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) 
  514.                 (OUTPTE).u.Soft.Transition = 1;           
  515.                 (OUTPTE).u.Soft.Valid = 0;                
  516.                 (OUTPTE).u.Soft.Prototype = 0;            
  517.                 (OUTPTE).u.Soft.Protection = PROTECT;
  518. //++
  519. //VOID
  520. //MI_MAKE_TRANSITION_PTE (
  521. //    OUT OUTPTE,
  522. //    IN PAGE,
  523. //    IN PROTECT,
  524. //    IN PPTE
  525. //    );
  526. //
  527. // Routine Description:
  528. //
  529. //    This macro takes a valid pte and turns it into a transition PTE.
  530. //
  531. // Argments
  532. //
  533. //    OUTPTE - Supplies the PTE in which to build the transition PTE.
  534. //
  535. //    PAGE - Supplies the page frame number for the PTE.
  536. //
  537. //    PROTECT - Supplies the protection to set in the transition PTE.
  538. //
  539. //    PPTE - Supplies a pointer to the PTE, this is used to determine
  540. //           the owner of the PTE.
  541. //
  542. // Return Value:
  543. //
  544. //     None.
  545. //
  546. //--
  547. #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE)   
  548.                 (OUTPTE).u.Long = 0;                       
  549.                 (OUTPTE).u.Trans.PageFrameNumber = PAGE;   
  550.                 (OUTPTE).u.Trans.Transition = 1;           
  551.                 (OUTPTE).u.Trans.Protection = PROTECT;
  552. //++
  553. //VOID
  554. //MI_MAKE_TRANSITION_PTE_VALID (
  555. //    OUT OUTPTE,
  556. //    IN PPTE
  557. //    );
  558. //
  559. // Routine Description:
  560. //
  561. //    This macro takes a transition pte and makes it a valid PTE.
  562. //
  563. // Argments
  564. //
  565. //    OUTPTE - Supplies the PTE in which to build the valid PTE.
  566. //
  567. //    PPTE - Supplies a pointer to the transition PTE.
  568. //
  569. // Return Value:
  570. //
  571. //     None.
  572. //
  573. //--
  574. #if !defined(_MIALT4K_)
  575. #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE)                             
  576.         ASSERT (((PPTE)->u.Hard.Valid == 0) &&                                
  577.                 ((PPTE)->u.Trans.Prototype == 0) &&                           
  578.                 ((PPTE)->u.Trans.Transition == 1));                           
  579.        (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000;                     
  580.        (OUTPTE).u.Hard.Valid = 1;                                             
  581.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                          
  582.        (OUTPTE).u.Hard.Accessed = 1;                                          
  583.        (OUTPTE).u.Hard.Exception = 1;                                         
  584.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                      
  585.        (OUTPTE).u.Long |= (MmProtectToPteMask[(PPTE)->u.Trans.Protection]);
  586. #endif
  587. //++
  588. //VOID
  589. //MI_SET_PTE_IN_WORKING_SET (
  590. //    OUT PMMPTE PTE,
  591. //    IN ULONG WSINDEX
  592. //    );
  593. //
  594. // Routine Description:
  595. //
  596. //    This macro inserts the specified working set index into the argument PTE.
  597. //
  598. //    No TB invalidation is needed for other processors (or this one) even
  599. //    though the entry may already be in a TB - it's just a software field
  600. //    update and doesn't affect miss resolution.
  601. //
  602. // Arguments
  603. //
  604. //    OUTPTE - Supplies the PTE in which to insert the working set index.
  605. //
  606. //    WSINDEX - Supplies the working set index for the PTE.
  607. //
  608. // Return Value:
  609. //
  610. //     None.
  611. //
  612. //--
  613. #define MI_SET_PTE_IN_WORKING_SET(PTE, WSINDEX) {             
  614.     MMPTE _TempPte;                                           
  615.     _TempPte = *(PTE);                                        
  616.     _TempPte.u.Hard.SoftwareWsIndex = (WSINDEX);              
  617.     *(PTE) = _TempPte;                                        
  618. }
  619. //++
  620. //ULONG WsIndex
  621. //MI_GET_WORKING_SET_FROM_PTE(
  622. //    IN PMMPTE PTE
  623. //    );
  624. //
  625. // Routine Description:
  626. //
  627. //    This macro returns the working set index from the argument PTE.
  628. //
  629. // Arguments
  630. //
  631. //    PTE - Supplies the PTE to extract the working set index from.
  632. //
  633. // Return Value:
  634. //
  635. //    This macro returns the working set index for the argument PTE.
  636. //
  637. //--
  638. #define MI_GET_WORKING_SET_FROM_PTE(PTE)  (ULONG)(PTE)->u.Hard.SoftwareWsIndex
  639. //++
  640. //VOID
  641. //MI_SET_PTE_WRITE_COMBINE (
  642. //    IN MMPTE PTE
  643. //    );
  644. //
  645. // Routine Description:
  646. //
  647. //    This macro sets the write combined bit(s) in the specified PTE.
  648. //
  649. // Arguments
  650. //
  651. //    PTE - Supplies the PTE to set dirty.
  652. //
  653. // Return Value:
  654. //
  655. //     None.
  656. //
  657. //--
  658. #define MI_SET_PTE_WRITE_COMBINE(PTE)  
  659.     ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISABLED)
  660. #define MI_SET_PTE_WRITE_COMBINE2(PTE)  
  661.     ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISPLAY)
  662. //++
  663. //VOID
  664. //MI_SET_PTE_DIRTY (
  665. //    IN MMPTE PTE
  666. //    );
  667. //
  668. // Routine Description:
  669. //
  670. //    This macro sets the dirty bit(s) in the specified PTE.
  671. //
  672. // Argments
  673. //
  674. //    PTE - Supplies the PTE to set dirty.
  675. //
  676. // Return Value:
  677. //
  678. //     None.
  679. //
  680. //--
  681. #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Hard.Dirty = 1
  682. //++
  683. //VOID
  684. //MI_SET_PTE_CLEAN (
  685. //    IN MMPTE PTE
  686. //    );
  687. //
  688. // Routine Description:
  689. //
  690. //    This macro clears the dirty bit(s) in the specified PTE.
  691. //
  692. // Argments
  693. //
  694. //    PTE - Supplies the PTE to set clear.
  695. //
  696. // Return Value:
  697. //
  698. //     None.
  699. //
  700. //--
  701. #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Hard.Dirty = 0
  702. //++
  703. //VOID
  704. //MI_IS_PTE_DIRTY (
  705. //    IN MMPTE PTE
  706. //    );
  707. //
  708. // Routine Description:
  709. //
  710. //    This macro checks the dirty bit(s) in the specified PTE.
  711. //
  712. // Argments
  713. //
  714. //    PTE - Supplies the PTE to check.
  715. //
  716. // Return Value:
  717. //
  718. //    TRUE if the page is dirty (modified), FALSE otherwise.
  719. //
  720. //--
  721. #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != 0)
  722. //++
  723. //VOID
  724. //MI_SET_GLOBAL_BIT_IF_SYSTEM (
  725. //    OUT OUTPTE,
  726. //    IN PPTE
  727. //    );
  728. //
  729. // Routine Description:
  730. //
  731. //    This macro sets the global bit if the pointer PTE is within
  732. //    system space.
  733. //
  734. // Argments
  735. //
  736. //    OUTPTE - Supplies the PTE in which to build the valid PTE.
  737. //
  738. //    PPTE - Supplies a pointer to the PTE becoming valid.
  739. //
  740. // Return Value:
  741. //
  742. //     None.
  743. //
  744. //--
  745. #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE)
  746. //++
  747. //VOID
  748. //MI_SET_GLOBAL_STATE (
  749. //    IN MMPTE PTE,
  750. //    IN ULONG STATE
  751. //    );
  752. //
  753. // Routine Description:
  754. //
  755. //    This macro sets the global bit in the PTE. if the pointer PTE is within
  756. //
  757. // Argments
  758. //
  759. //    PTE - Supplies the PTE to set global state into.
  760. //
  761. //    STATE - Supplies 1 if global, 0 if not.
  762. //
  763. // Return Value:
  764. //
  765. //     None.
  766. //
  767. //--
  768. #define MI_SET_GLOBAL_STATE(PTE,STATE)
  769. //++
  770. //VOID
  771. //MI_ENABLE_CACHING (
  772. //    IN MMPTE PTE
  773. //    );
  774. //
  775. // Routine Description:
  776. //
  777. //    This macro takes a valid PTE and sets the caching state to be
  778. //    enabled.
  779. //
  780. // Argments
  781. //
  782. //    PTE - Supplies a valid PTE.
  783. //
  784. // Return Value:
  785. //
  786. //     None.
  787. //
  788. //--
  789. #define MI_ENABLE_CACHING(PTE) ((PTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED)
  790. //++
  791. //VOID
  792. //MI_DISABLE_CACHING (
  793. //    IN MMPTE PTE
  794. //    );
  795. //
  796. // Routine Description:
  797. //
  798. //    This macro takes a valid PTE and sets the caching state to be
  799. //    disabled.
  800. //
  801. // Argments
  802. //
  803. //    PTE - Supplies a pointer to the valid PTE.
  804. //
  805. // Return Value:
  806. //
  807. //     None.
  808. //
  809. //--
  810. #define MI_DISABLE_CACHING(PTE) ((PTE).u.Hard.Cache = MM_PTE_CACHE_DISABLED)
  811. //++
  812. //BOOLEAN
  813. //MI_IS_CACHING_DISABLED (
  814. //    IN PMMPTE PPTE
  815. //    );
  816. //
  817. // Routine Description:
  818. //
  819. //    This macro takes a valid PTE and returns TRUE if caching is
  820. //    disabled.
  821. //
  822. // Argments
  823. //
  824. //    PPTE - Supplies a pointer to the valid PTE.
  825. //
  826. // Return Value:
  827. //
  828. //     TRUE if caching is disabled, FALSE if it is enabled.
  829. //
  830. //--
  831. #define MI_IS_CACHING_DISABLED(PPTE) 
  832.             ((PPTE)->u.Hard.Cache == MM_PTE_CACHE_DISABLED)
  833. //++
  834. //VOID
  835. //MI_SET_PFN_DELETED (
  836. //    IN PMMPFN PPFN
  837. //    );
  838. //
  839. // Routine Description:
  840. //
  841. //    This macro takes a pointer to a PFN element and indicates that
  842. //    the PFN is no longer in use.
  843. //
  844. // Argments
  845. //
  846. //    PPTE - Supplies a pointer to the PFN element.
  847. //
  848. // Return Value:
  849. //
  850. //    none.
  851. //
  852. //--
  853. #define MI_SET_PFN_DELETED(PPFN) (((PPFN)->PteAddress = (PMMPTE)((INT_PTR)(LONG)0xFFFFFFFF)))
  854. //++
  855. //BOOLEAN
  856. //MI_IS_PFN_DELETED (
  857. //    IN PMMPFN PPFN
  858. //    );
  859. //
  860. // Routine Description:
  861. //
  862. //    This macro takes a pointer to a PFN element a determines if
  863. //    the PFN is no longer in use.
  864. //
  865. // Argments
  866. //
  867. //    PPTE - Supplies a pointer to the PFN element.
  868. //
  869. // Return Value:
  870. //
  871. //     TRUE if PFN is no longer used, FALSE if it is still being used.
  872. //
  873. //--
  874. #define MI_IS_PFN_DELETED(PPFN)   
  875.             ((PPFN)->PteAddress == (PMMPTE)((INT_PTR)(LONG)0xFFFFFFFF))
  876. //++
  877. //VOID
  878. //MI_CHECK_PAGE_ALIGNMENT (
  879. //    IN ULONG PAGE,
  880. //    IN PMMPTE PPTE
  881. //    );
  882. //
  883. // Routine Description:
  884. //
  885. //    This macro takes a PFN element number (Page) and checks to see
  886. //    if the virtual alignment for the previous address of the page
  887. //    is compatable with the new address of the page.  If they are
  888. //    not compatible, the D cache is flushed.
  889. //
  890. // Argments
  891. //
  892. //    PAGE - Supplies the PFN element.
  893. //    PPTE - Supplies a pointer to the new PTE which will contain the page.
  894. //
  895. // Return Value:
  896. //
  897. //    none.
  898. //
  899. //--
  900. // does nothing on MERCED.
  901. #define MI_CHECK_PAGE_ALIGNMENT(PAGE,PPTE)
  902. //++
  903. //VOID
  904. //MI_INITIALIZE_HYPERSPACE_MAP (
  905. //    VOID
  906. //    );
  907. //
  908. // Routine Description:
  909. //
  910. //    This macro initializes the PTEs reserved for double mapping within
  911. //    hyperspace.
  912. //
  913. // Argments
  914. //
  915. //    None.
  916. //
  917. // Return Value:
  918. //
  919. //    None.
  920. //
  921. //--
  922. // does nothing on MERCED.
  923. #define MI_INITIALIZE_HYPERSPACE_MAP(INDEX)
  924. //++
  925. //ULONG
  926. //MI_GET_PAGE_COLOR_FROM_PTE (
  927. //    IN PMMPTE PTEADDRESS
  928. //    );
  929. //
  930. // Routine Description:
  931. //
  932. //    This macro determines the pages color based on the PTE address
  933. //    that maps the page.
  934. //
  935. // Argments
  936. //
  937. //    PTEADDRESS - Supplies the PTE address the page is (or was) mapped at.
  938. //
  939. // Return Value:
  940. //
  941. //    The pages color.
  942. //
  943. //--
  944. #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS)  
  945.          ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask))
  946. //++
  947. //ULONG
  948. //MI_GET_PAGE_COLOR_FROM_VA (
  949. //    IN PVOID ADDRESS
  950. //    );
  951. //
  952. // Routine Description:
  953. //
  954. //    This macro determines the pages color based on the PTE address
  955. //    that maps the page.
  956. //
  957. // Argments
  958. //
  959. //    ADDRESS - Supplies the address the page is (or was) mapped at.
  960. //
  961. // Return Value:
  962. //
  963. //    The pages color.
  964. //
  965. //--
  966. #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS)  
  967.          ((ULONG)((MmSystemPageColor++) & MmSecondaryColorMask))
  968. //++
  969. //ULONG
  970. //MI_GET_PAGE_COLOR_FROM_SESSION (
  971. //    IN PMM_SESSION_SPACE SessionSpace
  972. //    );
  973. //
  974. // Routine Description:
  975. //
  976. //    This macro determines the page's color based on the PTE address
  977. //    that maps the page.
  978. //
  979. // Arguments
  980. //
  981. //    SessionSpace - Supplies the session space the page will be mapped into.
  982. //
  983. // Return Value:
  984. //
  985. //    The page's color.
  986. //
  987. //--
  988. #define MI_GET_PAGE_COLOR_FROM_SESSION(_SessionSpace)  
  989.          ((ULONG)((_SessionSpace->Color++) & MmSecondaryColorMask))
  990. //++
  991. //ULONG
  992. //MI_PAGE_COLOR_PTE_PROCESS (
  993. //    IN PCHAR COLOR,
  994. //    IN PMMPTE PTE
  995. //    );
  996. //
  997. // Routine Description:
  998. //
  999. //    This macro determines the pages color based on the PTE address
  1000. //    that maps the page.
  1001. //
  1002. // Argments
  1003. //
  1004. //
  1005. // Return Value:
  1006. //
  1007. //    The pages color.
  1008. //
  1009. //--
  1010. #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR)  
  1011.          (ULONG)((ULONG_PTR)((*(COLOR))++) & MmSecondaryColorMask)
  1012. //++
  1013. //ULONG
  1014. //MI_PAGE_COLOR_VA_PROCESS (
  1015. //    IN PVOID ADDRESS,
  1016. //    IN PEPROCESS COLOR
  1017. //    );
  1018. //
  1019. // Routine Description:
  1020. //
  1021. //    This macro determines the pages color based on the PTE address
  1022. //    that maps the page.
  1023. //
  1024. // Argments
  1025. //
  1026. //    ADDRESS - Supplies the address the page is (or was) mapped at.
  1027. //
  1028. // Return Value:
  1029. //
  1030. //    The pages color.
  1031. //
  1032. //--
  1033. #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) 
  1034.          ((ULONG)((*(COLOR))++) & MmSecondaryColorMask)
  1035. //++
  1036. //ULONG
  1037. //MI_GET_NEXT_COLOR (
  1038. //    IN ULONG COLOR
  1039. //    );
  1040. //
  1041. // Routine Description:
  1042. //
  1043. //    This macro returns the next color in the sequence.
  1044. //
  1045. // Argments
  1046. //
  1047. //    COLOR - Supplies the color to return the next of.
  1048. //
  1049. // Return Value:
  1050. //
  1051. //    Next color in sequence.
  1052. //
  1053. //--
  1054. #define MI_GET_NEXT_COLOR(COLOR)  ((COLOR + 1) & MM_COLOR_MASK)
  1055. //++
  1056. //ULONG
  1057. //MI_GET_PREVIOUS_COLOR (
  1058. //    IN ULONG COLOR
  1059. //    );
  1060. //
  1061. // Routine Description:
  1062. //
  1063. //    This macro returns the previous color in the sequence.
  1064. //
  1065. // Argments
  1066. //
  1067. //    COLOR - Supplies the color to return the previous of.
  1068. //
  1069. // Return Value:
  1070. //
  1071. //    Previous color in sequence.
  1072. //
  1073. //--
  1074. #define MI_GET_PREVIOUS_COLOR(COLOR)  (0)
  1075. #define MI_GET_SECONDARY_COLOR(PAGE,PFN) ((ULONG)(PAGE & MmSecondaryColorMask))
  1076. #define MI_GET_COLOR_FROM_SECONDARY(SECONDARY_COLOR) (0)
  1077. //++
  1078. //VOID
  1079. //MI_GET_MODIFIED_PAGE_BY_COLOR (
  1080. //    OUT ULONG PAGE,
  1081. //    IN ULONG COLOR
  1082. //    );
  1083. //
  1084. // Routine Description:
  1085. //
  1086. //    This macro returns the first page destined for a paging
  1087. //    file with the desired color.  It does NOT remove the page
  1088. //    from its list.
  1089. //
  1090. // Argments
  1091. //
  1092. //    PAGE - Returns the page located, the value MM_EMPTY_LIST is
  1093. //           returned if there is no page of the specified color.
  1094. //
  1095. //    COLOR - Supplies the color of page to locate.
  1096. //
  1097. // Return Value:
  1098. //
  1099. //    none.
  1100. //
  1101. //--
  1102. #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) 
  1103.             PAGE = MmModifiedPageListByColor[COLOR].Flink
  1104. //++
  1105. //VOID
  1106. //MI_GET_MODIFIED_PAGE_ANY_COLOR (
  1107. //    OUT ULONG PAGE,
  1108. //    IN OUT ULONG COLOR
  1109. //    );
  1110. //
  1111. // Routine Description:
  1112. //
  1113. //    This macro returns the first page destined for a paging
  1114. //    file with the desired color.  If not page of the desired
  1115. //    color exists, all colored lists are searched for a page.
  1116. //    It does NOT remove the page from its list.
  1117. //
  1118. // Argments
  1119. //
  1120. //    PAGE - Returns the page located, the value MM_EMPTY_LIST is
  1121. //           returned if there is no page of the specified color.
  1122. //
  1123. //    COLOR - Supplies the color of page to locate and returns the
  1124. //            color of the page located.
  1125. //
  1126. // Return Value:
  1127. //
  1128. //    none.
  1129. //
  1130. //--
  1131. #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) 
  1132.             {                                                                
  1133.                 if (MmTotalPagesForPagingFile == 0) {                        
  1134.                     PAGE = MM_EMPTY_LIST;                                    
  1135.                 } else {                                                     
  1136.                     PAGE = MmModifiedPageListByColor[COLOR].Flink;           
  1137.                 }                                                            
  1138.             }
  1139. //++
  1140. //VOID
  1141. //MI_MAKE_VALID_PTE_WRITE_COPY (
  1142. //    IN OUT PMMPTE PTE
  1143. //    );
  1144. //
  1145. // Routine Description:
  1146. //
  1147. //    This macro checks to see if the PTE indicates that the
  1148. //    page is writable and if so it clears the write bit and
  1149. //    sets the copy-on-write bit.
  1150. //
  1151. // Argments
  1152. //
  1153. //    PTE - Supplies the PTE to operate upon.
  1154. //
  1155. // Return Value:
  1156. //
  1157. //     None.
  1158. //
  1159. //--
  1160. #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) 
  1161.                     if ((PPTE)->u.Hard.Write == 1) {    
  1162.                         (PPTE)->u.Hard.CopyOnWrite = 1; 
  1163.                         (PPTE)->u.Hard.Write = 0;       
  1164.                     }
  1165. //++
  1166. //ULONG
  1167. //MI_DETERMINE_OWNER (
  1168. //    IN MMPTE PPTE
  1169. //    );
  1170. //
  1171. // Routine Description:
  1172. //
  1173. //    This macro examines the virtual address of the PTE and determines
  1174. //    if the PTE resides in system space or user space.
  1175. //
  1176. // Argments
  1177. //
  1178. //    PTE - Supplies the PTE to operate upon.
  1179. //
  1180. // Return Value:
  1181. //
  1182. //     3 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE.
  1183. //
  1184. //--
  1185. #if defined(_MIALT4K_)
  1186. #define MI_DETERMINE_OWNER(PPTE)   
  1187.      ((((((PPTE) >= (PMMPTE)PTE_UBASE) && ((PPTE) <= MiHighestUserPte))) || 
  1188.        (MI_IS_ALT_PAGE_TABLE_ADDRESS(PPTE))) ? 3 : 0)
  1189. #else
  1190. #define MI_DETERMINE_OWNER(PPTE)   
  1191.     ((((PPTE) >= (PMMPTE)PTE_UBASE) && 
  1192.       ((PPTE) <= MiHighestUserPte)) ? 3 : 0)
  1193. #endif
  1194. //++
  1195. //VOID
  1196. //MI_SET_ACCESSED_IN_PTE (
  1197. //    IN OUT MMPTE PPTE
  1198. //    );
  1199. //
  1200. // Routine Description:
  1201. //
  1202. //    This macro sets the ACCESSED field in the PTE.
  1203. //
  1204. // Argments
  1205. //
  1206. //    PTE - Supplies the PTE to operate upon.
  1207. //
  1208. // Return Value:
  1209. //
  1210. //     1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE.
  1211. //
  1212. //--
  1213. #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED)
  1214. //++
  1215. //ULONG
  1216. //MI_GET_ACCESSED_IN_PTE (
  1217. //    IN OUT MMPTE PPTE
  1218. //    );
  1219. //
  1220. // Routine Description:
  1221. //
  1222. //    This macro returns the state of the ACCESSED field in the PTE.
  1223. //
  1224. // Argments
  1225. //
  1226. //    PTE - Supplies the PTE to operate upon.
  1227. //
  1228. // Return Value:
  1229. //
  1230. //     The state of the ACCESSED field.
  1231. //
  1232. //--
  1233. #define MI_GET_ACCESSED_IN_PTE(PPTE) 0
  1234. //++
  1235. //VOID
  1236. //MI_SET_OWNER_IN_PTE (
  1237. //    IN PMMPTE PPTE
  1238. //    IN ULONG OWNER
  1239. //    );
  1240. //
  1241. // Routine Description:
  1242. //
  1243. //    This macro sets the owner field in the PTE.
  1244. //
  1245. // Argments
  1246. //
  1247. //    PTE - Supplies the PTE to operate upon.
  1248. //
  1249. // Return Value:
  1250. //
  1251. //    None.
  1252. //
  1253. //--
  1254. #define MI_SET_OWNER_IN_PTE(PPTE,OWNER)
  1255. //++
  1256. //ULONG
  1257. //MI_GET_OWNER_IN_PTE (
  1258. //    IN PMMPTE PPTE
  1259. //    );
  1260. //
  1261. // Routine Description:
  1262. //
  1263. //    This macro gets the owner field from the PTE.
  1264. //
  1265. // Argments
  1266. //
  1267. //    PTE - Supplies the PTE to operate upon.
  1268. //
  1269. // Return Value:
  1270. //
  1271. //     The state of the OWNER field.
  1272. //
  1273. //--
  1274. #define MI_GET_OWNER_IN_PTE(PPTE) KernelMode
  1275. //
  1276. // bit mask to clear out fields in a PTE to or in prototype pte offset.
  1277. //
  1278. #define CLEAR_FOR_PROTO_PTE_ADDRESS ((ULONG)0x701)
  1279. //
  1280. // bit mask to clear out fields in a PTE to or in paging file location.
  1281. //
  1282. #define CLEAR_FOR_PAGE_FILE 0x000003E0
  1283. //++
  1284. //VOID
  1285. //MI_SET_PAGING_FILE_INFO (
  1286. //    OUT MMPTE OUTPTE,
  1287. //    IN MMPTE PPTE,
  1288. //    IN ULONG FILEINFO,
  1289. //    IN ULONG OFFSET
  1290. //    );
  1291. //
  1292. // Routine Description:
  1293. //
  1294. //    This macro sets into the specified PTE the supplied information
  1295. //    to indicate where the backing store for the page is located.
  1296. //
  1297. // Argments
  1298. //
  1299. //    OUTPTE - Supplies the PTE in which to store the result.
  1300. //
  1301. //    PTE - Supplies the PTE to operate upon.
  1302. //
  1303. //    FILEINFO - Supplies the number of the paging file.
  1304. //
  1305. //    OFFSET - Supplies the offset into the paging file.
  1306. //
  1307. // Return Value:
  1308. //
  1309. //    None.
  1310. //
  1311. //--
  1312. #define MI_SET_PAGING_FILE_INFO(OUTPTE,PTE,FILEINFO,OFFSET) 
  1313.         (OUTPTE).u.Long = (((PTE).u.Soft.Protection << MM_PROTECT_FIELD_SHIFT) | 
  1314.          ((ULONGLONG)(FILEINFO) << _MM_PAGING_FILE_LOW_SHIFT) | 
  1315.          ((ULONGLONG)(OFFSET) << _MM_PAGING_FILE_HIGH_SHIFT));
  1316. //++
  1317. //PMMPTE
  1318. //MiPteToProto (
  1319. //    IN OUT MMPTE PPTE,
  1320. //    IN ULONG FILEINFO,
  1321. //    IN ULONG OFFSET
  1322. //    );
  1323. //
  1324. // Routine Description:
  1325. //
  1326. //   This macro returns the address of the corresponding prototype which
  1327. //   was encoded earlier into the supplied PTE.
  1328. //
  1329. //    NOTE THAT AS PROTOPTE CAN ONLY RESIDE IN PAGED POOL!!!!!!
  1330. //
  1331. //    MAX SIZE = 2^(2+7+21) = 2^30 = 1GB.
  1332. //
  1333. //    NOTE, that the valid bit must be zero!
  1334. //
  1335. // Argments
  1336. //
  1337. //    lpte - Supplies the PTE to operate upon.
  1338. //
  1339. // Return Value:
  1340. //
  1341. //    Pointer to the prototype PTE that backs this PTE.
  1342. //
  1343. //--
  1344. #define MiPteToProto(lpte) 
  1345.             ((PMMPTE) ((ULONG_PTR)((lpte)->u.Proto.ProtoAddress) + MmProtopte_Base))
  1346. //++
  1347. //ULONG_PTR
  1348. //MiProtoAddressForPte (
  1349. //    IN PMMPTE proto_va
  1350. //    );
  1351. //
  1352. // Routine Description:
  1353. //
  1354. //    This macro sets into the specified PTE the supplied information
  1355. //    to indicate where the backing store for the page is located.
  1356. //    MiProtoAddressForPte returns the bit field to OR into the PTE to
  1357. //    reference a prototype PTE.  And set the protoPTE bit,
  1358. //    MM_PTE_PROTOTYPE_MASK.
  1359. //
  1360. // Argments
  1361. //
  1362. //    proto_va - Supplies the address of the prototype PTE.
  1363. //
  1364. // Return Value:
  1365. //
  1366. //    Mask to set into the PTE.
  1367. //
  1368. //--
  1369. #define MiProtoAddressForPte(proto_va)  
  1370.         (( (ULONGLONG)((ULONG_PTR)proto_va - MmProtopte_Base) <<  
  1371.           (_MM_PROTO_ADDRESS_SHIFT)) | MM_PTE_PROTOTYPE_MASK)
  1372. #define MISetProtoAddressForPte(PTE, proto_va) 
  1373.         (PTE).u.Long = 0;                      
  1374.         (PTE).u.Proto.Prototype = 1;           
  1375.         (PTE).u.Proto.ProtoAddress = (ULONG_PTR)proto_va - MmProtopte_Base;
  1376. //++
  1377. //ULONG_PTR
  1378. //MiProtoAddressForKernelPte (
  1379. //    IN PMMPTE proto_va
  1380. //    );
  1381. //
  1382. // Routine Description:
  1383. //
  1384. //    This macro sets into the specified PTE the supplied information
  1385. //    to indicate where the backing store for the page is located.
  1386. //    MiProtoAddressForPte returns the bit field to OR into the PTE to
  1387. //    reference a prototype PTE.  And set the protoPTE bit,
  1388. //    MM_PTE_PROTOTYPE_MASK.
  1389. //
  1390. //    This macro also sets any other information (such as global bits)
  1391. //    required for kernel mode PTEs.
  1392. //
  1393. // Argments
  1394. //
  1395. //    proto_va - Supplies the address of the prototype PTE.
  1396. //
  1397. // Return Value:
  1398. //
  1399. //    Mask to set into the PTE.
  1400. //
  1401. //--
  1402. //  not different on x86.
  1403. #define MiProtoAddressForKernelPte(proto_va)  MiProtoAddressForPte(proto_va)
  1404. #define MM_SUBSECTION_MAP (128*1024*1024)
  1405. //++
  1406. //PSUBSECTION
  1407. //MiGetSubsectionAddress (
  1408. //    IN PMMPTE lpte
  1409. //    );
  1410. //
  1411. // Routine Description:
  1412. //
  1413. //   This macro takes a PTE and returns the address of the subsection that
  1414. //   the PTE refers to.  Subsections are quadword structures allocated
  1415. //   from nonpaged pool.
  1416. //
  1417. //   NOTE THIS MACRO LIMITS THE SIZE OF NONPAGED POOL!
  1418. //    MAXIMUM NONPAGED POOL = 2^(3+4+21) = 2^28 = 256mb.
  1419. //
  1420. //
  1421. // Argments
  1422. //
  1423. //    lpte - Supplies the PTE to operate upon.
  1424. //
  1425. // Return Value:
  1426. //
  1427. //    A pointer to the subsection referred to by the supplied PTE.
  1428. //
  1429. //--
  1430. #define MiGetSubsectionAddress(lpte)                              
  1431.     (((lpte)->u.Subsect.WhichPool == 1) ?                              
  1432.      ((PSUBSECTION)((ULONG_PTR)MmSubsectionBase +    
  1433.                     ((ULONG_PTR)(lpte)->u.Subsect.SubsectionAddress))) 
  1434.      : 
  1435.      ((PSUBSECTION)((ULONG_PTR)MM_NONPAGED_POOL_END -    
  1436.                     ((ULONG_PTR)(lpte)->u.Subsect.SubsectionAddress))))
  1437. //++
  1438. //ULONGLONG
  1439. //MiGetSubsectionAddressForPte (
  1440. //    IN PSUBSECTION VA
  1441. //    );
  1442. //
  1443. // Routine Description:
  1444. //
  1445. //    This macro takes the address of a subsection and encodes it for use
  1446. //    in a PTE.
  1447. //
  1448. //    NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED!
  1449. //
  1450. // Argments
  1451. //
  1452. //    VA - Supplies a pointer to the subsection to encode.
  1453. //
  1454. // Return Value:
  1455. //
  1456. //     The mask to set into the PTE to make it reference the supplied
  1457. //     subsetion.
  1458. //
  1459. //--
  1460. #define MiGetSubsectionAddressForPte(VA)                   
  1461.    ( ((ULONG_PTR)(VA) < (ULONG_PTR)KSEG2_BASE) ?                  
  1462.      ( ((ULONGLONG)((ULONG_PTR)VA - (ULONG_PTR)MmSubsectionBase) 
  1463.           << (_MM_PTE_SUBSECTION_ADDRESS_SHIFT)) | 0x80) 
  1464.      : 
  1465.        ((ULONGLONG)((ULONG_PTR)MM_NONPAGED_POOL_END - (ULONG_PTR)VA) 
  1466.           << (_MM_PTE_SUBSECTION_ADDRESS_SHIFT)) )
  1467. #define MiSetSubsectionAddressForPte(PTE, VA)  
  1468.    (PTE).u.Long = 0;                          
  1469.    if ((ULONG_PTR)(VA) < (ULONG_PTR)KSEG2_BASE) { 
  1470.        (PTE).u.Subsect.SubsectionAddress = (ULONG_PTR)VA - (ULONG_PTR)MmSubsectionBase; 
  1471.        (PTE).u.Subsect.WhichPool = 1;  
  1472.    } else { 
  1473.        (PTE).u.Subsect.SubsectionAddress = (ULONG_PTR)MM_NONPAGED_POOL_END - (ULONG_PTR)VA; 
  1474.    }
  1475. //++
  1476. //ULONG
  1477. //MiGetPpeOffset (
  1478. //    IN PVOID va
  1479. //    );
  1480. //
  1481. // Routine Description:
  1482. //
  1483. //    MiGetPpeOffset returns the offset into a page root
  1484. //    for a given virtual address.
  1485. //
  1486. // Arguments
  1487. //
  1488. //    Va - Supplies the virtual address to locate the offset for.
  1489. //
  1490. // Return Value:
  1491. //
  1492. //    The offset into the page root table the corresponding PPE is at.
  1493. //
  1494. //    LWFIX: expand for 3-level
  1495. //
  1496. //--
  1497. #define MiGetPpeOffset(va) ((ULONG)(((ULONG_PTR)(va) >> PDI1_SHIFT) & PDI_MASK))
  1498. //++
  1499. //ULONG_PTR
  1500. //MiGetPdeOffset (
  1501. //    IN PVOID va
  1502. //    );
  1503. //
  1504. // Routine Description:
  1505. //
  1506. //    MiGetPdeOffset returns the offset into a page directory
  1507. //    for a given virtual address.
  1508. //
  1509. // Argments
  1510. //
  1511. //    Va - Supplies the virtual address to locate the offset for.
  1512. //
  1513. // Return Value:
  1514. //
  1515. //    The offset into the page directory table the corresponding PDE is at.
  1516. //
  1517. //--
  1518. #define MiGetPdeOffset(va) ((ULONG) (((ULONG_PTR)(va) >> PDI_SHIFT) & PDI_MASK))
  1519. //++
  1520. //ULONG
  1521. //MiGetPpePdeOffset (
  1522. //    IN PVOID va
  1523. //    );
  1524. //
  1525. // Routine Description:
  1526. //
  1527. //    MiGetPpePdeOffset returns the offset into a page directory
  1528. //    for a given virtual address.
  1529. //
  1530. //    N.B. This does not mask off PPE bits.
  1531. //
  1532. // Arguments
  1533. //
  1534. //    Va - Supplies the virtual address to locate the offset for.
  1535. //
  1536. // Return Value:
  1537. //
  1538. //    The offset into the page directory (and parent) table the
  1539. //    corresponding PDE is at.
  1540. //
  1541. //--
  1542. #define MiGetPpePdeOffset(va) ((ULONG) ((ULONG_PTR)(va) >> PDI_SHIFT))
  1543. //++
  1544. //ULONG_PTR
  1545. //MiGetPteOffset (
  1546. //    IN PVOID va
  1547. //    );
  1548. //
  1549. // Routine Description:
  1550. //
  1551. //    MiGetPteOffset returns the offset into a page table page
  1552. //    for a given virtual address.
  1553. //
  1554. // Argments
  1555. //
  1556. //    Va - Supplies the virtual address to locate the offset for.
  1557. //
  1558. // Return Value:
  1559. //
  1560. //    The offset into the page table page table the corresponding PTE is at.
  1561. //
  1562. //--
  1563. #define MiGetPteOffset(va) ((ULONG) (((ULONG_PTR)(va) >> PTI_SHIFT) & PDI_MASK))
  1564. //++
  1565. //++
  1566. //PVOID
  1567. //MiGetVirtualAddressMappedByPpe (
  1568. //    IN PMMPTE PTE
  1569. //    );
  1570. //
  1571. // Routine Description:
  1572. //
  1573. //    MiGetVirtualAddressMappedByPpe returns the virtual address
  1574. //    which is mapped by a given PPE address.
  1575. //
  1576. // Arguments
  1577. //
  1578. //    PPE - Supplies the PPE to get the virtual address for.
  1579. //
  1580. // Return Value:
  1581. //
  1582. //    Virtual address mapped by the PPE.
  1583. //
  1584. //--
  1585. #define MiGetVirtualAddressMappedByPpe(PPE) 
  1586.     MiGetVirtualAddressMappedByPte(MiGetVirtualAddressMappedByPde(PPE))
  1587. //++
  1588. //PVOID
  1589. //MiGetVirtualAddressMappedByPde (
  1590. //    IN PMMPTE PDE
  1591. //    );
  1592. //
  1593. // Routine Description:
  1594. //
  1595. //    MiGetVirtualAddressMappedByPde returns the virtual address
  1596. //    which is mapped by a given PDE address.
  1597. //
  1598. // Arguments
  1599. //
  1600. //    PDE - Supplies the PDE to get the virtual address for.
  1601. //
  1602. // Return Value:
  1603. //
  1604. //    Virtual address mapped by the PDE.
  1605. //
  1606. //--
  1607. #define MiGetVirtualAddressMappedByPde(Pde) 
  1608.     MiGetVirtualAddressMappedByPte(MiGetVirtualAddressMappedByPte(Pde))
  1609. //++
  1610. //PVOID
  1611. //MiGetVirtualAddressMappedByPte (
  1612. //    IN PMMPTE PTE
  1613. //    );
  1614. //
  1615. // Routine Description:
  1616. //
  1617. //    MiGetVirtualAddressMappedByPte returns the virtual address
  1618. //    which is mapped by a given PTE address.
  1619. //
  1620. // Argments
  1621. //
  1622. //    PTE - Supplies the PTE to get the virtual address for.
  1623. //
  1624. // Return Value:
  1625. //
  1626. //    Virtual address mapped by the PTE.
  1627. //
  1628. //--
  1629. #ifdef  _WIN64
  1630. #define MiGetVirtualAddressMappedByPte(PTE) 
  1631.   (((ULONG_PTR)(PTE) & PTA_SIGN) ? 
  1632.    (PVOID)(((ULONG_PTR)(PTE) & VRN_MASK) | VA_FILL | 
  1633.            (((ULONG_PTR)(PTE)-PTE_BASE) << (PAGE_SHIFT - PTE_SHIFT))) : 
  1634.    (PVOID)(((ULONG_PTR)(PTE) & VRN_MASK) | (((ULONG_PTR)(PTE)-PTE_BASE) << (PAGE_SHIFT - PTE_SHIFT))))
  1635. #else
  1636. #define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG_PTR)(PTE) << (PAGE_SHIFT - PTE_SHIFT)))
  1637. #endif
  1638. //++
  1639. //LOGICAL
  1640. //MiIsVirtualAddressOnPpeBoundary (
  1641. //    IN PVOID VA
  1642. //    );
  1643. //
  1644. // Routine Description:
  1645. //
  1646. //    MiIsVirtualAddressOnPpeBoundary returns TRUE if the virtual address is
  1647. //    on a page directory entry boundary.
  1648. //
  1649. // Arguments
  1650. //
  1651. //    VA - Supplies the virtual address to check.
  1652. //
  1653. // Return Value:
  1654. //
  1655. //    TRUE if on a boundary, FALSE if not.
  1656. //
  1657. //--
  1658. #define MiIsVirtualAddressOnPpeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY1_MASK) == 0)
  1659. //++
  1660. //LOGICAL
  1661. //MiIsVirtualAddressOnPdeBoundary (
  1662. //    IN PVOID VA
  1663. //    );
  1664. //
  1665. // Routine Description:
  1666. //
  1667. //    MiIsVirtualAddressOnPdeBoundary returns TRUE if the virtual address is
  1668. //    on a page directory entry boundary.
  1669. //
  1670. // Arguments
  1671. //
  1672. //    VA - Supplies the virtual address to check.
  1673. //
  1674. // Return Value:
  1675. //
  1676. //    TRUE if on a 4MB PDE boundary, FALSE if not.
  1677. //
  1678. //--
  1679. #define MiIsVirtualAddressOnPdeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY2_MASK) == 0)
  1680. //++
  1681. //LOGICAL
  1682. //MiIsPteOnPpeBoundary (
  1683. //    IN PVOID VA
  1684. //    );
  1685. //
  1686. // Routine Description:
  1687. //
  1688. //    MiIsPteOnPpeBoundary returns TRUE if the PTE is
  1689. //    on a page directory parent entry boundary.
  1690. //
  1691. // Arguments
  1692. //
  1693. //    VA - Supplies the virtual address to check.
  1694. //
  1695. // Return Value:
  1696. //
  1697. //    TRUE if on a boundary, FALSE if not.
  1698. //
  1699. //--
  1700. #define MiIsPteOnPpeBoundary(PTE) (((ULONG_PTR)(PTE) & (MM_VA_MAPPED_BY_PDE - 1)) == 0)
  1701. //++
  1702. //LOGICAL
  1703. //MiIsPteOnPdeBoundary (
  1704. //    IN PVOID PTE
  1705. //    );
  1706. //
  1707. // Routine Description:
  1708. //
  1709. //    MiIsPteOnPdeBoundary returns TRUE if the PTE is
  1710. //    on a page directory entry boundary.
  1711. //
  1712. // Arguments
  1713. //
  1714. //    PTE - Supplies the PTE to check.
  1715. //
  1716. // Return Value:
  1717. //
  1718. //    TRUE if on a 8MB PDE boundary, FALSE if not.
  1719. //
  1720. //--
  1721. #define MiIsPteOnPdeBoundary(PTE) (((ULONG_PTR)(PTE) & (PAGE_SIZE - 1)) == 0)
  1722. //++
  1723. //ULONG
  1724. //GET_PAGING_FILE_NUMBER (
  1725. //    IN MMPTE PTE
  1726. //    );
  1727. //
  1728. // Routine Description:
  1729. //
  1730. //    This macro extracts the paging file number from a PTE.
  1731. //
  1732. // Argments
  1733. //
  1734. //    PTE - Supplies the PTE to operate upon.
  1735. //
  1736. // Return Value:
  1737. //
  1738. //    The paging file number.
  1739. //
  1740. //--
  1741. #define GET_PAGING_FILE_NUMBER(PTE) ((ULONG) (PTE).u.Soft.PageFileLow)
  1742. //++
  1743. //ULONG
  1744. //GET_PAGING_FILE_OFFSET (
  1745. //    IN MMPTE PTE
  1746. //    );
  1747. //
  1748. // Routine Description:
  1749. //
  1750. //    This macro extracts the offset into the paging file from a PTE.
  1751. //
  1752. // Argments
  1753. //
  1754. //    PTE - Supplies the PTE to operate upon.
  1755. //
  1756. // Return Value:
  1757. //
  1758. //    The paging file offset.
  1759. //
  1760. //--
  1761. #define GET_PAGING_FILE_OFFSET(PTE) ((ULONG) (PTE).u.Soft.PageFileHigh)
  1762. //++
  1763. //ULONG_PTR
  1764. //IS_PTE_NOT_DEMAND_ZERO (
  1765. //    IN PMMPTE PPTE
  1766. //    );
  1767. //
  1768. // Routine Description:
  1769. //
  1770. //    This macro checks to see if a given PTE is NOT a demand zero PTE.
  1771. //
  1772. // Argments
  1773. //
  1774. //    PTE - Supplies the PTE to operate upon.
  1775. //
  1776. // Return Value:
  1777. //
  1778. //     Returns 0 if the PTE is demand zero, non-zero otherwise.
  1779. //
  1780. //--
  1781. #define IS_PTE_NOT_DEMAND_ZERO(PTE) 
  1782.                  ((PTE).u.Long & ((ULONG_PTR)0xFFFFFFFFFFFFF000 |  
  1783.                                   MM_PTE_VALID_MASK |       
  1784.                                   MM_PTE_PROTOTYPE_MASK |   
  1785.                                   MM_PTE_TRANSITION_MASK))
  1786. //++
  1787. //VOID
  1788. //MI_MAKING_VALID_PTE_INVALID(
  1789. //    IN PMMPTE PPTE
  1790. //    );
  1791. //
  1792. // Routine Description:
  1793. //
  1794. //    Prepare to make a single valid PTE invalid.
  1795. //    No action is required on x86.
  1796. //
  1797. // Argments
  1798. //
  1799. //    SYSTEM_WIDE - Supplies TRUE if this will happen on all processors.
  1800. //
  1801. // Return Value:
  1802. //
  1803. //    None.
  1804. //
  1805. //--
  1806. #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE)
  1807. //++
  1808. //VOID
  1809. //MI_MAKING_VALID_MULTIPLE_PTES_INVALID(
  1810. //    IN PMMPTE PPTE
  1811. //    );
  1812. //
  1813. // Routine Description:
  1814. //
  1815. //    Prepare to make multiple valid PTEs invalid.
  1816. //    No action is required on x86.
  1817. //
  1818. // Argments
  1819. //
  1820. //    SYSTEM_WIDE - Supplies TRUE if this will happen on all processors.
  1821. //
  1822. // Return Value:
  1823. //
  1824. //    None.
  1825. //
  1826. //--
  1827. #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE)
  1828. //++
  1829. //VOID
  1830. //MI_MAKE_PROTECT_WRITE_COPY (
  1831. //    IN OUT MMPTE PPTE
  1832. //    );
  1833. //
  1834. // Routine Description:
  1835. //
  1836. //    This macro makes a writable PTE a writeable-copy PTE.
  1837. //
  1838. // Argments
  1839. //
  1840. //    PTE - Supplies the PTE to operate upon.
  1841. //
  1842. // Return Value:
  1843. //
  1844. //    NONE
  1845. //
  1846. //--
  1847. #define MI_MAKE_PROTECT_WRITE_COPY(PTE) 
  1848.         if ((PTE).u.Soft.Protection & MM_PROTECTION_WRITE_MASK) {      
  1849.             (PTE).u.Long |= MM_PROTECTION_COPY_MASK << MM_PROTECT_FIELD_SHIFT;      
  1850.         }
  1851. //++
  1852. //VOID
  1853. //MI_SET_PAGE_DIRTY(
  1854. //    IN PMMPTE PPTE,
  1855. //    IN PVOID VA,
  1856. //    IN PVOID PFNHELD
  1857. //    );
  1858. //
  1859. // Routine Description:
  1860. //
  1861. //    This macro sets the dirty bit (and release page file space).
  1862. //
  1863. // Argments
  1864. //
  1865. //    TEMP - Supplies a temporary for usage.
  1866. //
  1867. //    PPTE - Supplies a pointer to the PTE that corresponds to VA.
  1868. //
  1869. //    VA - Supplies a the virtual address of the page fault.
  1870. //
  1871. //    PFNHELD - Supplies TRUE if the PFN lock is held.
  1872. //
  1873. // Return Value:
  1874. //
  1875. //    None.
  1876. //
  1877. //--
  1878. #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD)                          
  1879.             if ((PPTE)->u.Hard.Dirty == 1) {                        
  1880.                 MiSetDirtyBit ((VA),(PPTE),(PFNHELD));              
  1881.             }
  1882. //++
  1883. //VOID
  1884. //MI_NO_FAULT_FOUND(
  1885. //    IN TEMP,
  1886. //    IN PMMPTE PPTE,
  1887. //    IN PVOID VA,
  1888. //    IN PVOID PFNHELD
  1889. //    );
  1890. //
  1891. // Routine Description:
  1892. //
  1893. //    This macro handles the case when a page fault is taken and no
  1894. //    PTE with the valid bit clear is found.
  1895. //
  1896. // Argments
  1897. //
  1898. //    TEMP - Supplies a temporary for usage.
  1899. //
  1900. //    PPTE - Supplies a pointer to the PTE that corresponds to VA.
  1901. //
  1902. //    VA - Supplies a the virtual address of the page fault.
  1903. //
  1904. //    PFNHELD - Supplies TRUE if the PFN lock is held.
  1905. //
  1906. // Return Value:
  1907. //
  1908. //    None.
  1909. //
  1910. //--
  1911. #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) 
  1912.         if (StoreInstruction && ((PPTE)->u.Hard.Dirty == 0)) {  
  1913.             MiSetDirtyBit ((VA),(PPTE),(PFNHELD));     
  1914.         }
  1915. //++
  1916. //ULONG_PTR
  1917. //MI_CAPTURE_DIRTY_BIT_TO_PFN (
  1918. //    IN PMMPTE PPTE,
  1919. //    IN PMMPFN PPFN
  1920. //    );
  1921. //
  1922. // Routine Description:
  1923. //
  1924. //    This macro gets captures the state of the dirty bit to the PFN
  1925. //    and frees any associated page file space if the PTE has been
  1926. //    modified element.
  1927. //
  1928. //    NOTE - THE PFN LOCK MUST BE HELD!
  1929. //
  1930. // Argments
  1931. //
  1932. //    PPTE - Supplies the PTE to operate upon.
  1933. //
  1934. //    PPFN - Supplies a pointer to the PFN database element that corresponds
  1935. //           to the page mapped by the PTE.
  1936. //
  1937. // Return Value:
  1938. //
  1939. //    None.
  1940. //
  1941. //--
  1942. #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN)                      
  1943.          ASSERT (KeGetCurrentIrql() > APC_LEVEL);                   
  1944.          if (((PPFN)->u3.e1.Modified == 0) &&                       
  1945.             ((PPTE)->u.Hard.Dirty != 0)) {               
  1946.              (PPFN)->u3.e1.Modified = 1;                            
  1947.              if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) &&     
  1948.                           ((PPFN)->u3.e1.WriteInProgress == 0)) {   
  1949.                  MiReleasePageFileSpace ((PPFN)->OriginalPte);      
  1950.                  (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0;       
  1951.              }                                                      
  1952.          }
  1953. //++
  1954. //BOOLEAN
  1955. //MI_IS_PHYSICAL_ADDRESS (
  1956. //    IN PVOID VA
  1957. //    );
  1958. //
  1959. // Routine Description:
  1960. //
  1961. //    This macro deterines if a give virtual address is really a
  1962. //    physical address.
  1963. //
  1964. // Argments
  1965. //
  1966. //    VA - Supplies the virtual address.
  1967. //
  1968. // Return Value:
  1969. //
  1970. //    FALSE if it is not a physical address, TRUE if it is.
  1971. //
  1972. //--
  1973. #define MI_IS_PHYSICAL_ADDRESS(Va) 
  1974.      ((((ULONG_PTR)(Va) >= KSEG3_BASE) && ((ULONG_PTR)(Va) < KSEG3_LIMIT)) || 
  1975.       (((ULONG_PTR)Va >= KSEG0_BASE) && ((ULONG_PTR)Va < KSEG2_BASE)))
  1976. //++
  1977. //ULONG_PTR
  1978. //MI_CONVERT_PHYSICAL_TO_PFN (
  1979. //    IN PVOID VA
  1980. //    );
  1981. //
  1982. // Routine Description:
  1983. //
  1984. //    This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS)
  1985. //    to its corresponding physical frame number.
  1986. //
  1987. // Argments
  1988. //
  1989. //    VA - Supplies a pointer to the physical address.
  1990. //
  1991. // Return Value:
  1992. //
  1993. //    Returns the PFN for the page.
  1994. //
  1995. //--
  1996. PVOID KiGetPhysicalAddress(
  1997.     IN PVOID VirtualAddress
  1998.     );
  1999. #define MI_CONVERT_PHYSICAL_TO_PFN(Va)   
  2000.     (((ULONG_PTR)(Va) < KSEG0_BASE) ?                             
  2001.      ((PFN_NUMBER)(((ULONG_PTR)(Va) - KSEG3_BASE) >> PAGE_SHIFT)) : 
  2002.      ((PFN_NUMBER)(((ULONG_PTR)KiGetPhysicalAddress(Va)) >> PAGE_SHIFT)))
  2003. typedef struct _MMCOLOR_TABLES {
  2004.     PFN_NUMBER Flink;
  2005.     PVOID Blink;
  2006. } MMCOLOR_TABLES, *PMMCOLOR_TABLES;
  2007. typedef struct _MMPRIMARY_COLOR_TABLES {
  2008.     LIST_ENTRY ListHead;
  2009. } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES;
  2010. #if MM_MAXIMUM_NUMBER_OF_COLORS > 1
  2011. extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS];
  2012. #endif
  2013. extern PMMCOLOR_TABLES MmFreePagesByColor[2];
  2014. extern ULONG MmTotalPagesForPagingFile;
  2015. //
  2016. // A VALID Page Table Entry on an Intel IA64 has the following definition.
  2017. //
  2018. #define _MM_PAGING_FILE_LOW_SHIFT 28
  2019. #define _MM_PAGING_FILE_HIGH_SHIFT 32
  2020. #define MI_PTE_LOOKUP_NEEDED ((ULONG64)0xffffffff)
  2021. typedef struct _MMPTE_SOFTWARE {
  2022.     ULONGLONG Valid : 1;
  2023.     ULONGLONG Prototype : 1;
  2024.     ULONGLONG Protection : 5;
  2025.     ULONGLONG Transition : 1;
  2026.     ULONGLONG UsedPageTableEntries : PTE_PER_PAGE_BITS;
  2027.     ULONGLONG Reserved : 20 - PTE_PER_PAGE_BITS;
  2028.     ULONGLONG PageFileLow: 4;
  2029.     ULONGLONG PageFileHigh : 32;
  2030. } MMPTE_SOFTWARE;
  2031. typedef struct _MMPTE_TRANSITION {
  2032.     ULONGLONG Valid : 1;
  2033.     ULONGLONG Prototype : 1;
  2034.     ULONGLONG Protection : 5;
  2035.     ULONGLONG Transition : 1;
  2036.     ULONGLONG Rsvd0 : PAGE_SHIFT - 8;
  2037.     ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT;
  2038.     ULONGLONG Rsvd1 : 14;
  2039. } MMPTE_TRANSITION;
  2040. #define _MM_PROTO_ADDRESS_SHIFT 12
  2041. typedef struct _MMPTE_PROTOTYPE {
  2042.     ULONGLONG Valid : 1;
  2043.     ULONGLONG Prototype : 1;
  2044.     ULONGLONG ReadOnly : 1;  // if set allow read only access.
  2045.     ULONGLONG Rsvd : 9;
  2046.     ULONGLONG ProtoAddress : 52;
  2047. } MMPTE_PROTOTYPE;
  2048. #define _MM_PTE_SUBSECTION_ADDRESS_SHIFT  12
  2049. typedef struct _MMPTE_SUBSECTION {
  2050.     ULONGLONG Valid : 1;
  2051.     ULONGLONG Prototype : 1;
  2052.     ULONGLONG Protection : 5;
  2053.     ULONGLONG WhichPool : 1;
  2054.     ULONGLONG Rsvd : 4;
  2055.     ULONGLONG SubsectionAddress : 52;
  2056. } MMPTE_SUBSECTION;
  2057. typedef struct _MMPTE_LIST {
  2058.     ULONGLONG Valid : 1;
  2059.     ULONGLONG OneEntry : 1;
  2060.     ULONGLONG filler10 : 10;
  2061.     ULONGLONG NextEntry : 32;
  2062.     ULONGLONG Rsvd : 20;
  2063. } MMPTE_LIST;
  2064. //
  2065. // A Page Table Entry on an Intel IA64 has the following definition.
  2066. //
  2067. #define _HARDWARE_PTE_WORKING_SET_BITS  11
  2068. typedef struct _MMPTE_HARDWARE {
  2069.     ULONGLONG Valid : 1;
  2070.     ULONGLONG Rsvd0 : 1;
  2071.     ULONGLONG Cache : 3;
  2072.     ULONGLONG Accessed : 1;
  2073.     ULONGLONG Dirty : 1;
  2074.     ULONGLONG Owner : 2;
  2075.     ULONGLONG Execute : 1;
  2076.     ULONGLONG Write : 1;
  2077.     ULONGLONG Rsvd1 : PAGE_SHIFT - 12;
  2078.     ULONGLONG CopyOnWrite : 1;
  2079.     ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT;
  2080.     ULONGLONG Rsvd2 : 2;
  2081.     ULONGLONG Exception : 1;
  2082.     ULONGLONG SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS;
  2083. } MMPTE_HARDWARE, *PMMPTE_HARDWARE;
  2084. typedef struct _MMPTE_LARGEPAGE {
  2085.     ULONGLONG Valid : 1;
  2086.     ULONGLONG Rsvd0 : 1;
  2087.     ULONGLONG Cache : 3;
  2088.     ULONGLONG Accessed : 1;
  2089.     ULONGLONG Dirty : 1;
  2090.     ULONGLONG Owner : 2;
  2091.     ULONGLONG Execute : 1;
  2092.     ULONGLONG Write : 1;
  2093.     ULONGLONG Rsvd1 : PAGE_SHIFT - 12;
  2094.     ULONGLONG CopyOnWrite : 1;
  2095.     ULONGLONG PageFrameNumber : 50 - PAGE_SHIFT;
  2096.     ULONGLONG Rsvd2 : 2;
  2097.     ULONGLONG Exception : 1;
  2098.     ULONGLONG Rsvd3 : 1;
  2099.     ULONGLONG LargePage : 1;
  2100.     ULONGLONG PageSize : 6;
  2101.     ULONGLONG Rsvd4 : 3;
  2102. } MMPTE_LARGEPAGE, *PMMPTE_LARGEPAGE;
  2103. typedef struct _ALT_4KPTE {
  2104.     ULONGLONG Commit : 1;
  2105.     ULONGLONG Rsvd0 : 1;
  2106.     ULONGLONG Cache : 3;
  2107.     ULONGLONG Accessed : 1;
  2108.     ULONGLONG Dirty : 1;
  2109.     ULONGLONG Owner : 2;
  2110.     ULONGLONG Execute : 1;
  2111.     ULONGLONG Write : 1;
  2112.     ULONGLONG Rsvd1 : 1;
  2113.     ULONGLONG PteOffset : 32;
  2114.     ULONGLONG Rsvd2 : 8;
  2115.     ULONGLONG Exception : 1;
  2116.     ULONGLONG Protection : 5;
  2117.     ULONGLONG Lock : 1;
  2118.     ULONGLONG FillZero : 1;
  2119.     ULONGLONG NoAccess : 1;
  2120.     ULONGLONG CopyOnWrite : 1;
  2121.     ULONGLONG PteIndirect : 1;
  2122.     ULONGLONG Private : 1;
  2123. } ALT_4KPTE, *PALT_4KPTE;
  2124. #define MI_GET_PAGE_FRAME_FROM_PTE(PTE) ((ULONG)((PTE)->u.Hard.PageFrameNumber))
  2125. #define MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE(PTE) ((ULONG)((PTE)->u.Trans.PageFrameNumber))
  2126. #define MI_GET_PROTECTION_FROM_SOFT_PTE(PTE) ((ULONG)((PTE)->u.Soft.Protection))
  2127. #define MI_GET_PROTECTION_FROM_TRANSITION_PTE(PTE) ((ULONG)((PTE)->u.Trans.Protection))
  2128. typedef struct _MMPTE {
  2129.     union  {
  2130.         ULONGLONG Long;
  2131.         MMPTE_HARDWARE Hard;
  2132.         MMPTE_LARGEPAGE Large;
  2133.         HARDWARE_PTE Flush;
  2134.         MMPTE_PROTOTYPE Proto;
  2135.         MMPTE_SOFTWARE Soft;
  2136.         MMPTE_TRANSITION Trans;
  2137.         MMPTE_SUBSECTION Subsect;
  2138.         MMPTE_LIST List;
  2139.         ALT_4KPTE Alt;
  2140.         } u;
  2141. } MMPTE;
  2142. typedef MMPTE *PMMPTE;
  2143. //++
  2144. //VOID
  2145. //MI_WRITE_VALID_PTE (
  2146. //    IN PMMPTE PointerPte,
  2147. //    IN MMPTE PteContents
  2148. //    );
  2149. //
  2150. // Routine Description:
  2151. //
  2152. //    MI_WRITE_VALID_PTE fills in the specified PTE making it valid with the
  2153. //    specified contents.
  2154. //
  2155. // Arguments
  2156. //
  2157. //    PointerPte - Supplies a PTE to fill.
  2158. //
  2159. //    PteContents - Supplies the contents to put in the PTE.
  2160. //
  2161. // Return Value:
  2162. //
  2163. //    None.
  2164. //
  2165. //--
  2166. #define MI_WRITE_VALID_PTE(_PointerPte, _PteContents)    
  2167.             (*(_PointerPte) = (_PteContents))
  2168. //++
  2169. //VOID
  2170. //MI_WRITE_INVALID_PTE (
  2171. //    IN PMMPTE PointerPte,
  2172. //    IN MMPTE PteContents
  2173. //    );
  2174. //
  2175. // Routine Description:
  2176. //
  2177. //    MI_WRITE_INVALID_PTE fills in the specified PTE making it invalid with the
  2178. //    specified contents.
  2179. //
  2180. // Arguments
  2181. //
  2182. //    PointerPte - Supplies a PTE to fill.
  2183. //
  2184. //    PteContents - Supplies the contents to put in the PTE.
  2185. //
  2186. // Return Value:
  2187. //
  2188. //    None.
  2189. //
  2190. //--
  2191. #define MI_WRITE_INVALID_PTE(_PointerPte, _PteContents)  
  2192.             (*(_PointerPte) = (_PteContents))
  2193. //++
  2194. //VOID
  2195. //MI_WRITE_VALID_PTE_NEW_PROTECTION (
  2196. //    IN PMMPTE PointerPte,
  2197. //    IN MMPTE PteContents
  2198. //    );
  2199. //
  2200. // Routine Description:
  2201. //
  2202. //    MI_WRITE_VALID_PTE_NEW_PROTECTION fills in the specified PTE (which was
  2203. //    already valid) changing only the protection or the dirty bit.
  2204. //
  2205. // Arguments
  2206. //
  2207. //    PointerPte - Supplies a PTE to fill.
  2208. //
  2209. //    PteContents - Supplies the contents to put in the PTE.
  2210. //
  2211. // Return Value:
  2212. //
  2213. //    None.
  2214. //
  2215. //--
  2216. #define MI_WRITE_VALID_PTE_NEW_PROTECTION(_PointerPte, _PteContents)    
  2217.             (*(_PointerPte) = (_PteContents))
  2218. //
  2219. // For EM build, need to export this function to ps/psldt.c
  2220. //
  2221. extern PVOID
  2222. MiCreatePebOrTeb (
  2223.     IN PEPROCESS TargetProcess,
  2224.     IN ULONG Size
  2225.     );
  2226. //++
  2227. //VOID
  2228. //MiFillMemoryPte (
  2229. //    IN PMMPTE Destination,
  2230. //    IN ULONG  Length,
  2231. //    IN MMPTE  Pattern,
  2232. //    };
  2233. //
  2234. // Routine Description:
  2235. //
  2236. //    This function fills memory with the specified PTE pattern.
  2237. //
  2238. // Arguments
  2239. //
  2240. //    Destination - Supplies a pointer to the memory to fill.
  2241. //
  2242. //    Length      - Supplies the length, in bytes, of the memory to be
  2243. //                  filled.
  2244. //
  2245. //    Pattern     - Supplies the PTE fill pattern.
  2246. //
  2247. // Return Value:
  2248. //
  2249. //    None.
  2250. //
  2251. //--
  2252. #define MiFillMemoryPte(Destination, Length, Pattern) 
  2253.              RtlFillMemoryUlonglong ((Destination), (Length), (Pattern))
  2254. #define KiWbInvalidateCache
  2255. //++
  2256. //BOOLEAN
  2257. //MI_IS_PAGE_TABLE_ADDRESS (
  2258. //    IN PVOID VA
  2259. //    );
  2260. //
  2261. // Routine Description:
  2262. //
  2263. //    This macro determines if a given virtual address is really a
  2264. //    page table address (PTE, PDE, PPE).
  2265. //
  2266. // Arguments
  2267. //
  2268. //    VA - Supplies the virtual address.
  2269. //
  2270. // Return Value:
  2271. //
  2272. //    FALSE if it is not a page table address, TRUE if it is.
  2273. //
  2274. //--
  2275. #if defined(_MIALT4K_)
  2276. #define MI_IS_PAGE_TABLE_ADDRESS(VA) 
  2277.     ((((ULONG_PTR)VA >= PTE_UBASE) && ((ULONG_PTR)VA <= (PDE_UTBASE + PAGE_SIZE))) || 
  2278.      (((ULONG_PTR)VA >= PTE_KBASE) && ((ULONG_PTR)VA <= (PDE_KTBASE + PAGE_SIZE))) || 
  2279.      (((ULONG_PTR)VA >= PTE_SBASE) && ((ULONG_PTR)VA <= (PDE_STBASE + PAGE_SIZE))) || 
  2280.      (((ULONG_PTR)VA >= ALT4KB_PERMISSION_TABLE_START) && 
  2281.       ((ULONG_PTR)VA <= ALT4KB_PERMISSION_TABLE_END)))
  2282. #else
  2283. #define MI_IS_PAGE_TABLE_ADDRESS(VA) 
  2284.     ((((ULONG_PTR)VA >= PTE_UBASE) && ((ULONG_PTR)VA <= (PDE_UTBASE + PAGE_SIZE))) || 
  2285.      (((ULONG_PTR)VA >= PTE_KBASE) && ((ULONG_PTR)VA <= (PDE_KTBASE + PAGE_SIZE))) || 
  2286.      (((ULONG_PTR)VA >= PTE_SBASE) && ((ULONG_PTR)VA <= (PDE_STBASE + PAGE_SIZE))))
  2287. #endif
  2288. //++
  2289. //BOOLEAN
  2290. //MI_IS_HYPER_SPACE_ADDRESS (
  2291. //    IN PVOID VA
  2292. //    );
  2293. //
  2294. // Routine Description:
  2295. //
  2296. //    This macro determines if a given virtual address resides in 
  2297. //    the hyper space.
  2298. //
  2299. // Arguments
  2300. //
  2301. //    VA - Supplies the virtual address.
  2302. //
  2303. // Return Value:
  2304. //
  2305. //    FALSE if it is not a hyper space address, TRUE if it is.
  2306. //
  2307. //--
  2308. #define MI_IS_HYPER_SPACE_ADDRESS(VA) 
  2309.     (((ULONG_PTR)VA >= (ULONG_PTR)HYPER_SPACE) && ((ULONG_PTR)VA <= HYPER_SPACE_END))
  2310. //++
  2311. //BOOLEAN
  2312. //MI_IS_PTE_ADDRESS (
  2313. //    IN PMMPTE PTE
  2314. //    );
  2315. //
  2316. // Routine Description:
  2317. //
  2318. //    This macro determines if a given virtual address is really a
  2319. //    page table page (PTE) address.
  2320. //
  2321. // Arguments
  2322. //
  2323. //    PTE - Supplies the PTE virtual address.
  2324. //
  2325. // Return Value:
  2326. //
  2327. //    FALSE if it is not a PTE address, TRUE if it is.
  2328. //
  2329. //--
  2330. #define MI_IS_PTE_ADDRESS(PTE) 
  2331.     (((PTE >= (PMMPTE)PTE_UBASE) && (PTE <= (PMMPTE)PTE_UTOP)) || 
  2332.      ((PTE >= (PMMPTE)PTE_KBASE) && (PTE <= (PMMPTE)PTE_KTOP)) || 
  2333.      ((PTE >= (PMMPTE)PTE_SBASE) && (PTE <= (PMMPTE)PTE_STOP)))
  2334. #define MI_IS_PPE_ADDRESS(PTE) 
  2335.     (((PTE >= (PMMPTE)PDE_UTBASE) && (PTE <= (PMMPTE)(PDE_UTBASE + PAGE_SIZE))) || 
  2336.      ((PTE >= (PMMPTE)PDE_KTBASE) && (PTE <= (PMMPTE)(PDE_KTBASE + PAGE_SIZE))) || 
  2337.      ((PTE >= (PMMPTE)PDE_STBASE) && (PTE <= (PMMPTE)(PDE_STBASE + PAGE_SIZE))))
  2338. //++
  2339. //BOOLEAN
  2340. //MI_IS_KERNEL_PTE_ADDRESS (
  2341. //    IN PMMPTE PTE
  2342. //    );
  2343. //
  2344. // Routine Description:
  2345. //
  2346. //    This macro determines if a given virtual address is really a
  2347. //    kernel page table page (PTE) address.
  2348. //
  2349. // Arguments
  2350. //
  2351. //    PTE - Supplies the PTE virtual address.
  2352. //
  2353. // Return Value:
  2354. //
  2355. //    FALSE if it is not a kernel PTE address, TRUE if it is.
  2356. //
  2357. //--
  2358. #define MI_IS_KERNEL_PTE_ADDRESS(PTE) 
  2359.      (((PMMPTE)PTE >= (PMMPTE)PTE_KBASE) && ((PMMPTE)PTE <= (PMMPTE)PTE_KTOP))
  2360. //++
  2361. //BOOLEAN
  2362. //MI_IS_USER_PTE_ADDRESS (
  2363. //    IN PMMPTE PTE
  2364. //    );
  2365. //
  2366. // Routine Description:
  2367. //
  2368. //    This macro determines if a given virtual address is really a
  2369. //    page table page (PTE) address.
  2370. //
  2371. // Arguments
  2372. //
  2373. //    PTE - Supplies the PTE virtual address.
  2374. //
  2375. // Return Value:
  2376. //
  2377. //    FALSE if it is not a PTE address, TRUE if it is.
  2378. //
  2379. //--
  2380. #define MI_IS_USER_PTE_ADDRESS(PTE) 
  2381.     ((PTE >= (PMMPTE)PTE_UBASE) && (PTE <= (PMMPTE)PTE_UTOP))
  2382. //++
  2383. //BOOLEAN
  2384. //MI_IS_PAGE_DIRECTORY_ADDRESS (
  2385. //    IN PMMPTE PDE
  2386. //    );
  2387. //
  2388. // Routine Description:
  2389. //
  2390. //    This macro determines if a given virtual address is really a
  2391. //    page directory page (PDE) address.
  2392. //
  2393. // Arguments
  2394. //
  2395. //    PDE - Supplies the virtual address.
  2396. //
  2397. // Return Value:
  2398. //
  2399. //    FALSE if it is not a PDE address, TRUE if it is.
  2400. //
  2401. //--
  2402. #define MI_IS_PAGE_DIRECTORY_ADDRESS(PDE) 
  2403.     (((PDE >= (PMMPTE)PDE_UBASE) && (PDE <= (PMMPTE)PDE_UTOP)) || 
  2404.      ((PDE >= (PMMPTE)PDE_KBASE) && (PDE <= (PMMPTE)PDE_KTOP)) || 
  2405.      ((PDE >= (PMMPTE)PDE_SBASE) && (PDE <= (PMMPTE)PDE_STOP)))
  2406. //++
  2407. //BOOLEAN
  2408. //MI_IS_USER_PDE_ADDRESS (
  2409. //    IN PMMPTE PDE
  2410. //    );
  2411. //
  2412. // Routine Description:
  2413. //
  2414. //    This macro determines if a given virtual address is really a
  2415. //    user page directory page (PDE) address.
  2416. //
  2417. // Arguments
  2418. //
  2419. //    PDE - Supplies the PDE virtual address.
  2420. //
  2421. // Return Value:
  2422. //
  2423. //    FALSE if it is not a user PDE address, TRUE if it is.
  2424. //
  2425. //--
  2426. #define MI_IS_USER_PDE_ADDRESS(PDE) 
  2427.     ((PDE >= (PMMPTE)PDE_UBASE) && (PDE <= (PMMPTE)PDE_UTOP)) 
  2428. //++
  2429. //BOOLEAN
  2430. //MI_IS_KERNEL_PDE_ADDRESS (
  2431. //    IN PMMPTE PDE
  2432. //    );
  2433. //
  2434. // Routine Description:
  2435. //
  2436. //    This macro determines if a given virtual address is really a
  2437. //    kernel page directory page (PDE) address.
  2438. //
  2439. // Arguments
  2440. //
  2441. //    PDE - Supplies the PDE virtual address.
  2442. //
  2443. // Return Value:
  2444. //
  2445. //    FALSE if it is not a user PDE address, TRUE if it is.
  2446. //
  2447. //--
  2448. #define MI_IS_KERNEL_PDE_ADDRESS(PDE) 
  2449.     ((PDE >= (PMMPTE)PDE_KBASE) && (PDE <= (PMMPTE)PDE_KTOP)) 
  2450. //++
  2451. //BOOLEAN
  2452. //MI_IS_PROCESS_SPACE_ADDRESS (
  2453. //    IN PVOID VA
  2454. //    );
  2455. //
  2456. // Routine Description:
  2457. //
  2458. //    This macro determines if a given virtual address resides in 
  2459. //    the per-process space.
  2460. //
  2461. // Arguments
  2462. //
  2463. //    VA - Supplies the virtual address.
  2464. //
  2465. // Return Value:
  2466. //
  2467. //    FALSE if it is not a per-process address, TRUE if it is.
  2468. //
  2469. //--
  2470. #define MI_IS_PROCESS_SPACE_ADDRESS(VA) (((ULONG_PTR)VA >> 61) == UREGION_INDEX)
  2471. //++
  2472. //BOOLEAN
  2473. //MI_IS_SYSTEM_ADDRESS (
  2474. //    IN PVOID VA
  2475. //    );
  2476. //
  2477. // Routine Description:
  2478. //
  2479. //    This macro determines if a given virtual address resides in 
  2480. //    the system (global) space.
  2481. //
  2482. // Arguments
  2483. //
  2484. //    VA - Supplies the virtual address.
  2485. //
  2486. // Return Value:
  2487. //
  2488. //    FALSE if it is not a system (global) address, TRUE if it is.
  2489. //
  2490. //--
  2491. #define MI_IS_SYSTEM_ADDRESS(VA) (((ULONG_PTR)VA >> 61) == KREGION_INDEX)
  2492. //
  2493. // Generate kernel segment physical address
  2494. //
  2495. //PVOID
  2496. //MiGetKSegAddress (
  2497. //    PFN_NUMBER FrameNumber
  2498. //    );
  2499. //
  2500. //++
  2501. //PVOID
  2502. //KSEG_ADDRESS (
  2503. //    IN ULONG PAGE
  2504. //    );
  2505. //
  2506. // Routine Description:
  2507. //
  2508. //    This macro returns a KSEG virtual address which maps the page.
  2509. //
  2510. // Arguments:
  2511. //
  2512. //    PAGE - Supplies the physical page frame number
  2513. //
  2514. // Return Value:
  2515. //
  2516. //    The address of the KSEG address
  2517. //
  2518. //--
  2519. // #define KSEG_ADDRESS(PAGE) ((PVOID)(KSEG3_BASE | ((ULONG_PTR)(PAGE) << PAGE_SHIFT)))
  2520. // #define KSEG_ADDRESS(PAGE) MiGetKSegAddress ((ULONG)PAGE)
  2521. //
  2522. //++
  2523. //PVOID
  2524. //KSEG0_ADDRESS (
  2525. //    IN ULONG PAGE
  2526. //    );
  2527. //
  2528. // Routine Description:
  2529. //
  2530. //    This macro returns a KSEG0 virtual address which maps the page.
  2531. //
  2532. // Arguments:
  2533. //
  2534. //    PAGE - Supplies the physical page frame number
  2535. //
  2536. // Return Value:
  2537. //
  2538. //    The address of the KSEG address
  2539. //
  2540. //--
  2541. #define KSEG0_ADDRESS(PAGE) 
  2542.      (PVOID)(KSEG0_BASE | ((PAGE) <<  PAGE_SHIFT)) 
  2543. extern MMPTE ValidPpePte;
  2544. extern PFN_NUMBER MmSystemParentTablePage;
  2545. //++
  2546. //PMMPTE
  2547. //MiGetPpeAddress (
  2548. //    IN PVOID va
  2549. //    );
  2550. //
  2551. // Routine Description:
  2552. //
  2553. //    MiGetPpeAddress returns the address of the page directory parent entry
  2554. //    which maps the given virtual address.  This is one level above the
  2555. //    page directory.
  2556. //
  2557. // Arguments
  2558. //
  2559. //    Va - Supplies the virtual address to locate the PPE for.
  2560. //
  2561. // Return Value:
  2562. //
  2563. //    The address of the PPE.   // LWFIX: expand for 3 level
  2564. //
  2565. //--
  2566. #if PTE_THASH
  2567. __inline
  2568. PMMPTE
  2569. MiGetPpeAddress_XX(
  2570.     IN PVOID Va
  2571.     )
  2572. {
  2573.     if (((ULONG_PTR)(Va) & PTE_BASE) == PTE_BASE) {
  2574.         
  2575.         return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE))));
  2576.     } else {
  2577.         return ((PMMPTE)(__thash(__thash(__thash((ULONG_PTR)Va)))));
  2578.     }
  2579. }
  2580. #define MiGetPpeAddress(va) MiGetPpeAddress_XX((PVOID)(va))
  2581. #else
  2582. #define MiGetPpeAddress(Va) 
  2583.   (((((ULONG_PTR)(Va)) & PTE_BASE) == PTE_BASE) ? 
  2584.    ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :
  2585.    ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | 
  2586.               ((((((ULONG_PTR)(Va)) >> PDI1_SHIFT) << PTE_SHIFT) & 
  2587.                 (~(PDE_TBASE|VRN_MASK)) ) + PDE_TBASE))))
  2588. #endif
  2589. //MiGetPdeAddress (
  2590. //    IN PVOID va
  2591. //    );
  2592. //
  2593. // Routine Description:
  2594. //
  2595. //    MiGetPdeAddress returns the address of the PDE which maps the
  2596. //    given virtual address.
  2597. //
  2598. // Argments
  2599. //
  2600. //    Va - Supplies the virtual address to locate the PDE for.
  2601. //
  2602. // Return Value:
  2603. //
  2604. //    The address of the PDE.
  2605. //
  2606. //--
  2607. #if PTE_THASH
  2608. __inline
  2609. PMMPTE
  2610. MiGetPdeAddress_XX(
  2611.     IN PVOID Va
  2612.     )
  2613. {
  2614.     if (((ULONG_PTR)(Va) & PDE_BASE) == PDE_BASE) {
  2615.         
  2616.         return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE))));
  2617.     } else {
  2618.        return ((PMMPTE)(__thash(__thash((ULONG_PTR)(Va)))));
  2619.     }
  2620. }
  2621. #define MiGetPdeAddress(va) MiGetPdeAddress_XX((PVOID)(va))
  2622. #else
  2623. #define MiGetPdeAddress(Va) 
  2624.   (((((ULONG_PTR)(Va)) & PDE_BASE) == PDE_BASE) ? 
  2625.    ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :
  2626.    ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | 
  2627.              ((((((ULONG_PTR)(Va)) >> PDI_SHIFT) << PTE_SHIFT) & (~(PDE_BASE|VRN_MASK))) + PDE_BASE))))
  2628. #endif
  2629. //++
  2630. //PMMPTE
  2631. //MiGetPteAddress (
  2632. //    IN PVOID va
  2633. //    );
  2634. //
  2635. // Routine Description:
  2636. //
  2637. //    MiGetPteAddress returns the address of the PTE which maps the
  2638. //    given virtual address.
  2639. //
  2640. // Argments
  2641. //
  2642. //    Va - Supplies the virtual address to locate the PTE for.
  2643. //
  2644. // Return Value:
  2645. //
  2646. //    The address of the PTE.
  2647. //
  2648. //--
  2649. #if PTE_THASH
  2650. __inline
  2651. PMMPTE
  2652. MiGetPteAddress_XX(
  2653.     IN PVOID Va
  2654.     )
  2655. {
  2656.     if (((ULONG_PTR)(Va) & PDE_TBASE) == PDE_TBASE) {
  2657.         
  2658.         return ((PMMPTE)(((ULONG_PTR)Va & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE))));
  2659.     } else {
  2660.         return ((PMMPTE)(__thash((ULONG_PTR)(Va))));
  2661.     }
  2662. }
  2663. #define MiGetPteAddress(va) MiGetPteAddress_XX((PVOID)(va))
  2664. #else
  2665. #define MiGetPteAddress(Va) 
  2666.   (((((ULONG_PTR)(Va)) & PDE_TBASE) == PDE_TBASE) ? 
  2667.    ((PMMPTE)((((ULONG_PTR)(Va)) & VRN_MASK) | (PDE_TBASE + PAGE_SIZE - sizeof(MMPTE)))) :
  2668.    ((PMMPTE)(((((ULONG_PTR)(Va)) & VRN_MASK)) | 
  2669.              ((((((ULONG_PTR)(Va)) >> PTI_SHIFT) << PTE_SHIFT) & (~(PTE_BASE|VRN_MASK))) + PTE_BASE))))
  2670. #endif
  2671. #define MI_IS_PTE_PROTOTYPE(PointerPte)  (!MI_IS_USER_PTE_ADDRESS (PointerPte))
  2672. //++
  2673. //BOOLEAN
  2674. //MI_IS_SYSTEM_CACHE_ADDRESS (
  2675. //    IN PVOID VA
  2676. //    );
  2677. //
  2678. // Routine Description:
  2679. //
  2680. //    This macro takes a virtual address and determines if
  2681. //    it is a system cache address.
  2682. //
  2683. // Arguments
  2684. //
  2685. //    VA - Supplies a virtual address.
  2686. //
  2687. // Return Value:
  2688. //
  2689. //    TRUE if the address is in the system cache, FALSE if not.
  2690. //
  2691. //--
  2692. #define MI_IS_SYSTEM_CACHE_ADDRESS(VA)                      
  2693.          (((PVOID)(VA) >= (PVOID)MmSystemCacheStart &&      
  2694.      (PVOID)(VA) <= (PVOID)MmSystemCacheEnd))
  2695. #if defined(_MIALT4K_)
  2696. //
  2697. // Define constants and macros for alternate 4kb table.
  2698. //
  2699. // These are constants and defines that mimic the PAGE_SIZE constant but are
  2700. // hard coded to use 4K page values.
  2701. //
  2702. #define PAGE_4K         4096
  2703. #define PAGE_4K_SHIFT   12
  2704. #define PAGE_4K_MASK    (PAGE_4K - 1)
  2705. #define PAGE_4K_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_4K - 1)))
  2706. #define ROUND_TO_4K_PAGES(Size)  (((ULONG_PTR)(Size) + PAGE_4K - 1) & ~(PAGE_4K - 1))
  2707. #define PAGE_NEXT_ALIGN(Va) ((PVOID)(PAGE_ALIGN((ULONG_PTR)Va + PAGE_SIZE - 1)))
  2708. #define BYTES_TO_4K_PAGES(Size)  ((ULONG)((ULONG_PTR)(Size) >> PAGE_4K_SHIFT) + 
  2709.                                (((ULONG)(Size) & (PAGE_4K - 1)) != 0))
  2710. //
  2711. // Relative constants between native pages and 4K pages
  2712. //
  2713. #define SPLITS_PER_PAGE (PAGE_SIZE / PAGE_4K)
  2714. #define PAGE_SHIFT_DIFF (PAGE_SHIFT - PAGE_4K_SHIFT)
  2715. #define ALT_PTE_SHIFT 3
  2716. #define ALT_PROTECTION_MASK (MM_PTE_EXECUTE_MASK|MM_PTE_WRITE_MASK)
  2717. #define MiGetAltPteAddress(VA) 
  2718.       ((PMMPTE) (ALT4KB_PERMISSION_TABLE_START + 
  2719.                      ((((ULONG_PTR) (VA)) >> PAGE_4K_SHIFT) << ALT_PTE_SHIFT)))
  2720. //
  2721. // define Alternate 4k table flags
  2722. //
  2723. #define MI_ALTFLG_FLUSH2G         0x0000000000000001
  2724. //
  2725. // define MiProtectFor4kPage flages
  2726. //
  2727. #define ALT_ALLOCATE      1
  2728. #define ALT_COMMIT        2
  2729. #define ALT_CHANGE        4
  2730. //
  2731. // define ATE protection bits
  2732. //
  2733. #define MM_ATE_COMMIT             0x0000000000000001
  2734. #define MM_ATE_ACCESS             0x0000000000000020
  2735. #define MM_ATE_READONLY           0x0000000000000200
  2736. #define MM_ATE_EXECUTE            0x0400000000000200  
  2737. #define MM_ATE_EXECUTE_READ       0x0400000000000200
  2738. #define MM_ATE_READWRITE          0x0000000000000600
  2739. #define MM_ATE_WRITECOPY          0x0020000000000200
  2740. #define MM_ATE_EXECUTE_READWRITE  0x0400000000000600
  2741. #define MM_ATE_EXECUTE_WRITECOPY  0x0420000000000400
  2742. #define MM_ATE_ZEROFILL           0x0800000000000000
  2743. #define MM_ATE_NOACCESS           0x1000000000000000
  2744. #define MM_ATE_COPY_ON_WRITE      0x2000000000000000
  2745. #define MM_ATE_PRIVATE            0x8000000000000000
  2746. #define MM_ATE_PROTO_MASK         0x0000000000000621
  2747. //
  2748. // How big is the IA32 subsystem allowed?
  2749. // Assume it will be "not Large Address Aware" so limited to 2G
  2750. //
  2751. #define _MAX_WOW64_ADDRESS       (0x00000000080000000UI64)
  2752. MmX86Fault (
  2753.     IN BOOLEAN StoreInstruction,
  2754.     IN PVOID VirtualAddress, 
  2755.     IN KPROCESSOR_MODE PreviousMode,
  2756.     IN PVOID TrapInformation
  2757.     );
  2758. VOID
  2759. MiProtectFor4kPage(
  2760.     IN PVOID Base,
  2761.     IN SIZE_T Size,
  2762.     IN ULONG NewProtect,
  2763.     IN ULONG Flags,
  2764.     IN PEPROCESS Process
  2765.     );
  2766. VOID
  2767. MiProtectMapFileFor4kPage(
  2768.     IN PVOID Base,
  2769.     IN SIZE_T Size,
  2770.     IN ULONG NewProtect,
  2771.     IN PMMPTE PointerPte,
  2772.     IN PEPROCESS Process
  2773.     );
  2774. VOID
  2775. MiProtectImageFileFor4kPage(
  2776.     IN PVOID Base,
  2777.     IN SIZE_T Size,
  2778.     IN PMMPTE PointerPte,
  2779.     IN PEPROCESS Process
  2780.     );
  2781. VOID
  2782. MiReleaseFor4kPage(
  2783.     IN PVOID StartVirtual,
  2784.     IN PVOID EndVirtual,
  2785.     IN PEPROCESS Process
  2786.     );
  2787. VOID
  2788. MiDecommitFor4kPage(
  2789.     IN PVOID StartVirtual,
  2790.     IN PVOID EndVirtual,
  2791.     IN PEPROCESS Process
  2792.     );
  2793. VOID
  2794. MiDeleteFor4kPage(
  2795.     IN PVOID StartVirtual,
  2796.     IN PVOID EndVirtual,
  2797.     IN PEPROCESS Process
  2798.     );
  2799. VOID
  2800. MiQueryRegionFor4kPage(
  2801.     IN PVOID BaseAddress,
  2802.     IN PVOID EndAddress,
  2803.     IN OUT PSIZE_T RegionSize,
  2804.     IN OUT PULONG RegionState,
  2805.     IN OUT PULONG RegionProtect,
  2806.     IN PEPROCESS Process
  2807.     );
  2808. ULONG
  2809. MiQueryProtectionFor4kPage (
  2810.     IN PVOID BaseAddress,
  2811.     IN PEPROCESS Process
  2812.     );
  2813. NTSTATUS
  2814. MiInitializeAlternateTable(
  2815.     PEPROCESS Process
  2816.     );
  2817. VOID
  2818. MiDeleteAlternateTable(
  2819.     PEPROCESS Process
  2820.     );
  2821. VOID
  2822. MiLockFor4kPage(
  2823.     PVOID CapturedBase,
  2824.     SIZE_T CapturedRegionSize,
  2825.     PEPROCESS Process
  2826.     );
  2827. NTSTATUS
  2828. MiUnlockFor4kPage(
  2829.     PVOID CapturedBase,
  2830.     SIZE_T CapturedRegionSize,
  2831.     PEPROCESS Process
  2832.     );
  2833. BOOLEAN
  2834. MiShouldBeUnlockedFor4kPage(
  2835.     PVOID VirtualAddress,
  2836.     PEPROCESS Process
  2837.     );
  2838. VOID
  2839. MiMarkSplitPages(
  2840.     IN PVOID StartVirtual,
  2841.     IN PVOID EndVirtual,
  2842.     IN PULONG Bitmap,
  2843.     IN BOOLEAN SetBit
  2844.     );
  2845. ULONG
  2846. MiMakeProtectForNativePage(
  2847.     IN PVOID VirtualAddress,
  2848.     IN ULONG NewProtect,
  2849.     IN PEPROCESS Process
  2850.     );
  2851. extern ULONG MmProtectToPteMaskForIA32[32];
  2852. extern ULONG MmProtectToPteMaskForSplit[32];
  2853. extern ULONGLONG MmProtectToAteMask[32];
  2854. #define MiMakeProtectionAteMask(NewProtect) MmProtectToAteMask[NewProtect]
  2855. #define _ALTPERM_BITMAP_MASK ((_MAX_WOW64_ADDRESS - 1) >> PTI_SHIFT)
  2856. #if 1
  2857. #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE)                           
  2858.        (OUTPTE).u.Long = 0;                                                  
  2859.        (OUTPTE).u.Hard.Valid = 1;                                            
  2860.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                         
  2861.        (OUTPTE).u.Hard.Exception = 1;                                        
  2862.        (OUTPTE).u.Hard.PageFrameNumber = FRAME;                              
  2863.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                     
  2864.   PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; 
  2865.   if ((_Wow64Process != NULL) && 
  2866.       ((PPTE >= (PMMPTE)PTE_UBASE) && 
  2867.        (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) {  
  2868.       if (MI_CHECK_BIT(_Wow64Process->AltPermBitmap, 
  2869.              ((ULONG_PTR)PPTE >> PTE_SHIFT) & _ALTPERM_BITMAP_MASK) != 0) { 
  2870.           (OUTPTE).u.Long |= (MmProtectToPteMaskForSplit[PMASK]); 
  2871.       } else { 
  2872.           (OUTPTE).u.Long |= (MmProtectToPteMaskForIA32[PMASK]); 
  2873.           (OUTPTE).u.Hard.Accessed = 1; 
  2874.       } 
  2875.   } else { 
  2876.       (OUTPTE).u.Hard.Accessed = 1; 
  2877.       (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]);
  2878.   }
  2879. }
  2880. #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE)                        
  2881.         ASSERT (((PPTE)->u.Hard.Valid == 0) &&                           
  2882.                 ((PPTE)->u.Trans.Prototype == 0) &&                      
  2883.                 ((PPTE)->u.Trans.Transition == 1));                      
  2884.        (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000;                
  2885.        (OUTPTE).u.Hard.Valid = 1;                                        
  2886.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                     
  2887.        (OUTPTE).u.Hard.Exception = 1;                                    
  2888.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                 
  2889.   PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; 
  2890.   if ((_Wow64Process != NULL) && 
  2891.       ((PPTE >= (PMMPTE)PTE_UBASE) && 
  2892.        (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { 
  2893.       if (MI_CHECK_BIT(_Wow64Process->AltPermBitmap, 
  2894.              ((ULONG_PTR)PPTE >> PTE_SHIFT) & _ALTPERM_BITMAP_MASK) != 0) { 
  2895.           (OUTPTE).u.Long |= (MmProtectToPteMaskForSplit[(PPTE)->u.Trans.Protection]); 
  2896.       } else { 
  2897.           (OUTPTE).u.Long |= (MmProtectToPteMaskForIA32[(PPTE)->u.Trans.Protection]); 
  2898.           (OUTPTE).u.Hard.Accessed = 1; 
  2899.       } 
  2900.   } else { 
  2901.       (OUTPTE).u.Hard.Accessed = 1; 
  2902.       (OUTPTE).u.Long |=(MmProtectToPteMask[(PPTE)->u.Trans.Protection]);
  2903.   }
  2904. }
  2905. #else
  2906. #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE)                           
  2907.        (OUTPTE).u.Long = 0;                                                  
  2908.        (OUTPTE).u.Hard.Valid = 1;                                            
  2909.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                         
  2910.        (OUTPTE).u.Hard.Exception = 1;                                        
  2911.        (OUTPTE).u.Hard.PageFrameNumber = FRAME;                              
  2912.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                     
  2913.   PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; 
  2914.   if ((_Wow64Process != NULL) && 
  2915.       ((PPTE >= (PMMPTE)PTE_UBASE) && 
  2916.        (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) {  
  2917.       (OUTPTE).u.Long |= MM_PTE_READONLY; 
  2918.   } else { 
  2919.       (OUTPTE).u.Hard.Accessed = 1; 
  2920.       (OUTPTE).u.Long |= (MmProtectToPteMask[PMASK]);
  2921.   }
  2922. }
  2923. #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE)                        
  2924.         ASSERT (((PPTE)->u.Hard.Valid == 0) &&                           
  2925.                 ((PPTE)->u.Trans.Prototype == 0) &&                      
  2926.                 ((PPTE)->u.Trans.Transition == 1));                      
  2927.        (OUTPTE).u.Long = (PPTE)->u.Long & 0x1FFFFFFFE000;                
  2928.        (OUTPTE).u.Hard.Valid = 1;                                        
  2929.        (OUTPTE).u.Hard.Cache = MM_PTE_CACHE_ENABLED;                     
  2930.        (OUTPTE).u.Hard.Exception = 1;                                    
  2931.        (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE);                 
  2932.   PWOW64_PROCESS _Wow64Process = PsGetCurrentProcess()->Wow64Process; 
  2933.   if ((_Wow64Process != NULL) && 
  2934.       ((PPTE >= (PMMPTE)PTE_UBASE) && 
  2935.        (PPTE < MiGetPteAddress(_MAX_WOW64_ADDRESS)))) { 
  2936.       (OUTPTE).u.Long |= MM_PTE_READONLY; 
  2937.   } else { 
  2938.       (OUTPTE).u.Hard.Accessed = 1; 
  2939.       (OUTPTE).u.Long |=(MmProtectToPteMask[(PPTE)->u.Trans.Protection]);
  2940.   }
  2941. }
  2942. #endif
  2943. #define LOCK_ALTERNATE_TABLE(PWOW64) 
  2944.         ExAcquireFastMutex( &(PWOW64)->AlternateTableLock)
  2945. #define UNLOCK_ALTERNATE_TABLE(PWOW64) 
  2946.         ExReleaseFastMutex(&(PWOW64)->AlternateTableLock)
  2947. #define MI_IS_ALT_PAGE_TABLE_ADDRESS(PPTE) 
  2948.             (((PPTE) >= (PMMPTE)ALT4KB_PERMISSION_TABLE_START) && 
  2949.              ((PPTE) < (PMMPTE)ALT4KB_PERMISSION_TABLE_END))
  2950. #endif
  2951. //++
  2952. //VOID
  2953. //MI_BARRIER_SYNCHRONIZE (
  2954. //    IN ULONG TimeStamp
  2955. //    );
  2956. //
  2957. // Routine Description:
  2958. //
  2959. //    MI_BARRIER_SYNCHRONIZE compares the argument timestamp against the
  2960. //    current IPI barrier sequence stamp.  When equal, all processors will
  2961. //    issue memory barriers to ensure that newly created pages remain coherent.
  2962. //
  2963. //    When a page is put in the zeroed or free page list the current
  2964. //    barrier sequence stamp is read (interlocked - this is necessary
  2965. //    to get the correct value - memory barriers won't do the trick)
  2966. //    and stored in the pfn entry for the page. The current barrier
  2967. //    sequence stamp is maintained by the IPI send logic and is
  2968. //    incremented (interlocked) when the target set of an IPI send
  2969. //    includes all processors, but the one doing the send. When a page
  2970. //    is needed its sequence number is compared against the current
  2971. //    barrier sequence number.  If it is equal, then the contents of
  2972. //    the page may not be coherent on all processors, and an IPI must
  2973. //    be sent to all processors to ensure a memory barrier is
  2974. //    executed (generic call can be used for this). Sending the IPI
  2975. //    automatically updates the barrier sequence number. The compare
  2976. //    is for equality as this is the only value that requires the IPI
  2977. //    (i.e., the sequence number wraps, values in both directions are
  2978. //    older). When a page is removed in this fashion and either found
  2979. //    to be coherent or made coherent, it cannot be modified between
  2980. //    that time and writing the PTE. If the page is modified between
  2981. //    these times, then an IPI must be sent.
  2982. //
  2983. // Arguments
  2984. //
  2985. //    TimeStamp - Supplies the timestamp at the time when the page was zeroed.
  2986. //
  2987. // Return Value:
  2988. //
  2989. //    None.
  2990. //
  2991. //--
  2992. // currently does nothing on MERCED.
  2993. #define MI_BARRIER_SYNCHRONIZE(TimeStamp)
  2994. //++
  2995. //VOID
  2996. //MI_BARRIER_STAMP_ZEROED_PAGE (
  2997. //    IN PULONG PointerTimeStamp
  2998. //    );
  2999. //
  3000. // Routine Description:
  3001. //
  3002. //    MI_BARRIER_STAMP_ZEROED_PAGE issues an interlocked read to get the
  3003. //    current IPI barrier sequence stamp.  This is called AFTER a page is
  3004. //    zeroed.
  3005. //
  3006. // Arguments
  3007. //
  3008. //    PointerTimeStamp - Supplies a timestamp pointer to fill with the
  3009. //                       current IPI barrier sequence stamp.
  3010. //
  3011. // Return Value:
  3012. //
  3013. //    None.
  3014. //
  3015. //--
  3016. // currently does nothing on MERCED.
  3017. #define MI_BARRIER_STAMP_ZEROED_PAGE(PointerTimeStamp)
  3018. //++
  3019. //VOID
  3020. //MI_FLUSH_SINGLE_SESSION_TB (
  3021. //    IN PVOID Virtual,
  3022. //    IN ULONG Invalid,
  3023. //    IN LOGICAL AllProcessors,
  3024. //    IN PMMPTE PtePointer,
  3025. //    IN MMPTE PteValue,
  3026. //    IN MMPTE PreviousPte
  3027. //    );
  3028. //
  3029. // Routine Description:
  3030. //
  3031. //    MI_FLUSH_SINGLE_SESSION_TB flushes the requested single address
  3032. //    translation from the TB.  
  3033. //
  3034. //    Since IA64 supports ASNs and session space doesn't have one, the entire
  3035. //    TB needs to be flushed.
  3036. //
  3037. // Arguments
  3038. //
  3039. //    Virtual - Supplies the virtual address to invalidate.
  3040. //
  3041. //    Invalid - TRUE if invalidating.
  3042. //
  3043. //    AllProcessors - TRUE if all processors need to be IPI'd.
  3044. //
  3045. //    PtePointer - Supplies the PTE to invalidate.
  3046. //
  3047. //    PteValue - Supplies the new PTE value.
  3048. //
  3049. //    PreviousPte - The previous PTE value is returned here.
  3050. //
  3051. // Return Value:
  3052. //
  3053. //    None.
  3054. //
  3055. //--
  3056. #define MI_FLUSH_SINGLE_SESSION_TB(Virtual, Invalid, AllProcessors, PtePointer, PteValue, PreviousPte) 
  3057.     PreviousPte.u.Flush = *PtePointer;                  
  3058.     *PtePointer = PteValue;                             
  3059.     KeFlushEntireTb (TRUE, TRUE);
  3060. //++
  3061. //VOID
  3062. //MI_FLUSH_ENTIRE_SESSION_TB (
  3063. //    IN ULONG Invalid,
  3064. //    IN LOGICAL AllProcessors
  3065. //    );
  3066. //
  3067. // Routine Description:
  3068. //
  3069. //    MI_FLUSH_ENTIRE_SESSION_TB flushes the entire TB on IA64 since
  3070. //    the IA64 supports ASNs.
  3071. //
  3072. // Arguments
  3073. //
  3074. //    Invalid - TRUE if invalidating.
  3075. //
  3076. //    AllProcessors - TRUE if all processors need to be IPI'd.
  3077. //
  3078. // Return Value:
  3079. //
  3080. //    None.
  3081. //
  3082. #define MI_FLUSH_ENTIRE_SESSION_TB(Invalid, AllProcessors) 
  3083.     KeFlushEntireTb (Invalid, AllProcessors);
  3084. VOID
  3085. MiSweepCacheMachineDependent(
  3086.     IN PVOID VirtualAddress,
  3087.     IN SIZE_T Size,
  3088.     IN MEMORY_CACHING_TYPE CacheType
  3089.     );
  3090. #define MI_IS_PCR_PAGE(Va) (((PVOID)PCR <= Va) && (Va < (PVOID)(PCR+PAGE_SIZE)))
  3091. //++
  3092. //BOOLEAN
  3093. //MI_IS_ADDRESS_VALID_FOR_KD (
  3094. //    IN PVOID VirtualAddress
  3095. //    );
  3096. //
  3097. // Routine Description:
  3098. //
  3099. //    This macro deterines if a give virtual address is really a valid 
  3100. //    virtual address for the kerenl debugger memory references
  3101. //
  3102. // Argments
  3103. //
  3104. //    VirtualAddress - Supplies the virtual address.
  3105. //
  3106. // Return Value:
  3107. //
  3108. //    FALSE if it is not a physical address, TRUE if it is.
  3109. //
  3110. //--
  3111. #define MI_IS_ADDRESS_VALID_FOR_KD(VirtualAddress)  
  3112.          ((VirtualAddress <= (PVOID)(HYPER_SPACE_END)) || 
  3113.           (MI_IS_PTE_ADDRESS((PMMPTE)VirtualAddress)) || 
  3114.           (MI_IS_PAGE_DIRECTORY_ADDRESS((PMMPTE)VirtualAddress)) || 
  3115.           (MI_IS_PPE_ADDRESS((PMMPTE)VirtualAddress)) || 
  3116.           ((VirtualAddress >= MM_SYSTEM_RANGE_START) && 
  3117.            (VirtualAddress < (PVOID)MM_SYSTEM_SPACE_END)) || 
  3118.           (MI_IS_SESSION_ADDRESS(VirtualAddress)) || 
  3119.           (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) || 
  3120.           (MI_IS_PCR_PAGE(VirtualAddress)))