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.

404 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Copyright (c) 1992 Digital Equipment Corporation
  4. Module Name:
  5. debugsup.c
  6. Abstract:
  7. This module contains routines which provide support for the
  8. kernel debugger.
  9. Author:
  10. Lou Perazzoli (loup) 02-Aug-90
  11. Joe Notarangelo 23-Apr-1992
  12. Revision History:
  13. --*/
  14. #include "mi.h"
  15. PVOID
  16. MmDbgReadCheck (
  17. IN PVOID VirtualAddress
  18. )
  19. /*++
  20. Routine Description:
  21. ALPHA implementation specific:
  22. This routine returns the virtual address which is valid (mapped)
  23. for read access.
  24. Arguments:
  25. VirtualAddress - Supplies the virtual address to check.
  26. Return Value:
  27. Returns NULL if the address is not valid or readable, otherwise
  28. returns the virtual address.
  29. Environment:
  30. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  31. --*/
  32. {
  33. if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
  34. (VirtualAddress < (PVOID)KSEG2_BASE)) {
  35. return VirtualAddress;
  36. }
  37. if (!MmIsAddressValid (VirtualAddress)) {
  38. return NULL;
  39. }
  40. return VirtualAddress;
  41. }
  42. PVOID
  43. MmDbgWriteCheck (
  44. IN PVOID VirtualAddress,
  45. IN PHARDWARE_PTE Opaque
  46. )
  47. /*++
  48. Routine Description:
  49. ALPHA implementation specific:
  50. This routine returns the physical address for a virtual address
  51. which is valid (mapped) for write access.
  52. If the address is valid and writable and not within KSEG0
  53. the physical address within KSEG0 is returned. If the address
  54. is within KSEG0 then the called address is returned.
  55. NOTE: The physical address must only be used while the interrupt
  56. level on ALL processors is above DISPATCH_LEVEL, otherwise the
  57. binding between the virtual address and the physical address can
  58. change due to paging.
  59. Arguments:
  60. VirtualAddress - Supplies the virtual address to check.
  61. Opaque - Supplies a pointer to fill with an opaque value.
  62. Return Value:
  63. Returns NULL if the address is not valid or readable, otherwise
  64. returns the physical address of the corresponding virtual address.
  65. Environment:
  66. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  67. --*/
  68. {
  69. MMPTE PteContents;
  70. PMMPTE PointerPte;
  71. PMMPTE InputPte;
  72. InputPte = (PMMPTE)Opaque;
  73. InputPte->u.Long = 0;
  74. if ((VirtualAddress >= (PVOID)KSEG0_BASE) &&
  75. (VirtualAddress < (PVOID)KSEG2_BASE)) {
  76. return VirtualAddress;
  77. }
  78. if (!MmIsAddressValid (VirtualAddress)) {
  79. return NULL;
  80. }
  81. PointerPte = MiGetPteAddress (VirtualAddress);
  82. if ((VirtualAddress <= MM_HIGHEST_USER_ADDRESS) &&
  83. (PointerPte->u.Hard.PageFrameNumber < MM_PAGES_IN_KSEG0)) {
  84. //
  85. // User mode - return the physical address. This prevents
  86. // copy on write faults for breakpoints on user-mode pages.
  87. // IGNORE write protection.
  88. //
  89. // N.B. - The physical address must be less than 1GB to allow this
  90. // short-cut mapping.
  91. //
  92. // N.B. - Any non-breakpoint modifications can get lost when the page
  93. // is paged out because the PTE is not marked modified when
  94. // the access is made through this alternate mapping.
  95. //
  96. return (PVOID)
  97. ((ULONG)MmGetPhysicalAddress(VirtualAddress).LowPart + KSEG0_BASE);
  98. }
  99. if (PointerPte->u.Hard.Write == 0) {
  100. //
  101. // PTE is not writable, make it so.
  102. //
  103. PteContents = *PointerPte;
  104. *InputPte = PteContents;
  105. //
  106. // Modify the PTE to ensure write permissions.
  107. //
  108. PteContents.u.Hard.Write = 1;
  109. *PointerPte = PteContents;
  110. //
  111. // KeFillEntryTb is liable to IPI the other processors. This is
  112. // definitely NOT what we want as the other processors are frozen
  113. // in the debugger and we will deadlock if we try and IPI them.
  114. // Just flush the current processor instead.
  115. //
  116. // KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
  117. //
  118. KiFlushSingleTb(TRUE, VirtualAddress);
  119. }
  120. return VirtualAddress;
  121. }
  122. VOID
  123. MmDbgReleaseAddress (
  124. IN PVOID VirtualAddress,
  125. IN PHARDWARE_PTE Opaque
  126. )
  127. /*++
  128. Routine Description:
  129. i386/486 implementation specific:
  130. This routine resets the specified virtual address access permissions
  131. to its original state.
  132. Arguments:
  133. VirtualAddress - Supplies the virtual address to check.
  134. Opaque - Supplies an opaque pointer.
  135. Return Value:
  136. None.
  137. Environment:
  138. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  139. --*/
  140. {
  141. MMPTE TempPte;
  142. PMMPTE PointerPte;
  143. PMMPTE InputPte;
  144. InputPte = (PMMPTE)Opaque;
  145. ASSERT (MmIsAddressValid (VirtualAddress));
  146. if (InputPte->u.Long != 0) {
  147. PointerPte = MiGetPteAddress (VirtualAddress);
  148. TempPte = *InputPte;
  149. *PointerPte = TempPte;
  150. //
  151. // KeFillEntryTb is liable to IPI the other processors. This is
  152. // definitely NOT what we want as the other processors are frozen
  153. // in the debugger and we will deadlock if we try and IPI them.
  154. // Just flush the current processor instead.
  155. //
  156. // KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
  157. //
  158. KiFlushSingleTb(TRUE, VirtualAddress);
  159. }
  160. return;
  161. }
  162. PVOID64
  163. MmDbgReadCheck64 (
  164. IN PVOID64 VirtualAddress
  165. )
  166. /*++
  167. Routine Description:
  168. ALPHA implementation specific:
  169. This routine returns the virtual address which is valid (mapped)
  170. for read access.
  171. If the address is valid and readable then the called address is returned.
  172. Arguments:
  173. VirtualAddress - Supplies the virtual address to check.
  174. Return Value:
  175. Returns NULL if the address is not valid or readable, otherwise
  176. returns the virtual address.
  177. Environment:
  178. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  179. --*/
  180. {
  181. #ifdef VLM_SUPPORT
  182. if (!MmIsAddressValid64 (VirtualAddress)) {
  183. return NULL;
  184. }
  185. return VirtualAddress;
  186. #else
  187. return NULL;
  188. #endif
  189. }
  190. PVOID64
  191. MmDbgWriteCheck64 (
  192. IN PVOID64 VirtualAddress
  193. )
  194. /*++
  195. Routine Description:
  196. ALPHA implementation specific:
  197. This routine returns the physical address for a virtual address
  198. which is valid (mapped) for write access.
  199. If the address is valid and writable then the called address is returned.
  200. Arguments:
  201. VirtualAddress - Supplies the virtual address to check.
  202. Return Value:
  203. Returns NULL if the address is not valid or readable, otherwise
  204. returns the virtual address.
  205. Environment:
  206. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  207. --*/
  208. {
  209. #ifdef VLM_SUPPORT
  210. PMMPTE PointerPte;
  211. if (!MmIsAddressValid64 (VirtualAddress)) {
  212. return NULL;
  213. }
  214. PointerPte = MiGetPteAddress64 (VirtualAddress);
  215. if (PointerPte->u.Hard.Write == 0) {
  216. return NULL;
  217. }
  218. return VirtualAddress;
  219. #else
  220. return NULL;
  221. #endif
  222. }
  223. PVOID64
  224. MmDbgTranslatePhysicalAddress64 (
  225. IN PHYSICAL_ADDRESS PhysicalAddress
  226. )
  227. /*++
  228. Routine Description:
  229. ALPHA implementation specific:
  230. The Alpha processor provides a direct-mapped address space called
  231. the superpage. The entire physical address space can be
  232. addressed via the superpage. This routine translates a physical
  233. address to its corresponding superpage address. Unfortunately,
  234. the base superpage address is processor-dependent. Therefore, we
  235. have to compute it based on the processor level. As new processors are
  236. released, this routine will need to be updated.
  237. This routine does not use PTEs.
  238. Arguments:
  239. PhysicalAddress - Supplies the physical address to translate.
  240. Return Value:
  241. The virtual (superpage) address which corresponds to the physical address.
  242. Environment:
  243. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  244. --*/
  245. {
  246. switch (KeProcessorLevel) {
  247. case PROCESSOR_ALPHA_21064:
  248. case PROCESSOR_ALPHA_21066:
  249. case PROCESSOR_ALPHA_21068:
  250. PhysicalAddress.QuadPart &= 0x00000003ffffffff;
  251. PhysicalAddress.QuadPart |= 0xfffffc0000000000;
  252. break;
  253. case PROCESSOR_ALPHA_21164:
  254. case PROCESSOR_ALPHA_21164PC:
  255. PhysicalAddress.QuadPart &= 0x000000ffffffffff;
  256. PhysicalAddress.QuadPart |= 0xfffffc0000000000;
  257. break;
  258. case PROCESSOR_ALPHA_21264:
  259. PhysicalAddress.QuadPart &= 0x00000fffffffffff;
  260. PhysicalAddress.QuadPart |= 0xffff800000000000;
  261. break;
  262. default:
  263. return NULL64;
  264. }
  265. return (PVOID64)PhysicalAddress.QuadPart;
  266. }