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.

464 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Digital Equipment Corporation
  3. Module Name:
  4. debugsup.c
  5. Abstract:
  6. This module contains routines which provide support for the
  7. kernel debugger on 64-bit Alpha systems.
  8. Author:
  9. David N. Cutler (davec) 24-Feb-1998
  10. Revision History:
  11. --*/
  12. #include "mi.h"
  13. PHARDWARE_PTE
  14. MiCheckAddress (
  15. IN PVOID VirtualAddress,
  16. OUT PVOID *AccessAddress
  17. )
  18. /*++
  19. Routine Description:
  20. This function checks the specified virtual address for accessibility
  21. and returns a pointer to the hardware PTE that maps the virtual address
  22. and a 43-bit superpage address at which the address can be accessed.
  23. Arguments:
  24. VirtualAddress - Supplies the virtual address to check.
  25. AccessAddress - Supplies a pointer to a variable that receives the
  26. 43-bit superpage address at which the address can be accessed.
  27. Return Value:
  28. A value of NULL is returned if the address is invalid or not accessible.
  29. Otherwise, a pointer to the PTE that maps the specified virtual address
  30. is returned as the function value.
  31. --*/
  32. {
  33. ULONG Index;
  34. PHARDWARE_PTE Pdr1;
  35. PHARDWARE_PTE Pdr2;
  36. PHARDWARE_PTE Ptp;
  37. //
  38. // If the high order 21 bits of the virtual address are not all 1's or
  39. // 0's, then the address is invalid. Otherwise, attempt to tranverse
  40. // the page directory hierarchy.
  41. //
  42. if ((ULONG_PTR)(((LONG_PTR)VirtualAddress >> 43) + 1) > 1) {
  43. return NULL;
  44. }
  45. //
  46. // Compute the 43-bit superpage address of the level one page
  47. // directory page and check to see if the level two page directory
  48. // page is valid.
  49. //
  50. Pdr1 = (PHARDWARE_PTE)(KSEG43_BASE | (((PHARDWARE_PTE)PDE_SELFMAP)->PageFrameNumber << PAGE_SHIFT));
  51. Index = (ULONG)(((ULONG_PTR)VirtualAddress >> PDI1_SHIFT) & PDI_MASK);
  52. if (Pdr1[Index].Valid == 0) {
  53. return NULL;
  54. }
  55. //
  56. // Compute the 43-bit superpage address of the level two page
  57. // directory page and check to see if the page table page is
  58. // valid.
  59. //
  60. Pdr2 = (PHARDWARE_PTE)(KSEG43_BASE | (Pdr1[Index].PageFrameNumber << PAGE_SHIFT));
  61. Index = (ULONG)(((ULONG_PTR)VirtualAddress >> PDI2_SHIFT) & PDI_MASK);
  62. if (Pdr2[Index].Valid == 0) {
  63. return NULL;
  64. }
  65. //
  66. // Compute the 43-bit superpage address of the page table page and
  67. // check to see if the data page is valid.
  68. Ptp = (PHARDWARE_PTE)(KSEG43_BASE | (Pdr2[Index].PageFrameNumber << PAGE_SHIFT));
  69. Index = (ULONG)(((ULONG_PTR)VirtualAddress >> PTI_SHIFT) & PDI_MASK);
  70. if (Ptp[Index].Valid == 0) {
  71. return NULL;
  72. }
  73. //
  74. // Compute the 43-bit superpage address of the data page and return the
  75. // address of the PTE that maps the data page as the function value.
  76. //
  77. *AccessAddress = (PVOID)(KSEG43_BASE |
  78. (Ptp[Index].PageFrameNumber << PAGE_SHIFT) |
  79. (ULONG_PTR)VirtualAddress & (PAGE_SIZE - 1));
  80. return &Ptp[Index];
  81. }
  82. PVOID
  83. MmDbgReadCheck (
  84. IN PVOID VirtualAddress
  85. )
  86. /*++
  87. Routine Description:
  88. This routine returns the 43-bit superpage address which corresponds
  89. to the specified virtual address if the specified virtual address
  90. is readable.
  91. N.B. This function should only be called at IRQL DISPATCH_LEVEL or
  92. above.
  93. Arguments:
  94. VirtualAddress - Supplies the virtual address to check.
  95. Return Value:
  96. If the specified virtual address is invalid or not readable, then a
  97. value of NULL is returned. Otherwise, the 43-bit superpage address
  98. which corresponds to the specified virtual address is returned.
  99. --*/
  100. {
  101. PVOID AccessAddress;
  102. //
  103. // If the address is within the 32- or 43-bit superpage regions, then
  104. // the address is returned as the function value.
  105. //
  106. if (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) {
  107. return VirtualAddress;
  108. }
  109. //
  110. // Check if the specified virtual address if accessible. If the virtual
  111. // address is accessible, then return the 43-bit superpage address which
  112. // corresponds to the virtual address. Otherwise, return NULL.
  113. //
  114. if (MiCheckAddress(VirtualAddress, &AccessAddress) == NULL) {
  115. return NULL;
  116. } else {
  117. return AccessAddress;
  118. }
  119. }
  120. PVOID
  121. MmDbgWriteCheck (
  122. IN PVOID VirtualAddress,
  123. IN PHARDWARE_PTE Opaque
  124. )
  125. /*++
  126. Routine Description:
  127. This routine returns the 43-bit superpage address which corresponds
  128. to the specified virtual address if the specified virtual address is
  129. writable.
  130. N.B. This function should only be called at IRQL DISPATCH_LEVEL or
  131. above.
  132. Arguments:
  133. VirtualAddress - Supplies the virtual address to check.
  134. Opaque - Supplies a pointer to fill with an opaque value.
  135. Return Value:
  136. If the specified virtual address is invalid or not writable, then a
  137. value of NULL is returned. Otherwise, the 43-bit superpage address
  138. which corresponds to the specified virtual address is returned.
  139. --*/
  140. {
  141. MMPTE PteContents;
  142. PVOID AccessAddress;
  143. PHARDWARE_PTE Pte;
  144. PMMPTE InputPte;
  145. InputPte = (PMMPTE)Opaque;
  146. InputPte->u.Long = 0;
  147. //
  148. // If the address is within the 32- or 43-bit superpage regions, then
  149. // the address is returned as the function value.
  150. //
  151. if (MI_IS_PHYSICAL_ADDRESS(VirtualAddress)) {
  152. return VirtualAddress;
  153. }
  154. //
  155. // Check if the specified virtual address if accessible. If the virtual
  156. // address is accessible, then return the 43-bit superpage address which
  157. // corresponds to the virtual address. Otherwise, return NULL.
  158. //
  159. //
  160. Pte = MiCheckAddress(VirtualAddress, &AccessAddress);
  161. if (Pte == NULL) {
  162. return NULL;
  163. }
  164. if (Pte->Write == 0) {
  165. //
  166. // PTE is not writable, make it so.
  167. //
  168. PteContents = *(PMMPTE)Pte;
  169. *InputPte = PteContents;
  170. //
  171. // Modify the PTE to ensure write permissions :
  172. // turn on write and turn off fault on write.
  173. //
  174. PteContents.u.Hard.Write = 1;
  175. PteContents.u.Hard.FaultOnWrite = 0;
  176. *(PMMPTE)Pte = PteContents;
  177. //
  178. // KeFillEntryTb is liable to IPI the other processors. This is
  179. // definitely NOT what we want as the other processors are frozen
  180. // in the debugger and we will deadlock if we try and IPI them.
  181. // Just flush the current processor instead.
  182. //
  183. // KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
  184. //
  185. KiFlushSingleTb(TRUE, VirtualAddress);
  186. }
  187. else {
  188. return AccessAddress;
  189. }
  190. return VirtualAddress;
  191. }
  192. VOID
  193. MmDbgReleaseAddress (
  194. IN PVOID VirtualAddress,
  195. IN PHARDWARE_PTE Opaque
  196. )
  197. /*++
  198. Routine Description:
  199. i386/486 implementation specific:
  200. This routine resets the specified virtual address access permissions
  201. to its original state.
  202. Arguments:
  203. VirtualAddress - Supplies the virtual address to check.
  204. Opaque - Supplies an opaque pointer.
  205. Return Value:
  206. None.
  207. Environment:
  208. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  209. --*/
  210. {
  211. MMPTE TempPte;
  212. PMMPTE PointerPte;
  213. PMMPTE InputPte;
  214. InputPte = (PMMPTE)Opaque;
  215. ASSERT (MmIsAddressValid (VirtualAddress));
  216. if (InputPte->u.Long != 0) {
  217. PointerPte = MiGetPteAddress (VirtualAddress);
  218. TempPte = *InputPte;
  219. *PointerPte = TempPte;
  220. //
  221. // KeFillEntryTb is liable to IPI the other processors. This is
  222. // definitely NOT what we want as the other processors are frozen
  223. // in the debugger and we will deadlock if we try and IPI them.
  224. // Just flush the current processor instead.
  225. //
  226. // KeFillEntryTb ((PHARDWARE_PTE)PointerPte, VirtualAddress, TRUE);
  227. //
  228. KiFlushSingleTb(TRUE, VirtualAddress);
  229. }
  230. return;
  231. }
  232. PVOID64
  233. MmDbgReadCheck64 (
  234. IN PVOID64 VirtualAddress
  235. )
  236. /*++
  237. Routine Description:
  238. This routine returns the 43-bit superpage address which corresponds
  239. to the specified virtual address if the specified virtual address
  240. is readable.
  241. N.B. This function should only be called at IRQL DISPATCH_LEVEL or
  242. above.
  243. Arguments:
  244. VirtualAddress - Supplies the virtual address to check.
  245. Return Value:
  246. If the specified virtual address is invalid or not readable, then a
  247. value of NULL is returned. Otherwise, the 43-bit superpage address
  248. which corresponds to the specified virtual address is returned.
  249. --*/
  250. {
  251. return MmDbgReadCheck(VirtualAddress);
  252. }
  253. PVOID64
  254. MmDbgWriteCheck64 (
  255. IN PVOID64 VirtualAddress
  256. )
  257. /*++
  258. Routine Description:
  259. This routine returns the 43-bit superpage address which corresponds
  260. to the specified virtual address if the specified virtual address is
  261. writable.
  262. N.B. This function should only be called at IRQL DISPATCH_LEVEL or
  263. above.
  264. Arguments:
  265. VirtualAddress - Supplies the virtual address to check.
  266. Return Value:
  267. If the specified virtual address is invalid or not writable, then a
  268. value of NULL is returned. Otherwise, the 43-bit superpage address
  269. which corresponds to the specified virtual address is returned.
  270. --*/
  271. {
  272. HARDWARE_PTE Opaque;
  273. return MmDbgWriteCheck(VirtualAddress, &Opaque);
  274. }
  275. PVOID64
  276. MmDbgTranslatePhysicalAddress64 (
  277. IN PHYSICAL_ADDRESS PhysicalAddress
  278. )
  279. /*++
  280. Routine Description:
  281. ALPHA implementation specific:
  282. The Alpha processor provides a direct-mapped address space called
  283. the superpage. The entire physical address space can be
  284. addressed via the superpage. This routine translates a physical
  285. address to its corresponding superpage address. Unfortunately,
  286. the base superpage address is processor-dependent. Therefore, we
  287. have to compute it based on the processor level. As new processors are
  288. released, this routine will need to be updated.
  289. This routine does not use PTEs.
  290. Arguments:
  291. PhysicalAddress - Supplies the physical address to translate.
  292. Return Value:
  293. The virtual (superpage) address which corresponds to the physical address.
  294. Environment:
  295. Kernel mode IRQL at DISPATCH_LEVEL or greater.
  296. --*/
  297. {
  298. switch (KeProcessorLevel) {
  299. case PROCESSOR_ALPHA_21064:
  300. case PROCESSOR_ALPHA_21066:
  301. case PROCESSOR_ALPHA_21068:
  302. PhysicalAddress.QuadPart &= 0x00000003ffffffff;
  303. PhysicalAddress.QuadPart |= 0xfffffc0000000000;
  304. break;
  305. case PROCESSOR_ALPHA_21164:
  306. case PROCESSOR_ALPHA_21164PC:
  307. PhysicalAddress.QuadPart &= 0x000000ffffffffff;
  308. PhysicalAddress.QuadPart |= 0xfffffc0000000000;
  309. break;
  310. case PROCESSOR_ALPHA_21264:
  311. PhysicalAddress.QuadPart &= 0x00000fffffffffff;
  312. PhysicalAddress.QuadPart |= 0xffff800000000000;
  313. break;
  314. default:
  315. return NULL64;
  316. }
  317. return (PVOID64)PhysicalAddress.QuadPart;
  318. }