Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2788 lines
60 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Copyright (c) 1992 Digital Equipment Corporation
  4. Module Name:
  5. mialpha.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. It is specifically tailored for the DEC ALPHA architecture.
  11. Author:
  12. Lou Perazzoli (loup) 12-Mar-1990
  13. Joe Notarangelo 23-Apr-1992 ALPHA version
  14. Revision History:
  15. --*/
  16. /*++
  17. Virtual Memory Layout on an ALPHA is:
  18. +------------------------------------+
  19. 00000000 | |
  20. | |
  21. | |
  22. | User Mode Addresses |
  23. | |
  24. | All pages within this range |
  25. | are potentially accessible while |
  26. | the CPU is in USER mode. |
  27. | |
  28. | |
  29. +------------------------------------+
  30. 7ffff000 | 64k No Access Area |
  31. +------------------------------------+
  32. 80000000 | | KSEG_0
  33. | HAL loads kernel and initial |
  34. | boot drivers in first 16mb |
  35. | of this region. |
  36. | Kernel mode access only. |
  37. | |
  38. | Initial NonPaged Pool is within |
  39. | KEG_0 |
  40. | |
  41. +------------------------------------+
  42. C0000000 | Page Table Pages mapped through |
  43. | this 16mb region |
  44. | Kernel mode access only. |
  45. | (only using 2MB) |
  46. +------------------------------------+
  47. C1000000 | HyperSpace - working set lists |
  48. | and per process memory management |
  49. | structures mapped in this 16mb |
  50. | region. |
  51. | Kernel mode access only. |
  52. +------------------------------------+
  53. C2000000 | VLM PTEs |
  54. | |
  55. | |
  56. +------------------------------------+
  57. C3000000 | System Cache Structures |
  58. | reside in this 16mb region |
  59. | Kernel mode access only. |
  60. +------------------------------------+
  61. C4000000 | System cache resides here. |
  62. | Kernel mode access only. |
  63. | |
  64. | |
  65. +------------------------------------+
  66. DE000000 | System mapped views |
  67. | |
  68. | |
  69. +------------------------------------+
  70. E1000000 | Start of paged system area |
  71. | Kernel mode access only. |
  72. | |
  73. | |
  74. | |
  75. F0000000 +------------------------------------+
  76. | |
  77. | Kernel mode access only. |
  78. | |
  79. | |
  80. | NonPaged System area |
  81. +------------------------------------+
  82. FE000000 | |
  83. | Reserved for the HAL. |
  84. | |
  85. | |
  86. FFFFFFFF | |
  87. +------------------------------------+
  88. --*/
  89. #define _MI_PAGING_LEVELS 2
  90. //
  91. // Define empty list markers.
  92. //
  93. #define MM_EMPTY_LIST ((ULONG)0xFFFFFFFF) //
  94. #define MM_EMPTY_PTE_LIST ((ULONG)0xFFFFF) // N.B. tied to MMPTE definition
  95. #define MI_PTE_BASE_FOR_LOWEST_KERNEL_ADDRESS (MiGetPteAddress (0x80000000))
  96. //
  97. // Define start of KSEG0.
  98. //
  99. #define MM_KSEG0_BASE ((ULONG)0x80000000)
  100. //
  101. // Address space definitions.
  102. //
  103. #define MmProtopte_Base ((ULONG)0xE1000000)
  104. #define PTE_TOP (0xC01FFFFF)
  105. #define PDE_TOP (0xC01FFFFF)
  106. #define PDE_BASE64 ((ULONG)0xC0184000)
  107. #define PTE_BASE64 ((ULONG)0xC2000000)
  108. #define MM_PAGES_IN_KSEG0 (((ULONG)KSEG2_BASE - (ULONG)KSEG0_BASE) >> PAGE_SHIFT)
  109. #define MM_USER_ADDRESS_RANGE_LIMIT 0xFFFFFFFF // user address range limit
  110. #define MM_MAXIMUM_ZERO_BITS 21 // maximum number of zero bits
  111. #define MM_SYSTEM_SPACE_START (0xC3000000)
  112. #define MM_SYSTEM_CACHE_START (0xC4000000)
  113. #define MM_SYSTEM_CACHE_END (0xDE000000)
  114. #define MM_SESSION_SPACE_DEFAULT (0xDE000000)
  115. #define MM_MAXIMUM_SYSTEM_CACHE_SIZE \
  116. ( ((ULONG)MM_SYSTEM_CACHE_END - (ULONG)MM_SYSTEM_CACHE_START) >> PAGE_SHIFT )
  117. #define MM_SYSTEM_CACHE_WORKING_SET (0xC3000000)
  118. //
  119. // Define area for mapping views into system space.
  120. //
  121. #define MM_SYSTEM_VIEW_START (0xDE000000)
  122. #define MM_SYSTEM_VIEW_SIZE (16*1024*1024)
  123. #define MM_PAGED_POOL_START ((PVOID)0xE1000000)
  124. #define MM_LOWEST_NONPAGED_SYSTEM_START ((PVOID)0xEB000000)
  125. #define MM_NONPAGED_POOL_END ((PVOID)(0xFE000000-(16*PAGE_SIZE)))
  126. #define NON_PAGED_SYSTEM_END ((PVOID)0xFFFFFFF0) //quadword aligned.
  127. #define MM_SYSTEM_SPACE_END (0xFFFFFFFF)
  128. #define HYPER_SPACE_END (0xC1FFFFFF)
  129. //
  130. // Define absolute minimum and maximum count for system PTEs.
  131. //
  132. #define MM_MINIMUM_SYSTEM_PTES 5000
  133. #define MM_MAXIMUM_SYSTEM_PTES 20000
  134. #define MM_DEFAULT_SYSTEM_PTES 11000
  135. //
  136. // Pool limits.
  137. //
  138. //
  139. // The maximum amount of nonpaged pool that can be initially created.
  140. //
  141. #define MM_MAX_INITIAL_NONPAGED_POOL ((ULONG)(128*1024*1024))
  142. //
  143. // The total amount of nonpaged expansion pool.
  144. //
  145. #define MM_MAX_ADDITIONAL_NONPAGED_POOL ((ULONG)(128*1024*1024))
  146. //
  147. // The maximum amount of paged pool that can be created.
  148. //
  149. #define MM_MAX_PAGED_POOL ((ULONG)(240*1024*1024))
  150. //
  151. // Define the maximum default for pool (user specified 0 in registry).
  152. //
  153. #define MM_MAX_DEFAULT_NONPAGED_POOL ((ULONG)(128*1024*1024))
  154. #define MM_MAX_DEFAULT_PAGED_POOL ((ULONG)(128*1024*1024))
  155. //
  156. // The maximum total pool.
  157. //
  158. #define MM_MAX_TOTAL_POOL \
  159. (((ULONG)MM_NONPAGED_POOL_END) - ((ULONG)MM_PAGED_POOL_START))
  160. //
  161. // Granularity Hint definitions
  162. //
  163. //
  164. // Granularity Hint = 3, page size = 8**3 * PAGE_SIZE
  165. //
  166. #define GH3 (3)
  167. #define GH3_PAGE_SIZE (PAGE_SIZE << 9)
  168. //
  169. // Granularity Hint = 2, page size = 8**2 * PAGE_SIZE
  170. //
  171. #define GH2 (2)
  172. #define GH2_PAGE_SIZE (PAGE_SIZE << 6)
  173. //
  174. // Granularity Hint = 1, page size = 8**1 * PAGE_SIZE
  175. //
  176. #define GH1 (1)
  177. #define GH1_PAGE_SIZE (PAGE_SIZE << 3)
  178. //
  179. // Granularity Hint = 0, page size = PAGE_SIZE
  180. //
  181. #define GH0 (0)
  182. #define GH0_PAGE_SIZE PAGE_SIZE
  183. //
  184. // Physical memory size and boundary constants.
  185. //
  186. #define __1GB (0x40000000)
  187. //
  188. // PAGE_SIZE for ALPHA (at least current implementation) is 8k
  189. // PAGE_SHIFT bytes for an offset leaves 19
  190. //
  191. #define MM_VIRTUAL_PAGE_FILLER 1
  192. #define MM_VIRTUAL_PAGE_SIZE 19
  193. #define MM_PROTO_PTE_ALIGNMENT ((ULONG)MM_MAXIMUM_NUMBER_OF_COLORS * (ULONG)PAGE_SIZE)
  194. //
  195. // Define maximum number of paging files
  196. //
  197. #define MAX_PAGE_FILES (8)
  198. #define PAGE_DIRECTORY_MASK ((ULONG)0x00FFFFFF)
  199. #define MM_VA_MAPPED_BY_PDE (0x1000000)
  200. #define LOWEST_IO_ADDRESS (0)
  201. #define PTE_SHIFT (2)
  202. //
  203. // 64-bit VA support.
  204. //
  205. #if 0
  206. #define MM_LOWEST_USER_ADDRESS64 ((PVOID64)(0x100000000))
  207. #define MM_HIGHEST_USER_ADDRESS64 ((PVOID64)(0x7FFFFFFFF))
  208. #endif
  209. #define MM_HIGHEST_VAD_ADDRESS64 ((PVOID64)(0x800000000))
  210. //
  211. // Number of physical address bits, maximum for ALPHA architecture = 48.
  212. //
  213. #define PHYSICAL_ADDRESS_BITS (48)
  214. #define MM_MAXIMUM_NUMBER_OF_COLORS (1)
  215. //
  216. // i386 does not require support for colored pages.
  217. //
  218. #define MM_NUMBER_OF_COLORS (1)
  219. //
  220. // Mask for obtaining color from a physical page number.
  221. //
  222. #define MM_COLOR_MASK (0)
  223. //
  224. // Boundary for aligned pages of like color upon.
  225. //
  226. #define MM_COLOR_ALIGNMENT (0)
  227. //
  228. // Mask for isolating color from virtual address.
  229. //
  230. #define MM_COLOR_MASK_VIRTUAL (0)
  231. //
  232. // Define 1mb worth of secondary colors.
  233. //
  234. #define MM_SECONDARY_COLORS_DEFAULT ((1024*1024) >> PAGE_SHIFT)
  235. #define MM_SECONDARY_COLORS_MIN (2)
  236. #define MM_SECONDARY_COLORS_MAX (2048)
  237. //
  238. // Hyper space definitions.
  239. //
  240. #define HYPER_SPACE ((PVOID)0xC1000000)
  241. #define FIRST_MAPPING_PTE ((ULONG)0xC1000000)
  242. #define NUMBER_OF_MAPPING_PTES (1023)
  243. #define LAST_MAPPING_PTE \
  244. ((ULONG)((ULONG)FIRST_MAPPING_PTE + (NUMBER_OF_MAPPING_PTES * PAGE_SIZE)))
  245. #define IMAGE_MAPPING_PTE ((PMMPTE)((ULONG)LAST_MAPPING_PTE + PAGE_SIZE))
  246. #define ZEROING_PAGE_PTE ((PMMPTE)((ULONG)IMAGE_MAPPING_PTE + PAGE_SIZE))
  247. #define WORKING_SET_LIST ((PVOID)((ULONG)ZEROING_PAGE_PTE + PAGE_SIZE))
  248. #define MM_MAXIMUM_WORKING_SET \
  249. ((ULONG)((ULONG)2*1024*1024*1024 - 64*1024*1024) >> PAGE_SHIFT) //2Gb-64Mb
  250. #define MM_WORKING_SET_END ((ULONG)0xC2000000)
  251. #define MmWorkingSetList ((PMMWSL)WORKING_SET_LIST)
  252. #define MmWsle ((PMMWSLE)((PUCHAR)WORKING_SET_LIST + sizeof(MMWSL)))
  253. #define MM_PTE_VALID_MASK (0x1)
  254. #define MM_PTE_PROTOTYPE_MASK (0x2)
  255. #define MM_PTE_DIRTY_MASK (0x4)
  256. #define MM_PTE_TRANSITION_MASK (0x4)
  257. #define MM_PTE_GLOBAL_MASK (0x10)
  258. #define MM_PTE_WRITE_MASK (0x80)
  259. #define MM_PTE_COPY_ON_WRITE_MASK (0x100)
  260. #define MM_PTE_OWNER_MASK (0x2)
  261. //
  262. // Bit fields to or into PTE to make a PTE valid based on the
  263. // protection field of the invalid PTE.
  264. //
  265. #define MM_PTE_NOACCESS (0x0) // not expressable on ALPHA
  266. #define MM_PTE_READONLY (0x0)
  267. #define MM_PTE_READWRITE (MM_PTE_WRITE_MASK)
  268. #define MM_PTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK)
  269. #define MM_PTE_EXECUTE (0x0) // read-only on ALPHA
  270. #define MM_PTE_EXECUTE_READ (0x0)
  271. #define MM_PTE_EXECUTE_READWRITE (MM_PTE_WRITE_MASK)
  272. #define MM_PTE_EXECUTE_WRITECOPY (MM_PTE_WRITE_MASK | MM_PTE_COPY_ON_WRITE_MASK)
  273. #define MM_PTE_NOCACHE (0x0) // not expressable on ALPHA
  274. #define MM_PTE_GUARD (0x0) // not expressable on ALPHA
  275. #define MM_PTE_CACHE (0x0)
  276. #define MM_PROTECT_FIELD_SHIFT 3
  277. //
  278. // Bits available for the software working set index within the hardware PTE.
  279. //
  280. #define MI_MAXIMUM_PTE_WORKING_SET_INDEX 0
  281. //
  282. // Zero PTE
  283. //
  284. #define MM_ZERO_PTE 0
  285. //
  286. // Zero Kernel PTE
  287. //
  288. #define MM_ZERO_KERNEL_PTE 0
  289. //
  290. // A demand zero PTE with a protection or PAGE_READWRITE.
  291. //
  292. #define MM_DEMAND_ZERO_WRITE_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT)
  293. //
  294. // A demand zero PTE with a protection or PAGE_READWRITE for system space.
  295. //
  296. #define MM_KERNEL_DEMAND_ZERO_PTE (MM_READWRITE << MM_PROTECT_FIELD_SHIFT)
  297. //
  298. // A no access PTE for system space.
  299. //
  300. #define MM_KERNEL_NOACCESS_PTE (MM_NOACCESS << MM_PROTECT_FIELD_SHIFT)
  301. //
  302. // Dirty bit definitions for clean and dirty.
  303. //
  304. #define MM_PTE_CLEAN 0
  305. #define MM_PTE_DIRTY 1
  306. //
  307. // Kernel stack alignment requirements.
  308. //
  309. #define MM_STACK_ALIGNMENT (0x0)
  310. #define MM_STACK_OFFSET (0x0)
  311. //
  312. // System process definitions
  313. //
  314. #define PDE_PER_PAGE ((ULONG)256)
  315. #define PTE_PER_PAGE ((ULONG)2048)
  316. //
  317. // Number of page table pages for user addresses.
  318. //
  319. #define MM_USER_PAGE_TABLE_PAGES (128)
  320. //++
  321. //VOID
  322. //MI_MAKE_VALID_PTE (
  323. // OUT OUTPTE,
  324. // IN FRAME,
  325. // IN PMASK,
  326. // IN PPTE
  327. // );
  328. //
  329. // Routine Description:
  330. //
  331. // This macro makes a valid PTE from a page frame number, protection mask,
  332. // and owner.
  333. //
  334. // Arguments
  335. //
  336. // OUTPTE - Supplies the PTE in which to build the transition PTE.
  337. //
  338. // FRAME - Supplies the page frame number for the PTE.
  339. //
  340. // PMASK - Supplies the protection to set in the transition PTE.
  341. //
  342. // PPTE - Supplies a pointer to the PTE which is being made valid.
  343. // For prototype PTEs NULL should be specified.
  344. //
  345. // Return Value:
  346. //
  347. // None.
  348. //
  349. //--
  350. #define MI_MAKE_VALID_PTE(OUTPTE,FRAME,PMASK,PPTE) \
  351. { \
  352. (OUTPTE).u.Long = ( (FRAME << 9) | \
  353. (MmProtectToPteMask[PMASK]) | \
  354. MM_PTE_VALID_MASK ); \
  355. (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER(PPTE); \
  356. if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \
  357. if (MI_IS_SESSION_PTE((PMMPTE)PPTE)) { \
  358. (OUTPTE).u.Hard.Global = 0; \
  359. } else { \
  360. (OUTPTE).u.Hard.Global = 1; \
  361. } \
  362. } else { \
  363. (OUTPTE).u.Hard.Global = 0; \
  364. } \
  365. }
  366. //++
  367. //VOID
  368. //MI_MAKE_VALID_PTE_TRANSITION (
  369. // IN OUT OUTPTE
  370. // IN PROTECT
  371. // );
  372. //
  373. // Routine Description:
  374. //
  375. // This macro takes a valid pte and turns it into a transition PTE.
  376. //
  377. // Arguments
  378. //
  379. // OUTPTE - Supplies the current valid PTE. This PTE is then
  380. // modified to become a transition PTE.
  381. //
  382. // PROTECT - Supplies the protection to set in the transition PTE.
  383. //
  384. // Return Value:
  385. //
  386. // None.
  387. //
  388. //--
  389. #define MI_MAKE_VALID_PTE_TRANSITION(OUTPTE,PROTECT) \
  390. (OUTPTE).u.Soft.Transition = 1; \
  391. (OUTPTE).u.Soft.Valid = 0; \
  392. (OUTPTE).u.Soft.Prototype = 0; \
  393. (OUTPTE).u.Soft.Protection = PROTECT;
  394. //++
  395. //VOID
  396. //MI_MAKE_TRANSITION_PTE (
  397. // OUT OUTPTE,
  398. // IN PAGE,
  399. // IN PROTECT,
  400. // IN PPTE
  401. // );
  402. //
  403. // Routine Description:
  404. //
  405. // This macro takes a valid pte and turns it into a transition PTE.
  406. //
  407. // Arguments
  408. //
  409. // OUTPTE - Supplies the PTE in which to build the transition PTE.
  410. //
  411. // PAGE - Supplies the page frame number for the PTE.
  412. //
  413. // PROTECT - Supplies the protection to set in the transition PTE.
  414. //
  415. // PPTE - Supplies a pointer to the PTE, this is used to determine
  416. // the owner of the PTE.
  417. //
  418. // Return Value:
  419. //
  420. // None.
  421. //
  422. //--
  423. #define MI_MAKE_TRANSITION_PTE(OUTPTE,PAGE,PROTECT,PPTE) \
  424. (OUTPTE).u.Long = 0; \
  425. (OUTPTE).u.Trans.PageFrameNumber = PAGE; \
  426. (OUTPTE).u.Trans.Transition = 1; \
  427. (OUTPTE).u.Trans.Protection = PROTECT;
  428. //++
  429. //VOID
  430. //MI_MAKE_TRANSITION_PTE_VALID (
  431. // OUT OUTPTE,
  432. // IN PPTE
  433. // );
  434. //
  435. // Routine Description:
  436. //
  437. // This macro takes a transition pte and makes it a valid PTE.
  438. //
  439. // Arguments
  440. //
  441. // OUTPTE - Supplies the PTE in which to build the valid PTE.
  442. //
  443. // PPTE - Supplies a pointer to the transition PTE.
  444. //
  445. // Return Value:
  446. //
  447. // None.
  448. //
  449. //--
  450. #define MI_MAKE_TRANSITION_PTE_VALID(OUTPTE,PPTE) \
  451. (OUTPTE).u.Long = (((PPTE)->u.Long & 0xFFFFFE00) | \
  452. (MmProtectToPteMask[(PPTE)->u.Trans.Protection]) | \
  453. MM_PTE_VALID_MASK); \
  454. (OUTPTE).u.Hard.Owner = MI_DETERMINE_OWNER( PPTE ); \
  455. if (((PMMPTE)PPTE) >= MiGetPteAddress(MM_SYSTEM_SPACE_START)) { \
  456. if (MI_IS_SESSION_PTE((PMMPTE)PPTE)) { \
  457. (OUTPTE).u.Hard.Global = 0; \
  458. } else { \
  459. (OUTPTE).u.Hard.Global = 1; \
  460. } \
  461. } else { \
  462. (OUTPTE).u.Hard.Global = 0; \
  463. }
  464. //++
  465. //VOID
  466. //MI_SET_PTE_IN_WORKING_SET (
  467. // OUT PMMPTE PTE,
  468. // IN ULONG WSINDEX
  469. // );
  470. //
  471. // Routine Description:
  472. //
  473. // This macro inserts the specified working set index into the argument PTE.
  474. // Since the Alpha32 PTE has no free bits nothing needs to be done on this
  475. // architecture.
  476. //
  477. // Arguments
  478. //
  479. // OUTPTE - Supplies the PTE in which to insert the working set index.
  480. //
  481. // WSINDEX - Supplies the working set index for the PTE.
  482. //
  483. // Return Value:
  484. //
  485. // None.
  486. //
  487. //--
  488. #define MI_SET_PTE_IN_WORKING_SET(PTE, WSINDEX)
  489. //++
  490. //ULONG WsIndex
  491. //MI_GET_WORKING_SET_FROM_PTE(
  492. // IN PMMPTE PTE
  493. // );
  494. //
  495. // Routine Description:
  496. //
  497. // This macro returns the working set index from the argument PTE.
  498. // Since the Alpha32 PTE has no free bits nothing needs to be done on this
  499. // architecture.
  500. //
  501. // Arguments
  502. //
  503. // PTE - Supplies the PTE to extract the working set index from.
  504. //
  505. // Return Value:
  506. //
  507. // This macro returns the working set index for the argument PTE.
  508. //
  509. //--
  510. #define MI_GET_WORKING_SET_FROM_PTE(PTE) 0
  511. //++
  512. //VOID
  513. //MI_SET_PTE_WRITE_COMBINE (
  514. // IN MMPTE PTE
  515. // );
  516. //
  517. // Routine Description:
  518. //
  519. // This macro sets the write combined bit(s) in the specified PTE.
  520. //
  521. // Arguments
  522. //
  523. // PTE - Supplies the PTE to set dirty.
  524. //
  525. // Return Value:
  526. //
  527. // None.
  528. //
  529. //--
  530. #define MI_SET_PTE_WRITE_COMBINE(PTE)
  531. //++
  532. //VOID
  533. //MI_SET_PTE_DIRTY (
  534. // IN MMPTE PTE
  535. // );
  536. //
  537. // Routine Description:
  538. //
  539. // This macro sets the dirty bit(s) in the specified PTE.
  540. //
  541. // Arguments
  542. //
  543. // PTE - Supplies the PTE to set dirty.
  544. //
  545. // Return Value:
  546. //
  547. // None.
  548. //
  549. //--
  550. #define MI_SET_PTE_DIRTY(PTE) (PTE).u.Hard.Dirty = MM_PTE_DIRTY
  551. //++
  552. //VOID
  553. //MI_SET_PTE_CLEAN (
  554. // IN MMPTE PTE
  555. // );
  556. //
  557. // Routine Description:
  558. //
  559. // This macro clears the dirty bit(s) in the specified PTE.
  560. //
  561. // Arguments
  562. //
  563. // PTE - Supplies the PTE to set clear.
  564. //
  565. // Return Value:
  566. //
  567. // None.
  568. //
  569. //--
  570. #define MI_SET_PTE_CLEAN(PTE) (PTE).u.Hard.Dirty = MM_PTE_CLEAN
  571. //++
  572. //VOID
  573. //MI_IS_PTE_DIRTY (
  574. // IN MMPTE PTE
  575. // );
  576. //
  577. // Routine Description:
  578. //
  579. // This macro checks the dirty bit(s) in the specified PTE.
  580. //
  581. // Arguments
  582. //
  583. // PTE - Supplies the PTE to check.
  584. //
  585. // Return Value:
  586. //
  587. // TRUE if the page is dirty (modified), FALSE otherwise.
  588. //
  589. //--
  590. #define MI_IS_PTE_DIRTY(PTE) ((PTE).u.Hard.Dirty != MM_PTE_CLEAN)
  591. //++
  592. //VOID
  593. //MI_SET_GLOBAL_BIT_IF_SYSTEM (
  594. // OUT OUTPTE,
  595. // IN PPTE
  596. // );
  597. //
  598. // Routine Description:
  599. //
  600. // This macro sets the global bit if the pointer PTE is within
  601. // system space.
  602. //
  603. // Arguments
  604. //
  605. // OUTPTE - Supplies the PTE in which to build the valid PTE.
  606. //
  607. // PPTE - Supplies a pointer to the PTE becoming valid.
  608. //
  609. // Return Value:
  610. //
  611. // None.
  612. //
  613. //--
  614. // Global not implemented in software PTE for Alpha
  615. #define MI_SET_GLOBAL_BIT_IF_SYSTEM(OUTPTE,PPTE)
  616. //++
  617. //VOID
  618. //MI_SET_GLOBAL_STATE (
  619. // IN MMPTE PTE,
  620. // IN ULONG STATE
  621. // );
  622. //
  623. // Routine Description:
  624. //
  625. // This macro sets the global bit in the PTE. if the pointer PTE is within
  626. //
  627. // Arguments
  628. //
  629. // PTE - Supplies the PTE to set global state into.
  630. //
  631. // Return Value:
  632. //
  633. // None.
  634. //
  635. //--
  636. #define MI_SET_GLOBAL_STATE(PTE,STATE) \
  637. (PTE).u.Hard.Global = STATE;
  638. //++
  639. //VOID
  640. //MI_ENABLE_CACHING (
  641. // IN MMPTE PTE
  642. // );
  643. //
  644. // Routine Description:
  645. //
  646. // This macro takes a valid PTE and sets the caching state to be
  647. // enabled.
  648. //
  649. // Arguments
  650. //
  651. // PTE - Supplies a valid PTE.
  652. //
  653. // Return Value:
  654. //
  655. // None.
  656. //
  657. //--
  658. // not implemented on ALPHA
  659. #define MI_ENABLE_CACHING(PTE)
  660. //++
  661. //VOID
  662. //MI_DISABLE_CACHING (
  663. // IN MMPTE PTE
  664. // );
  665. //
  666. // Routine Description:
  667. //
  668. // This macro takes a valid PTE and sets the caching state to be
  669. // disabled.
  670. //
  671. // Arguments
  672. //
  673. // PTE - Supplies a valid PTE.
  674. //
  675. // Return Value:
  676. //
  677. // None.
  678. //
  679. //--
  680. // not implemented on ALPHA
  681. #define MI_DISABLE_CACHING(PTE)
  682. //++
  683. //BOOLEAN
  684. //MI_IS_CACHING_DISABLED (
  685. // IN PMMPTE PPTE
  686. // );
  687. //
  688. // Routine Description:
  689. //
  690. // This macro takes a valid PTE and returns TRUE if caching is
  691. // disabled.
  692. //
  693. // Arguments
  694. //
  695. // PPTE - Supplies a pointer to the valid PTE.
  696. //
  697. // Return Value:
  698. //
  699. // TRUE if caching is disabled, FALSE if it is enabled.
  700. //
  701. //--
  702. // caching is always on for ALPHA
  703. #define MI_IS_CACHING_DISABLED(PPTE) (FALSE)
  704. //++
  705. //VOID
  706. //MI_SET_PFN_DELETED (
  707. // IN PMMPFN PPFN
  708. // );
  709. //
  710. // Routine Description:
  711. //
  712. // This macro takes a pointer to a PFN element and indicates that
  713. // the PFN is no longer in use.
  714. //
  715. // Arguments
  716. //
  717. // PPTE - Supplies a pointer to the PFN element.
  718. //
  719. // Return Value:
  720. //
  721. // none.
  722. //
  723. //--
  724. #define MI_SET_PFN_DELETED(PPFN) \
  725. (((ULONG)(PPFN)->PteAddress &= (ULONG)0x7FFFFFFF))
  726. //++
  727. //BOOLEAN
  728. //MI_IS_PFN_DELETED (
  729. // IN PMMPFN PPFN
  730. // );
  731. //
  732. // Routine Description:
  733. //
  734. // This macro takes a pointer to a PFN element and determines if
  735. // the PFN is no longer in use.
  736. //
  737. // Arguments
  738. //
  739. // PPTE - Supplies a pointer to the PFN element.
  740. //
  741. // Return Value:
  742. //
  743. // TRUE if PFN is no longer used, FALSE if it is still being used.
  744. //
  745. //--
  746. #define MI_IS_PFN_DELETED(PPFN) \
  747. ( ( (ULONG)((PPFN)->PteAddress) & 0x80000000 ) == 0 )
  748. //++
  749. //VOID
  750. //MI_CHECK_PAGE_ALIGNMENT (
  751. // IN ULONG PAGE,
  752. // IN ULONG COLOR
  753. // );
  754. //
  755. // Routine Description:
  756. //
  757. // This macro takes a PFN element number (Page) and checks to see
  758. // if the virtual alignment for the previous address of the page
  759. // is compatible with the new address of the page. If they are
  760. // not compatible, the D cache is flushed.
  761. //
  762. // Arguments
  763. //
  764. // PAGE - Supplies the PFN element.
  765. // COLOR - Supplies the new page color of the page.
  766. //
  767. // Return Value:
  768. //
  769. // none.
  770. //
  771. //--
  772. #define MI_CHECK_PAGE_ALIGNMENT(PAGE,COLOR)
  773. //++
  774. //VOID
  775. //MI_INITIALIZE_HYPERSPACE_MAP (
  776. // VOID
  777. // );
  778. //
  779. // Routine Description:
  780. //
  781. // This macro initializes the PTEs reserved for double mapping within
  782. // hyperspace.
  783. //
  784. // Arguments
  785. //
  786. // None.
  787. //
  788. // Return Value:
  789. //
  790. // None.
  791. //
  792. //--
  793. // not implemented for ALPHA, we use super-pages
  794. #define MI_INITIALIZE_HYPERSPACE_MAP(HYPER_PAGE)
  795. //++
  796. //ULONG
  797. //MI_GET_PAGE_COLOR_FROM_PTE (
  798. // IN PMMPTE PTEADDRESS
  799. // );
  800. //
  801. // Routine Description:
  802. //
  803. // This macro determines the pages color based on the PTE address
  804. // that maps the page.
  805. //
  806. // Arguments
  807. //
  808. // PTEADDRESS - Supplies the PTE address the page is (or was) mapped at.
  809. //
  810. // Return Value:
  811. //
  812. // The page's color.
  813. //
  814. //--
  815. #define MI_GET_PAGE_COLOR_FROM_PTE(PTEADDRESS) \
  816. ((ULONG)((MI_SYSTEM_PAGE_COLOR++) & MmSecondaryColorMask))
  817. //++
  818. //ULONG
  819. //MI_GET_PAGE_COLOR_FROM_VA (
  820. // IN PVOID ADDRESS
  821. // );
  822. //
  823. // Routine Description:
  824. //
  825. // This macro determines the pages color based on the PTE address
  826. // that maps the page.
  827. //
  828. // Arguments
  829. //
  830. // ADDRESS - Supplies the address the page is (or was) mapped at.
  831. //
  832. // Return Value:
  833. //
  834. // The pages color.
  835. //
  836. //--
  837. #define MI_GET_PAGE_COLOR_FROM_VA(ADDRESS) \
  838. ((ULONG)((MI_SYSTEM_PAGE_COLOR++) & MmSecondaryColorMask))
  839. //++
  840. //ULONG
  841. //MI_GET_PAGE_COLOR_FROM_SESSION (
  842. // IN PMM_SESSION_SPACE SessionSpace
  843. // );
  844. //
  845. // Routine Description:
  846. //
  847. // This macro determines the page's color based on the PTE address
  848. // that maps the page.
  849. //
  850. // Arguments
  851. //
  852. // SessionSpace - Supplies the session space the page will be mapped into.
  853. //
  854. // Return Value:
  855. //
  856. // The page's color.
  857. //
  858. //--
  859. #define MI_GET_PAGE_COLOR_FROM_SESSION(_SessionSpace) \
  860. ((ULONG)((_SessionSpace->Color++) & MmSecondaryColorMask))
  861. //++
  862. //ULONG
  863. //MI_PAGE_COLOR_PTE_PROCESS (
  864. // IN PMMPTE PTE,
  865. // IN PUSHORT COLOR
  866. // );
  867. //
  868. // Routine Description:
  869. //
  870. // Select page color for this process.
  871. //
  872. // Arguments
  873. //
  874. // PTE Not used.
  875. // COLOR Value from which color is determined. This
  876. // variable is incremented.
  877. //
  878. // Return Value:
  879. //
  880. // Page color.
  881. //
  882. //--
  883. #define MI_PAGE_COLOR_PTE_PROCESS(PTE,COLOR) \
  884. ((ULONG)((*(COLOR))++) & MmSecondaryColorMask)
  885. //++
  886. //ULONG
  887. //MI_PAGE_COLOR_VA_PROCESS (
  888. // IN PVOID ADDRESS,
  889. // IN PEPROCESS COLOR
  890. // );
  891. //
  892. // Routine Description:
  893. //
  894. // This macro determines the pages color based on the PTE address
  895. // that maps the page.
  896. //
  897. // Arguments
  898. //
  899. // ADDRESS - Supplies the address the page is (or was) mapped at.
  900. //
  901. // Return Value:
  902. //
  903. // The pages color.
  904. //
  905. //--
  906. #define MI_PAGE_COLOR_VA_PROCESS(ADDRESS,COLOR) \
  907. ((ULONG)((*(COLOR))++) & MmSecondaryColorMask)
  908. //++
  909. //ULONG
  910. //MI_GET_NEXT_COLOR (
  911. // IN ULONG COLOR
  912. // );
  913. //
  914. // Routine Description:
  915. //
  916. // This macro returns the next color in the sequence.
  917. //
  918. // Arguments
  919. //
  920. // COLOR - Supplies the color to return the next of.
  921. //
  922. // Return Value:
  923. //
  924. // Next color in sequence.
  925. //
  926. //--
  927. #define MI_GET_NEXT_COLOR(COLOR) ((COLOR+1) & MM_COLOR_MASK)
  928. //++
  929. //ULONG
  930. //MI_GET_PREVIOUS_COLOR (
  931. // IN ULONG COLOR
  932. // );
  933. //
  934. // Routine Description:
  935. //
  936. // This macro returns the previous color in the sequence.
  937. //
  938. // Arguments
  939. //
  940. // COLOR - Supplies the color to return the previous of.
  941. //
  942. // Return Value:
  943. //
  944. // Previous color in sequence.
  945. //
  946. //--
  947. #define MI_GET_PREVIOUS_COLOR(COLOR) ((COLOR-1) & MM_COLOR_MASK)
  948. #define MI_GET_SECONDARY_COLOR(PAGE,PFN) (PAGE & MmSecondaryColorMask)
  949. #define MI_GET_COLOR_FROM_SECONDARY(SECONDARY_COLOR) (0)
  950. //++
  951. //VOID
  952. //MI_GET_MODIFIED_PAGE_BY_COLOR (
  953. // OUT ULONG PAGE,
  954. // IN ULONG COLOR
  955. // );
  956. //
  957. // Routine Description:
  958. //
  959. // This macro returns the first page destined fro a paging
  960. // file with the desired color. It does NOT remove the page
  961. // from its list.
  962. //
  963. // Arguments
  964. //
  965. // PAGE - Returns the page located, the value MM_EMPTY_LIST is
  966. // returned if there is no page of the specified color.
  967. //
  968. // COLOR - Supplies the color of page to locate.
  969. //
  970. // Return Value:
  971. //
  972. // None.
  973. //
  974. //--
  975. #define MI_GET_MODIFIED_PAGE_BY_COLOR(PAGE,COLOR) \
  976. PAGE = MmModifiedPageListByColor[COLOR].Flink
  977. //++
  978. //VOID
  979. //MI_GET_MODIFIED_PAGE_ANY_COLOR (
  980. // OUT ULONG PAGE,
  981. // IN OUT ULONG COLOR
  982. // );
  983. //
  984. // Routine Description:
  985. //
  986. // This macro returns the first page destined for a paging
  987. // file with the desired color. If not page of the desired
  988. // color exists, all colored lists are searched for a page.
  989. // It does NOT remove the page from its list.
  990. //
  991. // Arguments
  992. //
  993. // PAGE - Returns the page located, the value MM_EMPTY_LIST is
  994. // returned if there is no page of the specified color.
  995. //
  996. // COLOR - Supplies the color of the page to locate and returns the
  997. // color of the page located.
  998. //
  999. // Return Value:
  1000. //
  1001. // None.
  1002. //
  1003. //--
  1004. #define MI_GET_MODIFIED_PAGE_ANY_COLOR(PAGE,COLOR) \
  1005. { \
  1006. if( MmTotalPagesForPagingFile == 0 ){ \
  1007. PAGE = MM_EMPTY_LIST; \
  1008. } else { \
  1009. while( MmModifiedPageListByColor[COLOR].Flink == MM_EMPTY_LIST ){ \
  1010. COLOR = MI_GET_NEXT_COLOR(COLOR); \
  1011. } \
  1012. PAGE = MmModifiedPageListByColor[COLOR].Flink; \
  1013. } \
  1014. }
  1015. //++
  1016. //VOID
  1017. //MI_MAKE_VALID_PTE_WRITE_COPY (
  1018. // IN OUT PMMPTE PTE
  1019. // );
  1020. //
  1021. // Routine Description:
  1022. //
  1023. // This macro checks to see if the PTE indicates that the
  1024. // page is writable and if so it clears the write bit and
  1025. // sets the copy-on-write bit.
  1026. //
  1027. // Arguments
  1028. //
  1029. // PTE - Supplies the PTE to operate upon.
  1030. //
  1031. // Return Value:
  1032. //
  1033. // None.
  1034. //
  1035. //--
  1036. #define MI_MAKE_VALID_PTE_WRITE_COPY(PPTE) \
  1037. if ((PPTE)->u.Hard.Write == 1) { \
  1038. (PPTE)->u.Hard.CopyOnWrite = 1; \
  1039. (PPTE)->u.Hard.Dirty = MM_PTE_CLEAN; \
  1040. }
  1041. //++
  1042. //ULONG
  1043. //MI_DETERMINE_OWNER (
  1044. // IN MMPTE PPTE
  1045. // );
  1046. //
  1047. // Routine Description:
  1048. //
  1049. // This macro examines the virtual address of the PTE and determines
  1050. // if the PTE resides in system space or user space.
  1051. //
  1052. // Arguments
  1053. //
  1054. // PTE - Supplies the PTE to operate upon.
  1055. //
  1056. // Return Value:
  1057. //
  1058. // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE.
  1059. //
  1060. //--
  1061. #define MI_DETERMINE_OWNER(PPTE) \
  1062. (((PMMPTE)(PPTE) <= MiHighestUserPte) ? 1 : 0)
  1063. //++
  1064. //VOID
  1065. //MI_SET_ACCESSED_IN_PTE (
  1066. // IN OUT MMPTE PPTE
  1067. // );
  1068. //
  1069. // Routine Description:
  1070. //
  1071. // This macro sets the ACCESSED field in the PTE.
  1072. //
  1073. // Arguments
  1074. //
  1075. // PTE - Supplies the PTE to operate upon.
  1076. //
  1077. // Return Value:
  1078. //
  1079. // 1 if the owner is USER_MODE, 0 if the owner is KERNEL_MODE.
  1080. //
  1081. //--
  1082. #define MI_SET_ACCESSED_IN_PTE(PPTE,ACCESSED)
  1083. //++
  1084. //ULONG
  1085. //MI_GET_ACCESSED_IN_PTE (
  1086. // IN OUT MMPTE PPTE
  1087. // );
  1088. //
  1089. // Routine Description:
  1090. //
  1091. // This macro returns the state of the ACCESSED field in the PTE.
  1092. //
  1093. // Arguments
  1094. //
  1095. // PTE - Supplies the PTE to operate upon.
  1096. //
  1097. // Return Value:
  1098. //
  1099. // The state of the ACCESSED field.
  1100. //
  1101. //--
  1102. #define MI_GET_ACCESSED_IN_PTE(PPTE) 0
  1103. //++
  1104. //VOID
  1105. //MI_SET_OWNER_IN_PTE (
  1106. // IN PMMPTE PPTE
  1107. // IN ULONG OWNER
  1108. // );
  1109. //
  1110. // Routine Description:
  1111. //
  1112. // This macro sets the owner field in the PTE.
  1113. //
  1114. // Arguments
  1115. //
  1116. // PTE - Supplies the PTE to operate upon.
  1117. //
  1118. // Return Value:
  1119. //
  1120. // None.
  1121. //
  1122. //--
  1123. #define MI_SET_OWNER_IN_PTE(PPTE,OWNER) \
  1124. ( (PPTE)->u.Hard.Owner = OWNER )
  1125. //++
  1126. //ULONG
  1127. //MI_GET_OWNER_IN_PTE (
  1128. // IN PMMPTE PPTE
  1129. // );
  1130. //
  1131. // Routine Description:
  1132. //
  1133. // This macro gets the owner field from the PTE.
  1134. //
  1135. // Arguments
  1136. //
  1137. // PTE - Supplies the PTE to operate upon.
  1138. //
  1139. // Return Value:
  1140. //
  1141. // The state of the OWNER field.
  1142. //
  1143. //--
  1144. #define MI_GET_OWNER_IN_PTE(PPTE) \
  1145. ( (PPTE)->u.Hard.Owner )
  1146. //
  1147. // bit mask to clear out fields in a PTE to or in prototype pte offset.
  1148. //
  1149. #define CLEAR_FOR_PROTO_PTE_ADDRESS ((ULONG)0x7)
  1150. // bit mask to clear out fields in a PTE to or in paging file location.
  1151. #define CLEAR_FOR_PAGE_FILE 0x000000F8
  1152. //++
  1153. //VOID
  1154. //MI_SET_PAGING_FILE_INFO (
  1155. // OUT MMPTE OUTPTE,
  1156. // IN MMPTE PPTE,
  1157. // IN ULONG FILEINFO,
  1158. // IN ULONG OFFSET
  1159. // );
  1160. //
  1161. // Routine Description:
  1162. //
  1163. // This macro sets into the specified PTE the supplied information
  1164. // to indicate where the backing store for the page is located.
  1165. //
  1166. // Arguments
  1167. //
  1168. // OUTPTE - Supplies the PTE in which to store the result.
  1169. //
  1170. // PTE - Supplies the PTE to operate upon.
  1171. //
  1172. // FILEINFO - Supplies the number of the paging file.
  1173. //
  1174. // OFFSET - Supplies the offset into the paging file.
  1175. //
  1176. // Return Value:
  1177. //
  1178. // None.
  1179. //
  1180. //--
  1181. #define MI_SET_PAGING_FILE_INFO(OUTPTE,PPTE,FILEINFO,OFFSET) \
  1182. (OUTPTE).u.Long = (PPTE).u.Long; \
  1183. (OUTPTE).u.Long &= CLEAR_FOR_PAGE_FILE; \
  1184. (OUTPTE).u.Long |= ((((FILEINFO) & 0xF) << 8) | ((OFFSET) << 12));
  1185. //++
  1186. //PMMPTE
  1187. //MiPteToProto (
  1188. // IN OUT MMPTE PPTE,
  1189. // IN ULONG FILEINFO,
  1190. // IN ULONG OFFSET
  1191. // );
  1192. //
  1193. // Routine Description:
  1194. //
  1195. // This macro returns the address of the corresponding prototype which
  1196. // was encoded earlier into the supplied PTE.
  1197. //
  1198. // NOTE THAT A PROTOPTE CAN ONLY RESIDE IN PAGED POOL!!!!!!
  1199. //
  1200. // MAX SIZE = 2^(2+7+21) = 2^30 = 1GB.
  1201. //
  1202. // NOTE, that the valid bit must be zero!
  1203. //
  1204. // Arguments
  1205. //
  1206. // lpte - Supplies the PTE to operate upon.
  1207. //
  1208. // Return Value:
  1209. //
  1210. // Pointer to the prototype PTE that backs this PTE.
  1211. //
  1212. //--
  1213. //
  1214. //
  1215. #define MiPteToProto(lpte) \
  1216. ( (PMMPTE)( ( ((lpte)->u.Long >> 4 ) << 2 ) + \
  1217. MmProtopte_Base ) )
  1218. //++
  1219. //ULONG
  1220. //MiProtoAddressForPte (
  1221. // IN PMMPTE proto_va
  1222. // );
  1223. //
  1224. // Routine Description:
  1225. //
  1226. // This macro sets into the specified PTE the supplied information
  1227. // to indicate where the backing store for the page is located.
  1228. // MiProtoAddressForPte returns the bit field to OR into the PTE to
  1229. // reference a prototype PTE. And set the protoPTE bit,
  1230. // MM_PTE_PROTOTYPE_MASK.
  1231. //
  1232. // Arguments
  1233. //
  1234. // proto_va - Supplies the address of the prototype PTE.
  1235. //
  1236. // Return Value:
  1237. //
  1238. // Mask to set into the PTE.
  1239. //
  1240. //--
  1241. #define MiProtoAddressForPte(proto_va) \
  1242. (((((ULONG)proto_va - MmProtopte_Base) << 2) & 0xfffffff0) | \
  1243. MM_PTE_PROTOTYPE_MASK )
  1244. //++
  1245. //ULONG
  1246. //MiProtoAddressForKernelPte (
  1247. // IN PMMPTE proto_va
  1248. // );
  1249. //
  1250. // Routine Description:
  1251. //
  1252. // This macro sets into the specified PTE the supplied information
  1253. // to indicate where the backing store for the page is located.
  1254. // MiProtoAddressForPte returns the bit field to OR into the PTE to
  1255. // reference a prototype PTE. And set the protoPTE bit,
  1256. // MM_PTE_PROTOTYPE_MASK.
  1257. //
  1258. // This macro also sets any other information (such as global bits)
  1259. // required for kernel mode PTEs.
  1260. //
  1261. // Arguments
  1262. //
  1263. // proto_va - Supplies the address of the prototype PTE.
  1264. //
  1265. // Return Value:
  1266. //
  1267. // Mask to set into the PTE.
  1268. //
  1269. //--
  1270. // not different on alpha.
  1271. #define MiProtoAddressForKernelPte(proto_va) MiProtoAddressForPte(proto_va)
  1272. #define MM_SUBSECTION_MAP (128*1024*1024)
  1273. //++
  1274. //PSUBSECTION
  1275. //MiGetSubsectionAddress (
  1276. // IN PMMPTE lpte
  1277. // );
  1278. //
  1279. // Routine Description:
  1280. //
  1281. // This macro takes a PTE and returns the address of the subsection that
  1282. // the PTE refers to. Subsections are quadword structures allocated
  1283. // from nonpaged pool.
  1284. //
  1285. // NOTE THIS MACRO LIMITS THE SIZE OF NON-PAGED POOL!
  1286. // MAXIMUM NONPAGED POOL = 2^(24+3) = 2^27 = 128 MB in both pools.
  1287. //
  1288. //
  1289. // Arguments
  1290. //
  1291. // lpte - Supplies the PTE to operate upon.
  1292. //
  1293. // Return Value:
  1294. //
  1295. // A pointer to the subsection referred to by the supplied PTE.
  1296. //
  1297. //--
  1298. #define MiGetSubsectionAddress(lpte) \
  1299. ( ((lpte)->u.Subsect.WhichPool == 1) ? \
  1300. ((PSUBSECTION)((ULONG)MmSubsectionBase + \
  1301. (((lpte)->u.Long >> 8) << 3) )) \
  1302. : ((PSUBSECTION)((ULONG)MM_NONPAGED_POOL_END - \
  1303. (((lpte)->u.Long >> 8) << 3))) )
  1304. //++
  1305. //ULONG
  1306. //MiGetSubsectionAddressForPte (
  1307. // IN PSUBSECTION VA
  1308. // );
  1309. //
  1310. // Routine Description:
  1311. //
  1312. // This macro takes the address of a subsection and encodes it for use
  1313. // in a PTE.
  1314. //
  1315. // NOTE - THE SUBSECTION ADDRESS MUST BE QUADWORD ALIGNED!
  1316. //
  1317. // Arguments
  1318. //
  1319. // VA - Supplies a pointer to the subsection to encode.
  1320. //
  1321. // Return Value:
  1322. //
  1323. // The mask to set into the PTE to make it reference the supplied
  1324. // subsection.
  1325. //
  1326. //--
  1327. #define MiGetSubsectionAddressForPte(VA) \
  1328. ( ((ULONG)VA < (ULONG)KSEG2_BASE) ? \
  1329. ( (((ULONG)VA - (ULONG)MmSubsectionBase) << 5) | 0x4 ) \
  1330. : ( (((ULONG)MM_NONPAGED_POOL_END - (ULONG)VA) << 5 ) ) )
  1331. //++
  1332. //PMMPTE
  1333. //MiGetPdeAddress (
  1334. // IN PVOID va
  1335. // );
  1336. //
  1337. // Routine Description:
  1338. //
  1339. // MiGetPdeAddress returns the address of the PDE which maps the
  1340. // given virtual address.
  1341. //
  1342. // Arguments
  1343. //
  1344. // Va - Supplies the virtual address to locate the PDE for.
  1345. //
  1346. // Return Value:
  1347. //
  1348. // The address of the PDE.
  1349. //
  1350. //--
  1351. #define MiGetPdeAddress(va) \
  1352. ((PMMPTE)(((((ULONG)(va)) >> PDI_SHIFT) << 2) + PDE_BASE))
  1353. #define MiGetPdeAddress64(va) \
  1354. ((PMMPTE)((ULONG)((((ULONGLONG)(va)) >> PDI_SHIFT) << 2) + PDE_BASE64))
  1355. //++
  1356. //PMMPTE
  1357. //MiGetPteAddress (
  1358. // IN PVOID va
  1359. // );
  1360. //
  1361. // Routine Description:
  1362. //
  1363. // MiGetPteAddress returns the address of the PTE which maps the
  1364. // given virtual address.
  1365. //
  1366. // Arguments
  1367. //
  1368. // Va - Supplies the virtual address to locate the PTE for.
  1369. //
  1370. // Return Value:
  1371. //
  1372. // The address of the PTE.
  1373. //
  1374. //--
  1375. #define MiGetPteAddress(va) \
  1376. ((PMMPTE)(((((ULONG)(va)) >> PTI_SHIFT) << 2) + PTE_BASE))
  1377. #define MiGetPteAddress64(va) \
  1378. ((PMMPTE)((ULONG)((((ULONGLONG)(va)) >> PTI_SHIFT) << 2) + PTE_BASE64))
  1379. //++
  1380. //ULONG
  1381. //MiGetPpeOffset (
  1382. // IN PVOID va
  1383. // );
  1384. //
  1385. // Routine Description:
  1386. //
  1387. // MiGetPpeOffset returns the offset into a page root
  1388. // for a given virtual address.
  1389. //
  1390. // Arguments
  1391. //
  1392. // Va - Supplies the virtual address to locate the offset for.
  1393. //
  1394. // Return Value:
  1395. //
  1396. // The offset into the page root table the corresponding PPE is at.
  1397. //
  1398. //--
  1399. #define MiGetPpeOffset(va) (0)
  1400. //++
  1401. //ULONG
  1402. //MiGetPdeOffset (
  1403. // IN PVOID va
  1404. // );
  1405. //
  1406. // Routine Description:
  1407. //
  1408. // MiGetPdeOffset returns the offset into a page directory
  1409. // for a given virtual address.
  1410. //
  1411. // Arguments
  1412. //
  1413. // Va - Supplies the virtual address to locate the offset for.
  1414. //
  1415. // Return Value:
  1416. //
  1417. // The offset into the page directory table the corresponding PDE is at.
  1418. //
  1419. //--
  1420. #define MiGetPdeOffset(va) (((ULONG)(va)) >> PDI_SHIFT)
  1421. //++
  1422. //ULONG
  1423. //MiGetPdeIndex (
  1424. // IN PVOID va
  1425. // );
  1426. //
  1427. // Routine Description:
  1428. //
  1429. // MiGetPdeIndex returns the page directory index
  1430. // for a given virtual address.
  1431. //
  1432. // Arguments
  1433. //
  1434. // Va - Supplies the virtual address to locate the offset for.
  1435. //
  1436. // Return Value:
  1437. //
  1438. // The index into the page directory - ie: the virtual page table number.
  1439. // This is different from the page directory offset because this spans
  1440. // page directories on supported platforms.
  1441. //
  1442. //--
  1443. #define MiGetPdeIndex MiGetPdeOffset
  1444. //++
  1445. //ULONG
  1446. //MiGetPteOffset (
  1447. // IN PVOID va
  1448. // );
  1449. //
  1450. // Routine Description:
  1451. //
  1452. // MiGetPteOffset returns the offset into a page table page
  1453. // for a given virtual address.
  1454. //
  1455. // Arguments
  1456. //
  1457. // Va - Supplies the virtual address to locate the offset for.
  1458. //
  1459. // Return Value:
  1460. //
  1461. // The offset into the page table page table the corresponding PTE is at.
  1462. //
  1463. //--
  1464. #define MiGetPteOffset(va) \
  1465. ( (((ULONG)(va)) << (32-PDI_SHIFT)) >> ((32-PDI_SHIFT) + PTI_SHIFT) )
  1466. //++
  1467. //PVOID
  1468. //MiGetVirtualAddressMappedByPpe (
  1469. // IN PMMPTE PTE
  1470. // );
  1471. //
  1472. // Routine Description:
  1473. //
  1474. // MiGetVirtualAddressMappedByPpe returns the virtual address
  1475. // which is mapped by a given PPE address.
  1476. //
  1477. // Arguments
  1478. //
  1479. // PPE - Supplies the PPE to get the virtual address for.
  1480. //
  1481. // Return Value:
  1482. //
  1483. // Virtual address mapped by the PPE.
  1484. //
  1485. //--
  1486. #define MiGetVirtualAddressMappedByPpe(PPE) (NULL)
  1487. //++
  1488. //PVOID
  1489. //MiGetVirtualAddressMappedByPde (
  1490. // IN PMMPTE PDE
  1491. // );
  1492. //
  1493. // Routine Description:
  1494. //
  1495. // MiGetVirtualAddressMappedByPte returns the virtual address
  1496. // which is mapped by a given PDE address.
  1497. //
  1498. // Arguments
  1499. //
  1500. // PDE - Supplies the PDE to get the virtual address for.
  1501. //
  1502. // Return Value:
  1503. //
  1504. // Virtual address mapped by the PDE.
  1505. //
  1506. //--
  1507. #define MiGetVirtualAddressMappedByPde(va) \
  1508. ((PVOID)((ULONG)(va) << (PDI_SHIFT-2)))
  1509. //++
  1510. //PVOID
  1511. //MiGetVirtualAddressMappedByPte (
  1512. // IN PMMPTE PTE
  1513. // );
  1514. //
  1515. // Routine Description:
  1516. //
  1517. // MiGetVirtualAddressMappedByPte returns the virtual address
  1518. // which is mapped by a given PTE address.
  1519. //
  1520. // Arguments
  1521. //
  1522. // PTE - Supplies the PTE to get the virtual address for.
  1523. //
  1524. // Return Value:
  1525. //
  1526. // Virtual address mapped by the PTE.
  1527. //
  1528. //--
  1529. #define MiGetVirtualAddressMappedByPte(va) \
  1530. ((PVOID)((ULONG)(va) << (PAGE_SHIFT-2)))
  1531. #define MiGetVirtualAddressMappedByPte64(PTE) \
  1532. ((PVOID64)(((ULONGLONG)((ULONG)(PTE) - PTE_BASE64)) << 11))
  1533. #define MiGetVirtualPageNumberMappedByPte64(PTE) \
  1534. (((ULONG)(PTE) - PTE_BASE64) >> 2)
  1535. //++
  1536. //LOGICAL
  1537. //MiIsVirtualAddressOnPpeBoundary (
  1538. // IN PVOID VA
  1539. // );
  1540. //
  1541. // Routine Description:
  1542. //
  1543. // MiIsVirtualAddressOnPpeBoundary returns TRUE if the virtual address is
  1544. // on a page directory entry boundary.
  1545. //
  1546. // Arguments
  1547. //
  1548. // VA - Supplies the virtual address to check.
  1549. //
  1550. // Return Value:
  1551. //
  1552. // TRUE if on a boundary, FALSE if not.
  1553. //
  1554. //--
  1555. #define MiIsVirtualAddressOnPpeBoundary(VA) (FALSE)
  1556. //++
  1557. //LOGICAL
  1558. //MiIsVirtualAddressOnPdeBoundary (
  1559. // IN PVOID VA
  1560. // );
  1561. //
  1562. // Routine Description:
  1563. //
  1564. // MiIsVirtualAddressOnPdeBoundary returns TRUE if the virtual address is
  1565. // on a page directory entry boundary.
  1566. //
  1567. // Arguments
  1568. //
  1569. // VA - Supplies the virtual address to check.
  1570. //
  1571. // Return Value:
  1572. //
  1573. // TRUE if on a 4MB PDE boundary, FALSE if not.
  1574. //
  1575. //--
  1576. #define MiIsVirtualAddressOnPdeBoundary(VA) (((ULONG_PTR)(VA) & PAGE_DIRECTORY_MASK) == 0)
  1577. //++
  1578. //LOGICAL
  1579. //MiIsPteOnPdeBoundary (
  1580. // IN PVOID PTE
  1581. // );
  1582. //
  1583. // Routine Description:
  1584. //
  1585. // MiIsPteOnPdeBoundary returns TRUE if the PTE is
  1586. // on a page directory entry boundary.
  1587. //
  1588. // Arguments
  1589. //
  1590. // PTE - Supplies the PTE to check.
  1591. //
  1592. // Return Value:
  1593. //
  1594. // TRUE if on a 16MB PDE boundary, FALSE if not.
  1595. //
  1596. //--
  1597. #define MiIsPteOnPdeBoundary(PTE) (((ULONG_PTR)(PTE) & (PAGE_SIZE - 1)) == 0)
  1598. //++
  1599. //ULONG
  1600. //GET_PAGING_FILE_NUMBER (
  1601. // IN MMPTE PTE
  1602. // );
  1603. //
  1604. // Routine Description:
  1605. //
  1606. // This macro extracts the paging file number from a PTE.
  1607. //
  1608. // Arguments
  1609. //
  1610. // PTE - Supplies the PTE to operate upon.
  1611. //
  1612. // Return Value:
  1613. //
  1614. // The paging file number.
  1615. //
  1616. //--
  1617. #define GET_PAGING_FILE_NUMBER(PTE) ( ((PTE).u.Long << 20) >> 28 )
  1618. //++
  1619. //ULONG
  1620. //GET_PAGING_FILE_OFFSET (
  1621. // IN MMPTE PTE
  1622. // );
  1623. //
  1624. // Routine Description:
  1625. //
  1626. // This macro extracts the offset into the paging file from a PTE.
  1627. //
  1628. // Arguments
  1629. //
  1630. // PTE - Supplies the PTE to operate upon.
  1631. //
  1632. // Return Value:
  1633. //
  1634. // The paging file offset.
  1635. //
  1636. //--
  1637. #define GET_PAGING_FILE_OFFSET(PTE) ((((PTE).u.Long) >> 12) & 0x000FFFFF)
  1638. //++
  1639. //ULONG
  1640. //IS_PTE_NOT_DEMAND_ZERO (
  1641. // IN PMMPTE PPTE
  1642. // );
  1643. //
  1644. // Routine Description:
  1645. //
  1646. // This macro checks to see if a given PTE is NOT a demand zero PTE.
  1647. //
  1648. // Arguments
  1649. //
  1650. // PTE - Supplies the PTE to operate upon.
  1651. //
  1652. // Return Value:
  1653. //
  1654. // Returns 0 if the PTE is demand zero, non-zero otherwise.
  1655. //
  1656. //--
  1657. #define IS_PTE_NOT_DEMAND_ZERO(PTE) ((PTE).u.Long & (ULONG)0xFFFFFF01)
  1658. //++
  1659. //VOID
  1660. //MI_MAKING_VALID_PTE_INVALID(
  1661. // IN PMMPTE PPTE
  1662. // );
  1663. //
  1664. // Routine Description:
  1665. //
  1666. // Prepare to make a single valid PTE invalid.
  1667. // No action is required on x86.
  1668. //
  1669. // Arguments
  1670. //
  1671. // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors.
  1672. //
  1673. // Return Value:
  1674. //
  1675. // None.
  1676. //
  1677. //--
  1678. // No action is required.
  1679. #define MI_MAKING_VALID_PTE_INVALID(SYSTEM_WIDE)
  1680. //++
  1681. //VOID
  1682. //MI_MAKING_VALID_MULTIPLE_PTES_INVALID(
  1683. // IN PMMPTE PPTE
  1684. // );
  1685. //
  1686. // Routine Description:
  1687. //
  1688. // Prepare to make multiple valid PTEs invalid.
  1689. // No action is required on x86.
  1690. //
  1691. // Arguments
  1692. //
  1693. // SYSTEM_WIDE - Supplies TRUE if this will happen on all processors.
  1694. //
  1695. // Return Value:
  1696. //
  1697. // None.
  1698. //
  1699. //--
  1700. // No action is required.
  1701. #define MI_MAKING_MULTIPLE_PTES_INVALID(SYSTEM_WIDE)
  1702. //++
  1703. //VOID
  1704. //MI_MAKE_PROTECT_WRITE_COPY (
  1705. // IN OUT MMPTE PPTE
  1706. // );
  1707. //
  1708. // Routine Description:
  1709. //
  1710. // This macro makes a writable PTE a writable-copy PTE.
  1711. //
  1712. // Arguments
  1713. //
  1714. // PTE - Supplies the PTE to operate upon.
  1715. //
  1716. // Return Value:
  1717. //
  1718. // NONE
  1719. //
  1720. //--
  1721. #define MI_MAKE_PROTECT_WRITE_COPY(PTE) \
  1722. if ((PTE).u.Long & 0x20) { \
  1723. ((PTE).u.Long |= 0x8); \
  1724. }
  1725. //++
  1726. //VOID
  1727. //MI_SET_PAGE_DIRTY(
  1728. // IN PMMPTE PPTE,
  1729. // IN PVOID VA,
  1730. // IN PVOID PFNHELD
  1731. // );
  1732. //
  1733. // Routine Description:
  1734. //
  1735. // This macro sets the dirty bit (and release page file space).
  1736. //
  1737. // Arguments
  1738. //
  1739. // TEMP - Supplies a temporary for usage.
  1740. //
  1741. // PPTE - Supplies a pointer to the PTE that corresponds to VA.
  1742. //
  1743. // VA - Supplies a the virtual address of the page fault.
  1744. //
  1745. // PFNHELD - Supplies TRUE if the PFN lock is held.
  1746. //
  1747. // Return Value:
  1748. //
  1749. // None.
  1750. //
  1751. //--
  1752. #define MI_SET_PAGE_DIRTY(PPTE,VA,PFNHELD) \
  1753. if ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN) { \
  1754. MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \
  1755. }
  1756. //++
  1757. //VOID
  1758. //MI_NO_FAULT_FOUND(
  1759. // IN TEMP,
  1760. // IN PMMPTE PPTE,
  1761. // IN PVOID VA,
  1762. // IN PVOID PFNHELD
  1763. // );
  1764. //
  1765. // Routine Description:
  1766. //
  1767. // This macro handles the case when a page fault is taken and no
  1768. // PTE with the valid bit clear is found.
  1769. //
  1770. // Arguments
  1771. //
  1772. // TEMP - Supplies a temporary for usage.
  1773. //
  1774. // PPTE - Supplies a pointer to the PTE that corresponds to VA.
  1775. //
  1776. // VA - Supplies a the virtual address of the page fault.
  1777. //
  1778. // PFNHELD - Supplies TRUE if the PFN lock is held.
  1779. //
  1780. // Return Value:
  1781. //
  1782. // None.
  1783. //
  1784. //--
  1785. #define MI_NO_FAULT_FOUND(TEMP,PPTE,VA,PFNHELD) \
  1786. if (StoreInstruction && ((PPTE)->u.Hard.Dirty == MM_PTE_CLEAN)) { \
  1787. MiSetDirtyBit ((VA),(PPTE),(PFNHELD)); \
  1788. } else { \
  1789. KiFlushSingleTb( 1, VA ); \
  1790. }
  1791. //++
  1792. //ULONG
  1793. //MI_CAPTURE_DIRTY_BIT_TO_PFN (
  1794. // IN PMMPTE PPTE,
  1795. // IN PMMPFN PPFN
  1796. // );
  1797. //
  1798. // Routine Description:
  1799. //
  1800. // This macro gets captures the state of the dirty bit to the PFN
  1801. // and frees any associated page file space if the PTE has been
  1802. // modified element.
  1803. //
  1804. // NOTE - THE PFN LOCK MUST BE HELD!
  1805. //
  1806. // Arguments
  1807. //
  1808. // PPTE - Supplies the PTE to operate upon.
  1809. //
  1810. // PPFN - Supplies a pointer to the PFN database element that corresponds
  1811. // to the page mapped by the PTE.
  1812. //
  1813. // Return Value:
  1814. //
  1815. // None.
  1816. //
  1817. //--
  1818. #define MI_CAPTURE_DIRTY_BIT_TO_PFN(PPTE,PPFN) \
  1819. if (((PPFN)->u3.e1.Modified == 0) && \
  1820. ((PPTE)->u.Hard.Dirty == MM_PTE_DIRTY)) { \
  1821. (PPFN)->u3.e1.Modified = 1; \
  1822. if (((PPFN)->OriginalPte.u.Soft.Prototype == 0) && \
  1823. ((PPFN)->u3.e1.WriteInProgress == 0)) { \
  1824. MiReleasePageFileSpace ((PPFN)->OriginalPte); \
  1825. (PPFN)->OriginalPte.u.Soft.PageFileHigh = 0; \
  1826. } \
  1827. }
  1828. //++
  1829. //BOOLEAN
  1830. //MI_IS_PHYSICAL_ADDRESS (
  1831. // IN PVOID VA
  1832. // );
  1833. //
  1834. // Routine Description:
  1835. //
  1836. // This macro determines if a give virtual address is really a
  1837. // physical address.
  1838. //
  1839. // Arguments
  1840. //
  1841. // VA - Supplies the virtual address.
  1842. //
  1843. // Return Value:
  1844. //
  1845. // FALSE if it is not a physical address, TRUE if it is.
  1846. //
  1847. //--
  1848. #define MI_IS_PHYSICAL_ADDRESS(Va) \
  1849. ( ((ULONG)Va >= KSEG0_BASE) && ((ULONG)Va < KSEG2_BASE) )
  1850. //++
  1851. //ULONG
  1852. //MI_CONVERT_PHYSICAL_TO_PFN (
  1853. // IN PVOID VA
  1854. // );
  1855. //
  1856. // Routine Description:
  1857. //
  1858. // This macro converts a physical address (see MI_IS_PHYSICAL_ADDRESS)
  1859. // to its corresponding physical frame number.
  1860. //
  1861. // Arguments
  1862. //
  1863. // VA - Supplies a pointer to the physical address.
  1864. //
  1865. // Return Value:
  1866. //
  1867. // Returns the PFN for the page.
  1868. //
  1869. //--
  1870. #define MI_CONVERT_PHYSICAL_TO_PFN(Va) \
  1871. (((ULONG)Va << 2) >> (PAGE_SHIFT + 2))
  1872. //++
  1873. // ULONG
  1874. // MI_CONVERT_PHYSICAL_BUS_TO_PFN(
  1875. // PHYSICAL_ADDRESS Pa,
  1876. // )
  1877. //
  1878. // Routine Description:
  1879. //
  1880. // This macro takes a physical address and returns the pfn to which
  1881. // it corresponds.
  1882. //
  1883. // Arguments
  1884. //
  1885. // Pa - Supplies the physical address to convert.
  1886. //
  1887. // Return Value:
  1888. //
  1889. // The Pfn that corresponds to the physical address is returned.
  1890. //
  1891. //--
  1892. #define MI_CONVERT_PHYSICAL_BUS_TO_PFN(Pa) \
  1893. ((ULONG)( (Pa).QuadPart >> ((CCHAR)PAGE_SHIFT)))
  1894. typedef struct _MMCOLOR_TABLES {
  1895. ULONG Flink;
  1896. PVOID Blink;
  1897. } MMCOLOR_TABLES, *PMMCOLOR_TABLES;
  1898. typedef struct _MMPRIMARY_COLOR_TABLES {
  1899. LIST_ENTRY ListHead;
  1900. } MMPRIMARY_COLOR_TABLES, *PMMPRIMARY_COLOR_TABLES;
  1901. #if MM_MAXIMUM_NUMBER_OF_COLORS > 1
  1902. extern MMPFNLIST MmFreePagesByPrimaryColor[2][MM_MAXIMUM_NUMBER_OF_COLORS];
  1903. #endif
  1904. extern PMMCOLOR_TABLES MmFreePagesByColor[2];
  1905. extern ULONG MmTotalPagesForPagingFile;
  1906. #define MI_PTE_LOOKUP_NEEDED (0xfffff)
  1907. //
  1908. // The hardware PTE is defined in ...sdk/inc/ntalpha.h
  1909. //
  1910. //
  1911. // Invalid PTEs have the following definition.
  1912. //
  1913. typedef struct _MMPTE_SOFTWARE {
  1914. ULONG Valid: 1;
  1915. ULONG Prototype : 1;
  1916. ULONG Transition : 1;
  1917. ULONG Protection : 5;
  1918. ULONG PageFileLow : 4;
  1919. ULONG PageFileHigh : 20;
  1920. } MMPTE_SOFTWARE;
  1921. typedef struct _MMPTE_TRANSITION {
  1922. ULONG Valid : 1;
  1923. ULONG Prototype : 1;
  1924. ULONG Transition : 1;
  1925. ULONG Protection : 5;
  1926. ULONG filler01 : 1;
  1927. ULONG PageFrameNumber : 23;
  1928. } MMPTE_TRANSITION;
  1929. typedef struct _MMPTE_PROTOTYPE {
  1930. ULONG Valid : 1;
  1931. ULONG Prototype : 1;
  1932. ULONG ReadOnly : 1;
  1933. ULONG filler02 : 1;
  1934. ULONG ProtoAddress : 28;
  1935. } MMPTE_PROTOTYPE;
  1936. typedef struct _MMPTE_LIST {
  1937. ULONG Valid : 1;
  1938. ULONG filler07 : 7;
  1939. ULONG OneEntry : 1;
  1940. ULONG filler03 : 3;
  1941. ULONG NextEntry : 20;
  1942. } MMPTE_LIST;
  1943. typedef struct _MMPTE_SUBSECTION {
  1944. ULONG Valid : 1;
  1945. ULONG Prototype : 1;
  1946. ULONG WhichPool : 1;
  1947. ULONG Protection : 5;
  1948. ULONG SubsectionAddress : 24;
  1949. } MMPTE_SUBSECTION;
  1950. //
  1951. // A Valid Page Table Entry on a DEC ALPHA (ev4) has the following definition.
  1952. //
  1953. //
  1954. //
  1955. //typedef struct _HARDWARE_PTE {
  1956. // ULONG Valid: 1;
  1957. // ULONG Owner: 1;
  1958. // ULONG Dirty: 1;
  1959. // ULONG reserved: 1;
  1960. // ULONG Global: 1;
  1961. // ULONG filler2: 2;
  1962. // ULONG Write: 1;
  1963. // ULONG CopyOnWrite: 1;
  1964. // ULONG PageFrameNumber: 23;
  1965. //} HARDWARE_PTE, *PHARDWARE_PTE;
  1966. //
  1967. #define MI_GET_PAGE_FRAME_FROM_PTE(PTE) ((PTE)->u.Hard.PageFrameNumber)
  1968. #define MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE(PTE) ((PTE)->u.Trans.PageFrameNumber)
  1969. #define MI_GET_PROTECTION_FROM_SOFT_PTE(PTE) ((PTE)->u.Soft.Protection)
  1970. #define MI_GET_PROTECTION_FROM_TRANSITION_PTE(PTE) ((PTE)->u.Trans.Protection)
  1971. //
  1972. // A Page Table Entry on a DEC ALPHA (ev4) has the following definition.
  1973. //
  1974. typedef struct _MMPTE {
  1975. union {
  1976. ULONG Long;
  1977. HARDWARE_PTE Hard;
  1978. HARDWARE_PTE Flush;
  1979. MMPTE_PROTOTYPE Proto;
  1980. MMPTE_SOFTWARE Soft;
  1981. MMPTE_TRANSITION Trans;
  1982. MMPTE_LIST List;
  1983. MMPTE_SUBSECTION Subsect;
  1984. } u;
  1985. } MMPTE;
  1986. typedef MMPTE *PMMPTE;
  1987. //++
  1988. //VOID
  1989. //MI_WRITE_VALID_PTE (
  1990. // IN PMMPTE PointerPte,
  1991. // IN MMPTE PteContents
  1992. // );
  1993. //
  1994. // Routine Description:
  1995. //
  1996. // MI_WRITE_VALID_PTE fills in the specified PTE making it valid with the
  1997. // specified contents.
  1998. //
  1999. // Arguments
  2000. //
  2001. // PointerPte - Supplies a PTE to fill.
  2002. //
  2003. // PteContents - Supplies the contents to put in the PTE.
  2004. //
  2005. // Return Value:
  2006. //
  2007. // None.
  2008. //
  2009. //--
  2010. #define MI_WRITE_VALID_PTE(_PointerPte, _PteContents) \
  2011. (*(_PointerPte) = (_PteContents))
  2012. //++
  2013. //VOID
  2014. //MI_WRITE_INVALID_PTE (
  2015. // IN PMMPTE PointerPte,
  2016. // IN MMPTE PteContents
  2017. // );
  2018. //
  2019. // Routine Description:
  2020. //
  2021. // MI_WRITE_INVALID_PTE fills in the specified PTE making it invalid with the
  2022. // specified contents.
  2023. //
  2024. // Arguments
  2025. //
  2026. // PointerPte - Supplies a PTE to fill.
  2027. //
  2028. // PteContents - Supplies the contents to put in the PTE.
  2029. //
  2030. // Return Value:
  2031. //
  2032. // None.
  2033. //
  2034. //--
  2035. #define MI_WRITE_INVALID_PTE(_PointerPte, _PteContents) \
  2036. (*(_PointerPte) = (_PteContents))
  2037. //++
  2038. //VOID
  2039. //MI_WRITE_VALID_PTE_NEW_PROTECTION (
  2040. // IN PMMPTE PointerPte,
  2041. // IN MMPTE PteContents
  2042. // );
  2043. //
  2044. // Routine Description:
  2045. //
  2046. // MI_WRITE_VALID_PTE_NEW_PROTECTION fills in the specified PTE (which was
  2047. // already valid) changing only the protection or the dirty bit.
  2048. //
  2049. // Arguments
  2050. //
  2051. // PointerPte - Supplies a PTE to fill.
  2052. //
  2053. // PteContents - Supplies the contents to put in the PTE.
  2054. //
  2055. // Return Value:
  2056. //
  2057. // None.
  2058. //
  2059. //--
  2060. #define MI_WRITE_VALID_PTE_NEW_PROTECTION(_PointerPte, _PteContents) \
  2061. (*(_PointerPte) = (_PteContents))
  2062. //++
  2063. //VOID
  2064. //MiFillMemoryPte (
  2065. // IN PMMPTE Destination,
  2066. // IN ULONG Length,
  2067. // IN MMPTE Pattern,
  2068. // };
  2069. //
  2070. // Routine Description:
  2071. //
  2072. // This function fills memory with the specified PTE pattern.
  2073. //
  2074. // Arguments
  2075. //
  2076. // Destination - Supplies a pointer to the memory to fill.
  2077. //
  2078. // Length - Supplies the length, in bytes, of the memory to be
  2079. // filled.
  2080. //
  2081. // Pattern - Supplies the PTE fill pattern.
  2082. //
  2083. // Return Value:
  2084. //
  2085. // None.
  2086. //
  2087. //--
  2088. #define MiFillMemoryPte(Destination, Length, Pattern) \
  2089. RtlFillMemoryUlong ((Destination), (Length), (Pattern))
  2090. //++
  2091. //BOOLEAN
  2092. //MI_IS_PAGE_TABLE_ADDRESS (
  2093. // IN PVOID VA
  2094. // );
  2095. //
  2096. // Routine Description:
  2097. //
  2098. // This macro takes a virtual address and determines if
  2099. // it is a page table address.
  2100. //
  2101. // Arguments
  2102. //
  2103. // VA - Supplies a virtual address.
  2104. //
  2105. // Return Value:
  2106. //
  2107. // TRUE if the address is a page table address, FALSE if not.
  2108. //
  2109. //--
  2110. #define MI_IS_PAGE_TABLE_ADDRESS(VA) \
  2111. ((PVOID)(VA) >= (PVOID)PTE_BASE && (PVOID)(VA) <= (PVOID)PDE_TOP)
  2112. //++
  2113. //BOOLEAN
  2114. //MI_IS_KERNEL_PAGE_TABLE_ADDRESS (
  2115. // IN PVOID VA
  2116. // );
  2117. //
  2118. // Routine Description:
  2119. //
  2120. // This macro takes a virtual address and determines if
  2121. // it is a page table address for a kernel address.
  2122. //
  2123. // Arguments
  2124. //
  2125. // VA - Supplies a virtual address.
  2126. //
  2127. // Return Value:
  2128. //
  2129. // TRUE if the address is a kernel page table address, FALSE if not.
  2130. //
  2131. //--
  2132. #define MI_IS_KERNEL_PAGE_TABLE_ADDRESS(VA) \
  2133. ((PVOID)(VA) >= (PVOID)MiGetPteAddress(MmSystemRangeStart) && (PVOID)(VA) <= (PVOID)PDE_TOP)
  2134. //++
  2135. //BOOLEAN
  2136. //MI_IS_PAGE_DIRECTORY_ADDRESS (
  2137. // IN PVOID VA
  2138. // );
  2139. //
  2140. // Routine Description:
  2141. //
  2142. // This macro takes a virtual address and determines if
  2143. // it is a page directory address.
  2144. //
  2145. // Arguments
  2146. //
  2147. // VA - Supplies a virtual address.
  2148. //
  2149. // Return Value:
  2150. //
  2151. // TRUE if the address is a page directory address, FALSE if not.
  2152. //
  2153. //--
  2154. #define MI_IS_PAGE_DIRECTORY_ADDRESS(VA) \
  2155. ((PVOID)(VA) >= (PVOID)PDE_BASE && (PVOID)(VA) <= (PVOID)PDE_TOP)
  2156. //++
  2157. //BOOLEAN
  2158. //MI_IS_HYPER_SPACE_ADDRESS (
  2159. // IN PVOID VA
  2160. // );
  2161. //
  2162. // Routine Description:
  2163. //
  2164. // This macro takes a virtual address and determines if
  2165. // it is a hyper space address.
  2166. //
  2167. // Arguments
  2168. //
  2169. // VA - Supplies a virtual address.
  2170. //
  2171. // Return Value:
  2172. //
  2173. // TRUE if the address is a hyper space address, FALSE if not.
  2174. //
  2175. //--
  2176. #define MI_IS_HYPER_SPACE_ADDRESS(VA) \
  2177. ((PVOID)(VA) >= (PVOID)HYPER_SPACE && (PVOID)(VA) <= (PVOID)HYPER_SPACE_END)
  2178. //++
  2179. //BOOLEAN
  2180. //MI_IS_PROCESS_SPACE_ADDRESS (
  2181. // IN PVOID VA
  2182. // );
  2183. //
  2184. // Routine Description:
  2185. //
  2186. // This macro takes a virtual address and determines if
  2187. // it is a process-specific address. This is an address in user space
  2188. // or page table pages or hyper space.
  2189. //
  2190. // Arguments
  2191. //
  2192. // VA - Supplies a virtual address.
  2193. //
  2194. // Return Value:
  2195. //
  2196. // TRUE if the address is a process-specific address, FALSE if not.
  2197. //
  2198. //--
  2199. #define MI_IS_PROCESS_SPACE_ADDRESS(VA) \
  2200. (((PVOID)(VA) <= (PVOID)MM_HIGHEST_USER_ADDRESS) || \
  2201. ((PVOID)(VA) >= (PVOID)PTE_BASE && (PVOID)(VA) <= (PVOID)HYPER_SPACE_END))
  2202. //++
  2203. //BOOLEAN
  2204. //MI_IS_PTE_PROTOTYPE (
  2205. // IN PMMPTE PTE
  2206. // );
  2207. //
  2208. // Routine Description:
  2209. //
  2210. // This macro takes a PTE address and determines if it is a prototype PTE.
  2211. //
  2212. // Arguments
  2213. //
  2214. // PTE - Supplies the virtual address of the PTE to check.
  2215. //
  2216. // Return Value:
  2217. //
  2218. // TRUE if the PTE is in a segment (ie, a prototype PTE), FALSE if not.
  2219. //
  2220. //--
  2221. #define MI_IS_PTE_PROTOTYPE(PTE) \
  2222. ((PTE) > (PMMPTE)PDE_TOP)
  2223. //++
  2224. //BOOLEAN
  2225. //MI_IS_SYSTEM_CACHE_ADDRESS (
  2226. // IN PVOID VA
  2227. // );
  2228. //
  2229. // Routine Description:
  2230. //
  2231. // This macro takes a virtual address and determines if
  2232. // it is a system cache address.
  2233. //
  2234. // Arguments
  2235. //
  2236. // VA - Supplies a virtual address.
  2237. //
  2238. // Return Value:
  2239. //
  2240. // TRUE if the address is in the system cache, FALSE if not.
  2241. //
  2242. //--
  2243. #define MI_IS_SYSTEM_CACHE_ADDRESS(VA) \
  2244. (((PVOID)(VA) >= (PVOID)MmSystemCacheStart && \
  2245. (PVOID)(VA) <= (PVOID)MmSystemCacheEnd))
  2246. //++
  2247. //VOID
  2248. //MI_BARRIER_SYNCHRONIZE (
  2249. // IN ULONG TimeStamp
  2250. // );
  2251. //
  2252. // Routine Description:
  2253. //
  2254. // MI_BARRIER_SYNCHRONIZE compares the argument timestamp against the
  2255. // current IPI barrier sequence stamp. When equal, all processors will
  2256. // issue memory barriers to ensure that newly created pages remain coherent.
  2257. //
  2258. // When a page is put in the zeroed or free page list the current
  2259. // barrier sequence stamp is read (interlocked - this is necessary
  2260. // to get the correct value - memory barriers won't do the trick)
  2261. // and stored in the pfn entry for the page. The current barrier
  2262. // sequence stamp is maintained by the IPI send logic and is
  2263. // incremented (interlocked) when the target set of an IPI send
  2264. // includes all processors, but the one doing the send. When a page
  2265. // is needed its sequence number is compared against the current
  2266. // barrier sequence number. If it is equal, then the contents of
  2267. // the page may not be coherent on all processors, and an IPI must
  2268. // be sent to all processors to ensure a memory barrier is
  2269. // executed (generic call can be used for this). Sending the IPI
  2270. // automatically updates the barrier sequence number. The compare
  2271. // is for equality as this is the only value that requires the IPI
  2272. // (i.e., the sequence number wraps, values in both directions are
  2273. // older). When a page is removed in this fashion and either found
  2274. // to be coherent or made coherent, it cannot be modified between
  2275. // that time and writing the PTE. If the page is modified between
  2276. // these times, then an IPI must be sent.
  2277. //
  2278. // Arguments
  2279. //
  2280. // TimeStamp - Supplies the timestamp at the time when the page was zeroed.
  2281. //
  2282. // Return Value:
  2283. //
  2284. // None.
  2285. //
  2286. //--
  2287. #if defined(NT_UP)
  2288. #define MI_BARRIER_SYNCHRONIZE(TimeStamp) \
  2289. __MB();
  2290. #else
  2291. #define MI_BARRIER_SYNCHRONIZE(TimeStamp) \
  2292. if ((ULONG)TimeStamp == KeReadMbTimeStamp()) { \
  2293. KeSynchronizeMemoryAccess(); \
  2294. }
  2295. #endif
  2296. //++
  2297. //VOID
  2298. //MI_BARRIER_STAMP_ZEROED_PAGE (
  2299. // IN PULONG PointerTimeStamp
  2300. // );
  2301. //
  2302. // Routine Description:
  2303. //
  2304. // MI_BARRIER_STAMP_ZEROED_PAGE issues an interlocked read to get the
  2305. // current IPI barrier sequence stamp. This is called AFTER a page is
  2306. // zeroed.
  2307. //
  2308. // Arguments
  2309. //
  2310. // PointerTimeStamp - Supplies a timestamp pointer to fill with the
  2311. // current IPI barrier sequence stamp.
  2312. //
  2313. // Return Value:
  2314. //
  2315. // None.
  2316. //
  2317. //--
  2318. #if defined(NT_UP)
  2319. #define MI_BARRIER_STAMP_ZEROED_PAGE(PointerTimeStamp) NOTHING
  2320. #else
  2321. #define MI_BARRIER_SUPPORTED 1
  2322. #define MI_BARRIER_STAMP_ZEROED_PAGE(PointerTimeStamp) (*(PULONG)PointerTimeStamp = KeReadMbTimeStamp())
  2323. #endif
  2324. //++
  2325. //VOID
  2326. //MI_FLUSH_SINGLE_SESSION_TB (
  2327. // IN PVOID Virtual,
  2328. // IN ULONG Invalid,
  2329. // IN LOGICAL AllProcessors,
  2330. // IN PMMPTE PtePointer,
  2331. // IN MMPTE PteValue,
  2332. // IN MMPTE PreviousPte
  2333. // );
  2334. //
  2335. // Routine Description:
  2336. //
  2337. // MI_FLUSH_SINGLE_SESSION_TB flushes the requested single address
  2338. // translation from the TB.
  2339. //
  2340. // Since Alpha supports ASNs and session space doesn't have one, the entire
  2341. // TB needs to be flushed.
  2342. //
  2343. // Arguments
  2344. //
  2345. // Virtual - Supplies the virtual address to invalidate.
  2346. //
  2347. // Invalid - TRUE if invalidating.
  2348. //
  2349. // AllProcessors - TRUE if all processors need to be IPI'd.
  2350. //
  2351. // PtePointer - Supplies the PTE to invalidate.
  2352. //
  2353. // PteValue - Supplies the new PTE value.
  2354. //
  2355. // PreviousPte - The previous PTE value is returned here.
  2356. //
  2357. // Return Value:
  2358. //
  2359. // None.
  2360. //
  2361. //--
  2362. #define MI_FLUSH_SINGLE_SESSION_TB(Virtual, Invalid, AllProcessors, PtePointer, PteValue, PreviousPte) \
  2363. PreviousPte.u.Flush = *PtePointer; \
  2364. *PtePointer = PteValue; \
  2365. KeFlushEntireTb (TRUE, TRUE);
  2366. //++
  2367. //VOID
  2368. //MI_FLUSH_ENTIRE_SESSION_TB (
  2369. // IN ULONG Invalid,
  2370. // IN LOGICAL AllProcessors
  2371. // );
  2372. //
  2373. // Routine Description:
  2374. //
  2375. // MI_FLUSH_ENTIRE_SESSION_TB flushes the entire TB on Alphas since
  2376. // the Alpha supports ASNs.
  2377. //
  2378. // Arguments
  2379. //
  2380. // Invalid - TRUE if invalidating.
  2381. //
  2382. // AllProcessors - TRUE if all processors need to be IPI'd.
  2383. //
  2384. // Return Value:
  2385. //
  2386. // None.
  2387. //
  2388. #define MI_FLUSH_ENTIRE_SESSION_TB(Invalid, AllProcessors) \
  2389. KeFlushEntireTb (Invalid, AllProcessors);