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.

583 lines
11 KiB

  1. /*++
  2. Copyright (c) 1990-2001 Microsoft Corporation
  3. Module Name:
  4. kdcpuapi.c
  5. Abstract:
  6. This module implements CPU specific remote debug APIs.
  7. Author:
  8. Chuck Bauman 14-Aug-1993
  9. Revision History:
  10. Based on Mark Lucovsky (markl) MIPS version 04-Sep-1990
  11. --*/
  12. #include "kdp.h"
  13. #define END_OF_CONTROL_SPACE (sizeof(KPROCESSOR_STATE))
  14. ULONG64
  15. KiReadMsr(
  16. IN ULONG Msr
  17. );
  18. VOID
  19. KiWriteMsr(
  20. IN ULONG Msr,
  21. IN ULONG64 Value
  22. );
  23. VOID
  24. KdpSetContextState (
  25. IN OUT PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
  26. IN PCONTEXT ContextRecord
  27. )
  28. /*++
  29. Routine Description:
  30. Fill in the Wait_State_Change message record with context information.
  31. Arguments:
  32. WaitStateChange - Supplies pointer to record to fill in
  33. ContextRecord - Supplies a pointer to a context record.
  34. Return Value:
  35. None.
  36. --*/
  37. {
  38. // No CPU specific work necessary.
  39. }
  40. VOID
  41. KdpSetStateChange (
  42. IN OUT PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
  43. IN PEXCEPTION_RECORD ExceptionRecord,
  44. IN PCONTEXT ContextRecord,
  45. IN BOOLEAN SecondChance
  46. )
  47. /*++
  48. Routine Description:
  49. Fill in the Wait_State_Change message record.
  50. Arguments:
  51. WaitStateChange - Supplies pointer to record to fill in
  52. ExceptionRecord - Supplies a pointer to an exception record.
  53. ContextRecord - Supplies a pointer to a context record.
  54. SecondChance - Supplies a boolean value that determines whether this is
  55. the first or second chance for the exception.
  56. Return Value:
  57. None.
  58. --*/
  59. {
  60. // No CPU specific work necessary.
  61. }
  62. VOID
  63. KdpGetStateChange (
  64. IN PDBGKD_MANIPULATE_STATE64 ManipulateState,
  65. IN PCONTEXT ContextRecord
  66. )
  67. /*++
  68. Routine Description:
  69. Extract continuation control data from Manipulate_State message
  70. N.B. This is a noop for MIPS.
  71. Arguments:
  72. ManipulateState - supplies pointer to Manipulate_State packet
  73. ContextRecord - Supplies a pointer to a context record.
  74. Return Value:
  75. None.
  76. --*/
  77. {
  78. if (NT_SUCCESS(ManipulateState->u.Continue2.ContinueStatus) == TRUE) {
  79. //
  80. // If NT_SUCCESS returns TRUE, then the debugger is doing a
  81. // continue, and it makes sense to apply control changes.
  82. // Otherwise the debugger is saying that it doesn't know what
  83. // to do with this exception, so control values are ignored.
  84. //
  85. //
  86. // Clear .ss (bit 40 - single step) and .tb (bit 26 - taken branch) flags here
  87. //
  88. {
  89. PPSR ContextIPSR = (PPSR)&ContextRecord->StIPSR;
  90. ContextIPSR->sb.psr_ss =
  91. ((ManipulateState->u.Continue2.ControlSet.Continue &
  92. IA64_DBGKD_CONTROL_SET_CONTINUE_TRACE_INSTRUCTION) != 0);
  93. ContextIPSR->sb.psr_tb =
  94. ((ManipulateState->u.Continue2.ControlSet.Continue &
  95. IA64_DBGKD_CONTROL_SET_CONTINUE_TRACE_TAKEN_BRANCH) != 0);
  96. }
  97. //
  98. // Set KernelDebugActive if hardware debug registers are in use
  99. //
  100. {
  101. UCHAR KernelDebugActive =
  102. ContextRecord->DbI1 || ContextRecord->DbI3 ||
  103. ContextRecord->DbI5 || ContextRecord->DbI7 ||
  104. ContextRecord->DbD1 || ContextRecord->DbD3 ||
  105. ContextRecord->DbD5 || ContextRecord->DbD7;
  106. USHORT Proc;
  107. for (Proc = 0; Proc < KeNumberProcessors; ++Proc) {
  108. PKPCR Pcr = (PKPCR)(KSEG3_BASE +
  109. (KiProcessorBlock[Proc]->PcrPage <<
  110. PAGE_SHIFT));
  111. Pcr->KernelDebugActive = KernelDebugActive;
  112. }
  113. }
  114. }
  115. }
  116. NTSTATUS
  117. KdpSysReadControlSpace(
  118. ULONG Processor,
  119. ULONG64 Address,
  120. PVOID Buffer,
  121. ULONG Request,
  122. PULONG Actual
  123. )
  124. /*++
  125. Routine Description:
  126. Reads implementation specific system data.
  127. Arguments:
  128. Processor - Processor's information to access.
  129. Address - Offset in control space.
  130. Buffer - Data buffer.
  131. Request - Amount of data to move.
  132. Actual - Amount of data actually moved.
  133. Return Value:
  134. NTSTATUS.
  135. --*/
  136. {
  137. ULONG Length;
  138. PVOID Pointer;
  139. PVOID Data;
  140. if (Processor >= (ULONG)KeNumberProcessors) {
  141. *Actual = 0;
  142. return STATUS_UNSUCCESSFUL;
  143. }
  144. //
  145. // Case on address to determine what part of Control space is being read.
  146. //
  147. switch ( Address ) {
  148. //
  149. // Return the pcr address for the current processor.
  150. //
  151. case DEBUG_CONTROL_SPACE_PCR:
  152. Pointer = (PKPCR)(KSEG3_BASE + (KiProcessorBlock[Processor]->PcrPage << PAGE_SHIFT));
  153. Data = &Pointer;
  154. Length = sizeof(Pointer);
  155. break;
  156. //
  157. // Return the prcb address for the current processor.
  158. //
  159. case DEBUG_CONTROL_SPACE_PRCB:
  160. Pointer = KiProcessorBlock[Processor];
  161. Data = &Pointer;
  162. Length = sizeof(Pointer);
  163. break;
  164. //
  165. // Return the pointer to the current thread address for the
  166. // current processor.
  167. //
  168. case DEBUG_CONTROL_SPACE_THREAD:
  169. Pointer = KiProcessorBlock[Processor]->CurrentThread;
  170. Data = &Pointer;
  171. Length = sizeof(Pointer);
  172. break;
  173. case DEBUG_CONTROL_SPACE_KSPECIAL:
  174. Data = &(KiProcessorBlock[Processor]->ProcessorState.SpecialRegisters);
  175. Length = sizeof( KSPECIAL_REGISTERS );
  176. break;
  177. default:
  178. *Actual = 0;
  179. return STATUS_UNSUCCESSFUL;
  180. }
  181. if (Length > Request) {
  182. Length = Request;
  183. }
  184. return KdpCopyToPtr(Buffer, Data, Length, Actual);
  185. }
  186. NTSTATUS
  187. KdpSysWriteControlSpace(
  188. ULONG Processor,
  189. ULONG64 Address,
  190. PVOID Buffer,
  191. ULONG Request,
  192. PULONG Actual
  193. )
  194. /*++
  195. Routine Description:
  196. Writes implementation specific system data.
  197. Arguments:
  198. Processor - Processor's information to access.
  199. Address - Offset in control space.
  200. Buffer - Data buffer.
  201. Request - Amount of data to move.
  202. Actual - Amount of data actually moved.
  203. Return Value:
  204. NTSTATUS.
  205. --*/
  206. {
  207. ULONG Length;
  208. if (Processor >= (ULONG)KeNumberProcessors) {
  209. *Actual = 0;
  210. return STATUS_UNSUCCESSFUL;
  211. }
  212. switch ( Address ) {
  213. case DEBUG_CONTROL_SPACE_KSPECIAL:
  214. if (Request > sizeof(KSPECIAL_REGISTERS)) {
  215. Length = sizeof(KSPECIAL_REGISTERS);
  216. } else {
  217. Length = Request;
  218. }
  219. return KdpCopyFromPtr(&KiProcessorBlock[Processor]->ProcessorState.SpecialRegisters,
  220. Buffer,
  221. Length,
  222. Actual);
  223. default:
  224. *Actual = 0;
  225. return STATUS_UNSUCCESSFUL;
  226. }
  227. }
  228. NTSTATUS
  229. KdpSysReadIoSpace(
  230. INTERFACE_TYPE InterfaceType,
  231. ULONG BusNumber,
  232. ULONG AddressSpace,
  233. ULONG64 Address,
  234. PVOID Buffer,
  235. ULONG Request,
  236. PULONG Actual
  237. )
  238. /*++
  239. Routine Description:
  240. Reads system I/O locations.
  241. Arguments:
  242. InterfaceType - I/O interface type.
  243. BusNumber - Bus number.
  244. AddressSpace - Address space.
  245. Address - I/O address.
  246. Buffer - Data buffer.
  247. Request - Amount of data to move.
  248. Actual - Amount of data actually moved.
  249. Return Value:
  250. NTSTATUS.
  251. --*/
  252. {
  253. PUCHAR b;
  254. PUSHORT s;
  255. PULONG l;
  256. NTSTATUS Status;
  257. *Actual = 0;
  258. if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1) {
  259. return STATUS_UNSUCCESSFUL;
  260. }
  261. //
  262. // Check Size and Alignment
  263. //
  264. switch ( Request ) {
  265. case 1:
  266. *(PUCHAR)Buffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)Address);
  267. *Actual = 1;
  268. break;
  269. case 2:
  270. if ( Address & 1 ) {
  271. Status = STATUS_DATATYPE_MISALIGNMENT;
  272. } else {
  273. *(PUSHORT)Buffer =
  274. READ_PORT_USHORT((PUSHORT)(ULONG_PTR)Address);
  275. *Actual = 2;
  276. }
  277. break;
  278. case 4:
  279. if ( Address & 3 ) {
  280. Status = STATUS_DATATYPE_MISALIGNMENT;
  281. } else {
  282. *(PULONG)Buffer =
  283. READ_PORT_ULONG((PULONG)(ULONG_PTR)Address);
  284. *Actual = 4;
  285. }
  286. break;
  287. default:
  288. Status = STATUS_INVALID_PARAMETER;
  289. break;
  290. }
  291. return Status;
  292. }
  293. NTSTATUS
  294. KdpSysWriteIoSpace(
  295. INTERFACE_TYPE InterfaceType,
  296. ULONG BusNumber,
  297. ULONG AddressSpace,
  298. ULONG64 Address,
  299. PVOID Buffer,
  300. ULONG Request,
  301. PULONG Actual
  302. )
  303. /*++
  304. Routine Description:
  305. Writes system I/O locations.
  306. Arguments:
  307. InterfaceType - I/O interface type.
  308. BusNumber - Bus number.
  309. AddressSpace - Address space.
  310. Address - I/O address.
  311. Buffer - Data buffer.
  312. Request - Amount of data to move.
  313. Actual - Amount of data actually moved.
  314. Return Value:
  315. NTSTATUS.
  316. --*/
  317. {
  318. PUCHAR b;
  319. PUSHORT s;
  320. PULONG l;
  321. HARDWARE_PTE Opaque;
  322. NTSTATUS Status;
  323. ULONG Value;
  324. *Actual = 0;
  325. if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1) {
  326. return STATUS_UNSUCCESSFUL;
  327. }
  328. //
  329. // Check Size and Alignment
  330. //
  331. switch ( Request ) {
  332. case 1:
  333. WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)Address,
  334. *(PUCHAR)Buffer);
  335. *Actual = 1;
  336. break;
  337. case 2:
  338. if ( Address & 1 ) {
  339. Status = STATUS_DATATYPE_MISALIGNMENT;
  340. } else {
  341. WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)Address,
  342. *(PUSHORT)Buffer);
  343. *Actual = 2;
  344. }
  345. break;
  346. case 4:
  347. if ( Address & 3 ) {
  348. Status = STATUS_DATATYPE_MISALIGNMENT;
  349. } else {
  350. WRITE_PORT_ULONG((PULONG)(ULONG_PTR)Address,
  351. *(PULONG)Buffer);
  352. *Actual = 4;
  353. }
  354. break;
  355. default:
  356. Status = STATUS_INVALID_PARAMETER;
  357. break;
  358. }
  359. return Status;
  360. }
  361. NTSTATUS
  362. KdpSysReadMsr(
  363. ULONG Msr,
  364. PULONG64 Data
  365. )
  366. /*++
  367. Routine Description:
  368. Reads an MSR.
  369. Arguments:
  370. Msr - MSR index.
  371. Data - Data buffer.
  372. Return Value:
  373. NTSTATUS.
  374. --*/
  375. {
  376. NTSTATUS Status = STATUS_SUCCESS;
  377. try {
  378. *Data = KiReadMsr(Msr);
  379. } except (EXCEPTION_EXECUTE_HANDLER) {
  380. *Data = 0;
  381. Status = STATUS_NO_SUCH_DEVICE;
  382. }
  383. return Status;
  384. }
  385. NTSTATUS
  386. KdpSysWriteMsr(
  387. ULONG Msr,
  388. PULONG64 Data
  389. )
  390. /*++
  391. Routine Description:
  392. Writes an MSR.
  393. Arguments:
  394. Msr - MSR index.
  395. Data - Data buffer.
  396. Return Value:
  397. NTSTATUS.
  398. --*/
  399. {
  400. NTSTATUS Status = STATUS_SUCCESS;
  401. try {
  402. KiWriteMsr(Msr, *Data);
  403. } except (EXCEPTION_EXECUTE_HANDLER) {
  404. Status = STATUS_NO_SUCH_DEVICE;
  405. }
  406. return Status;
  407. }