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.

450 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. bdcpuapi.c
  5. Abstract:
  6. This module implements CPU specific remote debug APIs.
  7. Author:
  8. Mark Lucovsky (markl) 04-Sep-1990
  9. Revision History:
  10. --*/
  11. #include "bd.h"
  12. //
  13. // Define end of control space.
  14. //
  15. #define END_OF_CONTROL_SPACE ((PCHAR)(sizeof(KPROCESSOR_STATE)))
  16. VOID
  17. BdSetContextState(
  18. IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
  19. IN PCONTEXT ContextRecord
  20. )
  21. /*++
  22. Routine Description:
  23. The function fills in the processor-specific portions of
  24. the wait state change message record.
  25. Arguments:
  26. WaitStateChange - Supplies a pointer to record to fill in.
  27. ContextRecord - Supplies a pointer to a context record.
  28. Return Value:
  29. None.
  30. --*/
  31. {
  32. //
  33. // Special registers for the x86.
  34. //
  35. WaitStateChange->ControlReport.Dr6 = BdPrcb.ProcessorState.SpecialRegisters.KernelDr6;
  36. WaitStateChange->ControlReport.Dr7 = BdPrcb.ProcessorState.SpecialRegisters.KernelDr7;
  37. WaitStateChange->ControlReport.SegCs = (USHORT)(ContextRecord->SegCs);
  38. WaitStateChange->ControlReport.SegDs = (USHORT)(ContextRecord->SegDs);
  39. WaitStateChange->ControlReport.SegEs = (USHORT)(ContextRecord->SegEs);
  40. WaitStateChange->ControlReport.SegFs = (USHORT)(ContextRecord->SegFs);
  41. WaitStateChange->ControlReport.EFlags = ContextRecord->EFlags;
  42. WaitStateChange->ControlReport.ReportFlags = X86_REPORT_INCLUDES_SEGS;
  43. return;
  44. }
  45. VOID
  46. BdGetStateChange(
  47. IN PDBGKD_MANIPULATE_STATE64 ManipulateState,
  48. IN PCONTEXT ContextRecord
  49. )
  50. /*++
  51. Routine Description:
  52. The function extracts continuation control data from a manipulate state
  53. message.
  54. Arguments:
  55. ManipulateState - Supplies a pointer to the manipulate state packet.
  56. ContextRecord - Supplies a pointer to a context record.
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. //
  62. // If the continuation status is success, then set control space value.
  63. //
  64. if (NT_SUCCESS(ManipulateState->u.Continue2.ContinueStatus) != FALSE) {
  65. //
  66. // Set trace flag.
  67. //
  68. if (ManipulateState->u.Continue2.ControlSet.TraceFlag == TRUE) {
  69. ContextRecord->EFlags |= 0x100L;
  70. } else {
  71. ContextRecord->EFlags &= ~0x100L;
  72. }
  73. //
  74. // Set debug registers in processor control block.
  75. //
  76. BdPrcb.ProcessorState.SpecialRegisters.KernelDr6 = 0L;
  77. BdPrcb.ProcessorState.SpecialRegisters.KernelDr7 =
  78. ManipulateState->u.Continue2.ControlSet.Dr7;
  79. }
  80. }
  81. VOID
  82. BdSetStateChange(
  83. IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
  84. IN PEXCEPTION_RECORD ExceptionRecord,
  85. IN PCONTEXT ContextRecord
  86. )
  87. /*++
  88. Routine Description:
  89. Fill in the wait state change message record.
  90. Arguments:
  91. WaitStateChange - Supplies pointer to record to fill in
  92. ExceptionRecord - Supplies a pointer to an exception record.
  93. ContextRecord - Supplies a pointer to a context record.
  94. Return Value:
  95. None.
  96. --*/
  97. {
  98. BdSetContextState(WaitStateChange, ContextRecord);
  99. }
  100. VOID
  101. BdReadControlSpace(
  102. IN PDBGKD_MANIPULATE_STATE64 m,
  103. IN PSTRING AdditionalData,
  104. IN PCONTEXT Context
  105. )
  106. /*++
  107. Routine Description:
  108. This function reads control space.
  109. Arguments:
  110. m - Supplies a pointer to the state manipulation message.
  111. AdditionalData - Supplies any additional data for the message.
  112. Context - Supplies the current context.
  113. Return Value:
  114. None.
  115. --*/
  116. {
  117. PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory;
  118. ULONG Length;
  119. STRING MessageHeader;
  120. //
  121. // If the specified control registers are within control space, then
  122. // read the specified space and return a success status. Otherwise,
  123. // return an unsuccessful status.
  124. //
  125. Length = min(a->TransferCount,
  126. PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
  127. if (((PCHAR)a->TargetBaseAddress + Length) <= END_OF_CONTROL_SPACE) {
  128. BdCopyMemory(AdditionalData->Buffer,
  129. (PCHAR)&BdPrcb.ProcessorState + (ULONG)a->TargetBaseAddress,
  130. Length);
  131. m->ReturnStatus = STATUS_SUCCESS;
  132. a->ActualBytesRead = Length;
  133. AdditionalData->Length = (USHORT)Length;
  134. } else {
  135. m->ReturnStatus = STATUS_UNSUCCESSFUL;
  136. a->ActualBytesRead = 0;
  137. AdditionalData->Length = 0;
  138. }
  139. //
  140. // Send reply packet.
  141. //
  142. MessageHeader.Length = sizeof(*m);
  143. MessageHeader.Buffer = (PCHAR)m;
  144. BdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
  145. &MessageHeader,
  146. AdditionalData);
  147. return;
  148. }
  149. VOID
  150. BdWriteControlSpace(
  151. IN PDBGKD_MANIPULATE_STATE64 m,
  152. IN PSTRING AdditionalData,
  153. IN PCONTEXT Context
  154. )
  155. /*++
  156. Routine Description:
  157. This function writes control space.
  158. Arguments:
  159. m - Supplies a pointer to the state manipulation message.
  160. AdditionalData - Supplies any additional data for the message.
  161. Context - Supplies the current context.
  162. Return Value:
  163. None.
  164. --*/
  165. {
  166. PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory;
  167. ULONG Length;
  168. STRING MessageHeader;
  169. //
  170. // If the specified control registers are within control space, then
  171. // write the specified space and return a success status. Otherwise,
  172. // return an unsuccessful status.
  173. //
  174. Length = min(a->TransferCount, AdditionalData->Length);
  175. if (((PCHAR)a->TargetBaseAddress + Length) <= END_OF_CONTROL_SPACE) {
  176. BdCopyMemory((PCHAR)&BdPrcb.ProcessorState + (ULONG)a->TargetBaseAddress,
  177. AdditionalData->Buffer,
  178. Length);
  179. m->ReturnStatus = STATUS_SUCCESS;
  180. a->ActualBytesWritten = Length;
  181. } else {
  182. m->ReturnStatus = STATUS_UNSUCCESSFUL;
  183. a->ActualBytesWritten = 0;
  184. }
  185. //
  186. // Send reply message.
  187. //
  188. MessageHeader.Length = sizeof(*m);
  189. MessageHeader.Buffer = (PCHAR)m;
  190. BdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
  191. &MessageHeader,
  192. NULL);
  193. return;
  194. }
  195. VOID
  196. BdReadIoSpace(
  197. IN PDBGKD_MANIPULATE_STATE64 m,
  198. IN PSTRING AdditionalData,
  199. IN PCONTEXT Context
  200. )
  201. /*++
  202. Routine Description:
  203. This function reads I/O space.
  204. Arguments:
  205. m - Supplies a pointer to the state manipulation message.
  206. AdditionalData - Supplies any additional data for the message.
  207. Context - Supplies the current context.
  208. Return Value:
  209. None.
  210. --*/
  211. {
  212. PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo;
  213. STRING MessageHeader;
  214. //
  215. // Case of data size and check alignment.
  216. //
  217. m->ReturnStatus = STATUS_SUCCESS;
  218. switch (a->DataSize) {
  219. case 1:
  220. a->DataValue = (ULONG)READ_PORT_UCHAR((PUCHAR)a->IoAddress);
  221. break;
  222. case 2:
  223. if (((ULONG)a->IoAddress & 1) != 0) {
  224. m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
  225. } else {
  226. a->DataValue = (ULONG)READ_PORT_USHORT((PUSHORT)a->IoAddress);
  227. }
  228. break;
  229. case 4:
  230. if (((ULONG)a->IoAddress & 3) != 0) {
  231. m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
  232. } else {
  233. a->DataValue = READ_PORT_ULONG((PULONG)a->IoAddress);
  234. }
  235. break;
  236. default:
  237. m->ReturnStatus = STATUS_INVALID_PARAMETER;
  238. break;
  239. }
  240. //
  241. // Send reply packet.
  242. //
  243. MessageHeader.Length = sizeof(*m);
  244. MessageHeader.Buffer = (PCHAR)m;
  245. BdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
  246. &MessageHeader,
  247. NULL);
  248. return;
  249. }
  250. VOID
  251. BdWriteIoSpace(
  252. IN PDBGKD_MANIPULATE_STATE64 m,
  253. IN PSTRING AdditionalData,
  254. IN PCONTEXT Context
  255. )
  256. /*++
  257. Routine Description:
  258. This function wrties I/O space.
  259. Arguments:
  260. m - Supplies a pointer to the state manipulation message.
  261. AdditionalData - Supplies any additional data for the message.
  262. Context - Supplies the current context.
  263. Return Value:
  264. None.
  265. --*/
  266. {
  267. PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo;
  268. STRING MessageHeader;
  269. //
  270. // Case on data size and check alignment.
  271. //
  272. m->ReturnStatus = STATUS_SUCCESS;
  273. switch (a->DataSize) {
  274. case 1:
  275. WRITE_PORT_UCHAR((PUCHAR)a->IoAddress, (UCHAR)a->DataValue);
  276. break;
  277. case 2:
  278. if (((ULONG)a->IoAddress & 1) != 0) {
  279. m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
  280. } else {
  281. WRITE_PORT_USHORT((PUSHORT)a->IoAddress, (USHORT)a->DataValue);
  282. }
  283. break;
  284. case 4:
  285. if (((ULONG)a->IoAddress & 3) != 0) {
  286. m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
  287. } else {
  288. WRITE_PORT_ULONG((PULONG)a->IoAddress, a->DataValue);
  289. }
  290. break;
  291. default:
  292. m->ReturnStatus = STATUS_INVALID_PARAMETER;
  293. break;
  294. }
  295. //
  296. // Send reply packet.
  297. //
  298. MessageHeader.Length = sizeof(*m);
  299. MessageHeader.Buffer = (PCHAR)m;
  300. BdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
  301. &MessageHeader,
  302. NULL);
  303. return;
  304. }