Leaked source code of windows server 2003
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.

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