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.

324 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Copyright (c) 1992 Digital Equipment Corporation
  4. Module Name:
  5. hypermap.c
  6. Abstract:
  7. This module contains the routines which map physical pages into
  8. reserved PTEs within hyper space for AXP64 systems.
  9. Author:
  10. Lou Perazzoli (loup) 5-Apr-1989
  11. Joe Notarangelo 23-Apr-1992 ALPHA version from MIPS version
  12. Revision History:
  13. --*/
  14. #include "mi.h"
  15. PVOID
  16. MiMapPageInHyperSpace (
  17. IN PFN_NUMBER PageFrameIndex,
  18. IN PKIRQL OldIrql
  19. )
  20. /*++
  21. Routine Description:
  22. This routine returns the physical address of the page.
  23. ************************************
  24. * *
  25. * Returns with a spin lock held!!! *
  26. * *
  27. ************************************
  28. Arguments:
  29. PageFrameIndex - Supplies the physical page number to map.
  30. OldIrql - Supplies a pointer in which to return the entry IRQL.
  31. Return Value:
  32. Returns the address where the requested page was mapped.
  33. RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!!
  34. The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!!
  35. Environment:
  36. kernel mode.
  37. --*/
  38. {
  39. //
  40. // On AXP64 systems all pages can be mapped physically using the 43-bit
  41. // super page address range.
  42. //
  43. ASSERT(PageFrameIndex != 0);
  44. LOCK_HYPERSPACE(OldIrql);
  45. return KSEG_ADDRESS(PageFrameIndex);
  46. }
  47. PVOID
  48. MiMapPageInHyperSpaceAtDpc (
  49. IN PFN_NUMBER PageFrameIndex
  50. )
  51. /*++
  52. Routine Description:
  53. This routine returns the physical address of the page.
  54. ************************************
  55. * *
  56. * Returns with a spin lock held!!! *
  57. * *
  58. ************************************
  59. Arguments:
  60. PageFrameIndex - Supplies the physical page number to map.
  61. Return Value:
  62. Returns the address where the requested page was mapped.
  63. RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!!
  64. The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!!
  65. Environment:
  66. Kernel mode, DISPATCH_LEVEL on entry.
  67. --*/
  68. {
  69. ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
  70. //
  71. // On AXP64 systems all pages can be mapped physically using the 43-bit
  72. // super page address range.
  73. //
  74. ASSERT(PageFrameIndex != 0);
  75. LOCK_HYPERSPACE_AT_DPC();
  76. return KSEG_ADDRESS(PageFrameIndex);
  77. }
  78. PVOID
  79. MiMapImageHeaderInHyperSpace (
  80. IN PFN_NUMBER PageFrameIndex
  81. )
  82. /*++
  83. Routine Description:
  84. The physical address of the specified page is returned.
  85. Arguments:
  86. PageFrameIndex - Supplies the physical page number to map.
  87. Return Value:
  88. Returns the virtual address where the specified physical page was
  89. mapped.
  90. Environment:
  91. Kernel mode.
  92. --*/
  93. {
  94. MMPTE TempPte;
  95. PMMPTE PointerPte;
  96. KIRQL OldIrql;
  97. #if DBG
  98. if (PageFrameIndex == 0) {
  99. DbgPrint("attempt to map physical page 0 in hyper space\n");
  100. KeBugCheck (MEMORY_MANAGEMENT);
  101. }
  102. #endif //DBG
  103. PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE);
  104. LOCK_PFN(OldIrql);
  105. while (PointerPte->u.Long != 0) {
  106. //
  107. // If there is no event specified, set one up.
  108. //
  109. if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) {
  110. //
  111. // Set the global event into the field and wait for it.
  112. //
  113. MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent;
  114. }
  115. //
  116. // Release the PFN lock and wait on the event in an
  117. // atomic operation.
  118. //
  119. KeEnterCriticalRegion();
  120. UNLOCK_PFN_AND_THEN_WAIT(OldIrql);
  121. KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping,
  122. Executive,
  123. KernelMode,
  124. FALSE,
  125. (PLARGE_INTEGER)NULL);
  126. KeLeaveCriticalRegion();
  127. LOCK_PFN (OldIrql);
  128. }
  129. ASSERT (PointerPte->u.Long == 0);
  130. TempPte = ValidPtePte;
  131. TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
  132. *PointerPte = TempPte;
  133. UNLOCK_PFN (OldIrql);
  134. return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte);
  135. }
  136. VOID
  137. MiUnmapImageHeaderInHyperSpace (
  138. VOID
  139. )
  140. /*++
  141. Routine Description:
  142. This procedure unmaps the PTE reserved for mapping the image
  143. header, flushes the TB, and, if the WaitingForImageMapping field
  144. is not NULL, sets the specified event.
  145. On ALPHA, no action is required as the super-page address of the page
  146. was used.
  147. Arguments:
  148. None.
  149. Return Value:
  150. None.
  151. Environment:
  152. Kernel mode.
  153. --*/
  154. {
  155. MMPTE TempPte;
  156. PMMPTE PointerPte;
  157. KIRQL OldIrql;
  158. PKEVENT Event;
  159. PointerPte = MiGetPteAddress(IMAGE_MAPPING_PTE);
  160. TempPte.u.Long = 0;
  161. LOCK_PFN (OldIrql);
  162. //
  163. // Capture the current state of the event field and clear it out.
  164. //
  165. Event = MmWorkingSetList->WaitingForImageMapping;
  166. MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL;
  167. ASSERT (PointerPte->u.Long != 0);
  168. KeFlushSingleTb (IMAGE_MAPPING_PTE, TRUE, FALSE,
  169. (PHARDWARE_PTE)PointerPte, TempPte.u.Hard);
  170. UNLOCK_PFN (OldIrql);
  171. if (Event != (PKEVENT)NULL) {
  172. //
  173. // If there was an event specified, set the event.
  174. //
  175. KePulseEvent (Event, 0, FALSE);
  176. }
  177. return;
  178. }
  179. PVOID
  180. MiMapPageToZeroInHyperSpace (
  181. IN PFN_NUMBER PageFrameIndex
  182. )
  183. /*++
  184. Routine Description:
  185. This procedure maps the specified page frame into the 43-bit super
  186. page address range.
  187. Arguments:
  188. PageFrameIndex - Supplies the page frame to map.
  189. Return Value:
  190. The 43-bit super address of the respective page is returned as the
  191. function value.
  192. --*/
  193. {
  194. //
  195. // On AXP64 systems all pages can be mapped physically using the 43-bit
  196. // super page address range.
  197. //
  198. ASSERT(PageFrameIndex != 0);
  199. MM_PFN_LOCK_ASSERT();
  200. return KSEG_ADDRESS(PageFrameIndex);
  201. }