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.

1005 lines
28 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. bdtrap.c
  5. Abstract:
  6. This module contains code to implement the target side of the boot debugger.
  7. Author:
  8. David N. Cutler (davec) 30-Nov-96
  9. Revision History:
  10. --*/
  11. #include "bd.h"
  12. #define ALIGN_NATS(Result, Source, Start, AddressOffset, Mask) \
  13. if (AddressOffset == Start) { \
  14. Result = (ULONGLONG)Source; \
  15. } else if (AddressOffset < Start) { \
  16. Result = (ULONGLONG)(Source << (Start - AddressOffset)); \
  17. } else { \
  18. Result = (ULONGLONG)((Source >> (AddressOffset - Start)) | \
  19. (Source << (64 + Start - AddressOffset))); \
  20. } \
  21. Result = Result & (ULONGLONG)Mask
  22. #define EXTRACT_NATS(Result, Source, Start, AddressOffset, Mask) \
  23. Result = (ULONGLONG)(Source & (ULONGLONG)Mask); \
  24. if (AddressOffset < Start) { \
  25. Result = Result >> (Start - AddressOffset); \
  26. } else if (AddressOffset > Start) { \
  27. Result = ((Result << (AddressOffset - Start)) | \
  28. (Result >> (64 + Start - AddressOffset))); \
  29. }
  30. //
  31. // Define forward referenced function prototypes.
  32. //
  33. VOID
  34. BdRestoreKframe(
  35. IN OUT PKTRAP_FRAME TrapFrame,
  36. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  37. IN PCONTEXT ContextRecord
  38. );
  39. VOID
  40. BdSaveKframe(
  41. IN OUT PKTRAP_FRAME TrapFrame,
  42. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  43. OUT PCONTEXT ContextRecord
  44. );
  45. LOGICAL
  46. BdEnterDebugger(
  47. IN PKTRAP_FRAME TrapFrame,
  48. IN PKEXCEPTION_FRAME ExceptionFrame
  49. )
  50. {
  51. return FALSE;
  52. }
  53. VOID
  54. BdExitDebugger(
  55. IN LOGICAL Enable
  56. )
  57. {
  58. }
  59. VOID
  60. BdGetDebugContext (
  61. IN PKTRAP_FRAME TrapFrame,
  62. IN OUT PCONTEXT ContextFrame
  63. )
  64. /*++
  65. Routine Description:
  66. This routine moves the user mode h/w debug registers from the debug register
  67. save area in the kernel stack to the context record.
  68. Arguments:
  69. TrapFrame - Supplies a pointer to a trap frame from which volatile context
  70. should be copied into the context record.
  71. ContextFrame - Supplies a pointer to the context frame that receives the
  72. context.
  73. Return Value:
  74. None.
  75. Note:
  76. PSR.db must be set to activate the debug registers.
  77. This is used for getting user mode debug registers.
  78. --*/
  79. {
  80. PKDEBUG_REGISTERS DebugRegistersSaveArea;
  81. if (TrapFrame->PreviousMode == UserMode) {
  82. DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA();
  83. BdCopyMemory((PVOID)&ContextFrame->DbI0,
  84. (PVOID)DebugRegistersSaveArea,
  85. sizeof(KDEBUG_REGISTERS));
  86. }
  87. }
  88. VOID
  89. BdSetDebugContext (
  90. IN OUT PKTRAP_FRAME TrapFrame,
  91. IN PCONTEXT ContextFrame,
  92. IN KPROCESSOR_MODE PreviousMode
  93. )
  94. /*++
  95. Routine Description:
  96. This routine moves the debug context from the specified context frame into
  97. the debug registers save area in the kernel stack.
  98. Arguments:
  99. TrapFrame - Supplies a pointer to a trap frame.
  100. ContextFrame - Supplies a pointer to a context frame that contains the
  101. context that is to be copied.
  102. PreviousMode - Supplies the processor mode for the target context.
  103. Return Value:
  104. None.
  105. Notes:
  106. PSR.db must be set to activate the debug registers.
  107. This is used for setting up debug registers for user mode.
  108. --*/
  109. {
  110. PKDEBUG_REGISTERS DebugRegistersSaveArea; // User mode h/w debug registers
  111. if (PreviousMode == UserMode) {
  112. DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA();
  113. //
  114. // Sanitize the debug control regs. Leave the addresses unchanged.
  115. //
  116. DebugRegistersSaveArea->DbI0 = ContextFrame->DbI0;
  117. DebugRegistersSaveArea->DbI1 = SANITIZE_DR(ContextFrame->DbI1,UserMode);
  118. DebugRegistersSaveArea->DbI2 = ContextFrame->DbI2;
  119. DebugRegistersSaveArea->DbI3 = SANITIZE_DR(ContextFrame->DbI3,UserMode);
  120. DebugRegistersSaveArea->DbI4 = ContextFrame->DbI4;
  121. DebugRegistersSaveArea->DbI5 = SANITIZE_DR(ContextFrame->DbI5,UserMode);
  122. DebugRegistersSaveArea->DbI6 = ContextFrame->DbI6;
  123. DebugRegistersSaveArea->DbI7 = SANITIZE_DR(ContextFrame->DbI7,UserMode);
  124. DebugRegistersSaveArea->DbD0 = ContextFrame->DbD0;
  125. DebugRegistersSaveArea->DbD1 = SANITIZE_DR(ContextFrame->DbD1,UserMode);
  126. DebugRegistersSaveArea->DbD2 = ContextFrame->DbD2;
  127. DebugRegistersSaveArea->DbD3 = SANITIZE_DR(ContextFrame->DbD3,UserMode);
  128. DebugRegistersSaveArea->DbD4 = ContextFrame->DbD4;
  129. DebugRegistersSaveArea->DbD5 = SANITIZE_DR(ContextFrame->DbD5,UserMode);
  130. DebugRegistersSaveArea->DbD6 = ContextFrame->DbD6;
  131. DebugRegistersSaveArea->DbD7 = SANITIZE_DR(ContextFrame->DbD7,UserMode);
  132. }
  133. }
  134. LOGICAL
  135. BdTrap (
  136. IN PEXCEPTION_RECORD ExceptionRecord,
  137. IN PKEXCEPTION_FRAME ExceptionFrame,
  138. IN PKTRAP_FRAME TrapFrame
  139. )
  140. /*++
  141. Routine Description:
  142. This routine is called whenever a exception is dispatched and the boot
  143. debugger is active.
  144. Arguments:
  145. ExceptionRecord - Supplies a pointer to an exception record that
  146. describes the exception.
  147. ExceptionFrame - Supplies a pointer to an exception frame (NULL).
  148. TrapFrame - Supplies a pointer to a trap frame that describes the
  149. trap.
  150. Return Value:
  151. A value of TRUE is returned if the exception is handled. Otherwise a
  152. value of FALSE is returned.
  153. --*/
  154. {
  155. LOGICAL Completion;
  156. PCONTEXT ContextRecord;
  157. ULONG OldEip;
  158. STRING Reply;
  159. STRING String;
  160. PKD_SYMBOLS_INFO SymbolInfo;
  161. LOGICAL UnloadSymbols;
  162. LOGICAL Enable;
  163. ULONGLONG OldStIIP, OldStIPSR;
  164. STRING Input;
  165. STRING Output;
  166. //
  167. // Set address of context record and set context flags.
  168. //
  169. ContextRecord = &BdPrcb.ProcessorState.ContextFrame;
  170. ContextRecord->ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG;
  171. BdSaveKframe(TrapFrame, ExceptionFrame, ContextRecord);
  172. //
  173. // Print, prompt, load symbols, and unload symbols are all special cases
  174. // of STATUS_BREAKPOINT.
  175. //
  176. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
  177. (ExceptionRecord->ExceptionInformation[0] != KERNEL_BREAKPOINT)) {
  178. //
  179. // Switch on the breakpoint code.
  180. //
  181. switch (ExceptionRecord->ExceptionInformation[0]) {
  182. //
  183. // Print a debug string.
  184. //
  185. // Arguments: IA64 passes arguments via RSE not GR's. Since arguments are not
  186. // part of CONTEXT struct, they need to be copies Temp registers.
  187. // (see NTOS/RTL/IA64/DEBUGSTB.S)
  188. //
  189. // T0 - Supplies a pointer to an output string buffer.
  190. // T1 - Supplies the length of the output string buffer.
  191. //
  192. case BREAKPOINT_PRINT:
  193. //
  194. // Advance to next instruction slot so that the BREAK instruction
  195. // does not get re-executed
  196. //
  197. RtlIa64IncrementIP((ULONG_PTR)ExceptionRecord->ExceptionAddress >> 2,
  198. ContextRecord->StIPSR,
  199. ContextRecord->StIIP);
  200. Output.Buffer = (PCHAR)ContextRecord->IntT0;
  201. Output.Length = (USHORT)ContextRecord->IntT1;
  202. // KdLogDbgPrint(&Output);
  203. if (BdDebuggerNotPresent == FALSE) {
  204. Enable = BdEnterDebugger(TrapFrame, ExceptionFrame);
  205. if (BdPrintString(&Output)) {
  206. ContextRecord->IntV0 = (ULONG)STATUS_BREAKPOINT;
  207. } else {
  208. ContextRecord->IntV0 = (ULONG)STATUS_SUCCESS;
  209. }
  210. BdExitDebugger(Enable);
  211. } else {
  212. ContextRecord->IntV0 = (ULONG)STATUS_DEVICE_NOT_CONNECTED;
  213. }
  214. BdRestoreKframe(TrapFrame, ExceptionFrame, ContextRecord);
  215. return TRUE;
  216. //
  217. // Print a debug prompt string, then input a string.
  218. //
  219. // T0 - Supplies a pointer to an output string buffer.
  220. // T1 - Supplies the length of the output string buffer..
  221. // T2 - supplies a pointer to an input string buffer.
  222. // T3 - Supplies the length of the input string bufffer.
  223. //
  224. case BREAKPOINT_PROMPT:
  225. //
  226. // Advance to next instruction slot so that the BREAK instruction
  227. // does not get re-executed
  228. //
  229. RtlIa64IncrementIP((ULONG_PTR)ExceptionRecord->ExceptionAddress >> 2,
  230. ContextRecord->StIPSR,
  231. ContextRecord->StIIP);
  232. Output.Buffer = (PCHAR)ContextRecord->IntT0;
  233. Output.Length = (USHORT)ContextRecord->IntT1;
  234. Input.Buffer = (PCHAR)ContextRecord->IntT2;
  235. Input.MaximumLength = (USHORT)ContextRecord->IntT3;
  236. // BdPrintString(&Output);
  237. Enable = BdEnterDebugger(TrapFrame, ExceptionFrame);
  238. BdPromptString(&Output, &Input);
  239. ContextRecord->IntV0 = Input.Length;
  240. BdExitDebugger(Enable);
  241. BdRestoreKframe(TrapFrame, ExceptionFrame, ContextRecord);
  242. return TRUE;
  243. //
  244. // Load the symbolic information for an image.
  245. //
  246. // Arguments:
  247. //
  248. // T0 - Supplies a pointer to an output string descriptor.
  249. // T1 - Supplies a the base address of the image.
  250. //
  251. case BREAKPOINT_UNLOAD_SYMBOLS:
  252. UnloadSymbols = TRUE;
  253. //
  254. // Fall through
  255. //
  256. case BREAKPOINT_LOAD_SYMBOLS:
  257. //
  258. // Advance to next instruction slot so that the BREAK instruction
  259. // does not get re-executed
  260. //
  261. Enable = BdEnterDebugger(TrapFrame, ExceptionFrame);
  262. OldStIPSR = ContextRecord->StIPSR;
  263. OldStIIP = ContextRecord->StIIP;
  264. if (BdDebuggerNotPresent == FALSE) {
  265. BdReportLoadSymbolsStateChange((PSTRING)ContextRecord->IntT0,
  266. (PKD_SYMBOLS_INFO) ContextRecord->IntT1,
  267. UnloadSymbols,
  268. ContextRecord);
  269. }
  270. BdExitDebugger(Enable);
  271. //
  272. // If the kernel debugger did not update the IP, then increment
  273. // past the breakpoint instruction.
  274. //
  275. if ((ContextRecord->StIIP == OldStIIP) &&
  276. ((ContextRecord->StIPSR & IPSR_RI_MASK) == (OldStIPSR & IPSR_RI_MASK))) {
  277. RtlIa64IncrementIP((ULONG_PTR)ExceptionRecord->ExceptionAddress >> 2,
  278. ContextRecord->StIPSR,
  279. ContextRecord->StIIP);
  280. }
  281. BdRestoreKframe(TrapFrame, ExceptionFrame, ContextRecord);
  282. return TRUE;
  283. //
  284. // Kernel breakin break
  285. //
  286. case BREAKPOINT_BREAKIN:
  287. //
  288. // Advance to next instruction slot so that the BREAK instruction
  289. // does not get re-executed
  290. //
  291. RtlIa64IncrementIP((ULONG_PTR)ExceptionRecord->ExceptionAddress >> 2,
  292. ContextRecord->StIPSR,
  293. ContextRecord->StIIP);
  294. break;
  295. //
  296. // Unknown internal command.
  297. //
  298. default:
  299. break;
  300. }
  301. }
  302. //
  303. // Get here if single step or BREAKIN breakpoint
  304. //
  305. if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) ||
  306. (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) ) {
  307. //
  308. // Report state change to kernel debugger on host
  309. //
  310. Enable = BdEnterDebugger(TrapFrame, ExceptionFrame);
  311. Completion = BdReportExceptionStateChange(
  312. ExceptionRecord,
  313. &BdPrcb.ProcessorState.ContextFrame);
  314. BdExitDebugger(Enable);
  315. BdControlCPressed = FALSE;
  316. } else {
  317. //
  318. // This is real exception that user doesn't want to see,
  319. // so do NOT report it to debugger.
  320. //
  321. // return FALSE;
  322. }
  323. BdRestoreKframe(TrapFrame, ExceptionFrame, ContextRecord);
  324. return TRUE;
  325. }
  326. LOGICAL
  327. BdStub (
  328. IN PEXCEPTION_RECORD ExceptionRecord,
  329. IN PKEXCEPTION_FRAME ExceptionFrame,
  330. IN PKTRAP_FRAME TrapFrame
  331. )
  332. /*++
  333. Routine Description:
  334. This routine provides a kernel debugger stub routine to catch debug
  335. prints when the boot debugger is not active.
  336. Arguments:
  337. ExceptionRecord - Supplies a pointer to an exception record that
  338. describes the exception.
  339. ExceptionFrame - Supplies a pointer to an exception frame (NULL).
  340. TrapFrame - Supplies a pointer to a trap frame that describes the
  341. trap.
  342. Return Value:
  343. A value of TRUE is returned if the exception is handled. Otherwise a
  344. value of FALSE is returned.
  345. --*/
  346. {
  347. ULONG_PTR BreakpointCode;
  348. //
  349. // Isolate the breakpoint code from the breakpoint instruction which
  350. // is stored by the exception dispatch code in the information field
  351. // of the exception record.
  352. //
  353. BreakpointCode = (ULONG) ExceptionRecord->ExceptionInformation[0];
  354. //
  355. // If the breakpoint is a debug print, debug load symbols, or debug
  356. // unload symbols, then return TRUE. Otherwise, return FALSE;
  357. //
  358. if ((BreakpointCode == BREAKPOINT_PRINT) ||
  359. (BreakpointCode == BREAKPOINT_LOAD_SYMBOLS) ||
  360. (BreakpointCode == BREAKPOINT_UNLOAD_SYMBOLS)) {
  361. //
  362. // Advance to next instruction slot so that the BREAK instruction
  363. // does not get re-executed
  364. //
  365. RtlIa64IncrementIP((ULONG_PTR)ExceptionRecord->ExceptionAddress >> 2,
  366. TrapFrame->StIPSR,
  367. TrapFrame->StIIP);
  368. return TRUE;
  369. } else {
  370. return FALSE;
  371. }
  372. }
  373. VOID
  374. BdRestoreKframe(
  375. IN OUT PKTRAP_FRAME TrapFrame,
  376. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  377. IN PCONTEXT ContextFrame
  378. )
  379. /*++
  380. Routine Description:
  381. This routine moves the selected contents of the specified context frame into
  382. the specified trap and exception frames according to the specified context
  383. flags.
  384. Arguments:
  385. TrapFrame - Supplies a pointer to a trap frame that receives the volatile
  386. context from the context record.
  387. ExceptionFrame - Supplies a pointer to an exception frame that receives
  388. the nonvolatile context from the context record.
  389. ContextFrame - Supplies a pointer to a context frame that contains the
  390. context that is to be copied into the trap and exception frames.
  391. Return Value:
  392. None.
  393. --*/
  394. {
  395. USHORT R1Offset, R4Offset;
  396. USHORT RNatSaveIndex;
  397. SHORT BsFrameSize;
  398. SHORT TempFrameSize;
  399. ULONG ContextFlags=CONTEXT_FULL;
  400. //
  401. // Set control information if specified.
  402. //
  403. if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  404. TrapFrame->IntGp = ContextFrame->IntGp;
  405. TrapFrame->IntSp = ContextFrame->IntSp;
  406. TrapFrame->ApUNAT = ContextFrame->ApUNAT;
  407. TrapFrame->BrRp = ContextFrame->BrRp;
  408. TrapFrame->ApCCV = ContextFrame->ApCCV;
  409. TrapFrame->ApDCR = ContextFrame->ApDCR;
  410. //
  411. // Set preserved applicaton registers in exception frame.
  412. //
  413. ExceptionFrame->ApLC = ContextFrame->ApLC;
  414. ExceptionFrame->ApEC &= ~(PFS_EC_MASK << PFS_EC_MASK);
  415. ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT);
  416. //
  417. // Set RSE control states in the trap frame.
  418. //
  419. TrapFrame->RsPFS = ContextFrame->RsPFS;
  420. BsFrameSize = (SHORT)(ContextFrame->StIFS & PFS_SIZE_MASK);
  421. RNatSaveIndex = (USHORT)((ContextFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG);
  422. TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG;
  423. while (TempFrameSize >= 0) {
  424. BsFrameSize++;
  425. TempFrameSize -= NAT_BITS_PER_RNAT_REG;
  426. }
  427. TrapFrame->RsBSPSTORE = ContextFrame->RsBSPSTORE + BsFrameSize * 8;
  428. TrapFrame->RsBSP = TrapFrame->RsBSPSTORE;
  429. TrapFrame->RsRSC = ContextFrame->RsRSC;
  430. TrapFrame->RsRNAT = ContextFrame->RsRNAT;
  431. #if DEBUG
  432. DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT);
  433. #endif // DEBUG
  434. //
  435. // Set FPSR, IPSR, IIP, and IFS in the trap frame.
  436. //
  437. TrapFrame->StFPSR = ContextFrame->StFPSR;
  438. TrapFrame->StIPSR = ContextFrame->StIPSR;
  439. TrapFrame->StIFS = ContextFrame->StIFS;
  440. TrapFrame->StIIP = ContextFrame->StIIP;
  441. #if 0
  442. //
  443. // DebugActive controls h/w debug registers. Set if new psr.db = 1
  444. //
  445. KeGetCurrentThread()->DebugActive = ((TrapFrame->StIPSR & (1I64 << PSR_DB)) != 0);
  446. //
  447. // Set application registers directly
  448. // *** TBD SANATIZE??
  449. //
  450. if (PreviousMode == UserMode ) {
  451. __setReg(CV_IA64_AR21, ContextFrame->StFCR);
  452. __setReg(CV_IA64_AR24, ContextFrame->Eflag);
  453. __setReg(CV_IA64_AR25, ContextFrame->SegCSD);
  454. __setReg(CV_IA64_AR26, ContextFrame->SegSSD);
  455. __setReg(CV_IA64_AR27, ContextFrame->Cflag);
  456. __setReg(CV_IA64_AR28, ContextFrame->StFSR);
  457. __setReg(CV_IA64_AR29, ContextFrame->StFIR);
  458. __setReg(CV_IA64_AR30, ContextFrame->StFDR);
  459. }
  460. #endif
  461. }
  462. //
  463. // Set integer registers contents if specified.
  464. //
  465. if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  466. TrapFrame->IntT0 = ContextFrame->IntT0;
  467. TrapFrame->IntT1 = ContextFrame->IntT1;
  468. TrapFrame->IntT2 = ContextFrame->IntT2;
  469. TrapFrame->IntT3 = ContextFrame->IntT3;
  470. TrapFrame->IntT4 = ContextFrame->IntT4;
  471. TrapFrame->IntV0 = ContextFrame->IntV0;
  472. TrapFrame->IntTeb = ContextFrame->IntTeb;
  473. TrapFrame->Preds = ContextFrame->Preds;
  474. //
  475. // t5 - t22
  476. //
  477. memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  478. //
  479. // Set integer registers s0 - s3 in exception frame.
  480. //
  481. ExceptionFrame->IntS0 = ContextFrame->IntS0;
  482. ExceptionFrame->IntS1 = ContextFrame->IntS1;
  483. ExceptionFrame->IntS2 = ContextFrame->IntS2;
  484. ExceptionFrame->IntS3 = ContextFrame->IntS3;
  485. //
  486. // Set the integer nats field in the trap & exception frames
  487. //
  488. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  489. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  490. EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats,
  491. 1, R1Offset, 0xFFFFFF0E);
  492. EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats,
  493. 4, R4Offset, 0xF0);
  494. #if DEBUG
  495. DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n",
  496. TrapFrame->IntNats, ContextFrame->IntNats, R1Offset);
  497. DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n",
  498. ExceptionFrame->IntNats, R4Offset);
  499. #endif // DEBUG
  500. //
  501. // Set other branch registers in trap and exception frames
  502. //
  503. TrapFrame->BrT0 = ContextFrame->BrT0;
  504. TrapFrame->BrT1 = ContextFrame->BrT1;
  505. memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG));
  506. }
  507. //
  508. // Set lower floating register contents if specified.
  509. //
  510. if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  511. TrapFrame->StFPSR = ContextFrame->StFPSR;
  512. //
  513. // Set floating registers fs0 - fs19 in exception frame.
  514. //
  515. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0,
  516. &ContextFrame->FltS0,
  517. sizeof(FLOAT128) * (4));
  518. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4,
  519. &ContextFrame->FltS4,
  520. 16*sizeof(FLOAT128));
  521. //
  522. // Set floating registers ft0 - ft9 in trap frame.
  523. //
  524. RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0,
  525. &ContextFrame->FltT0,
  526. sizeof(FLOAT128) * (10));
  527. }
  528. //
  529. // Set higher floating register contents if specified.
  530. //
  531. if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  532. TrapFrame->StFPSR = ContextFrame->StFPSR;
  533. #if 0
  534. if (PreviousMode == UserMode) {
  535. //
  536. // Update the higher floating point save area (f32-f127) and
  537. // set the corresponding modified bit in the PSR to 1.
  538. //
  539. RtlCopyIa64FloatRegisterContext(
  540. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(),
  541. &ContextFrame->FltF32,
  542. 96*sizeof(FLOAT128)
  543. );
  544. //
  545. // set the dfh bit to force a reload of the high fp register
  546. // set on the next user access
  547. //
  548. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  549. }
  550. #endif
  551. }
  552. #if 0
  553. //
  554. // Set debug registers.
  555. //
  556. if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  557. BdSetDebugContext (TrapFrame, ContextFrame, 0);
  558. }
  559. #endif
  560. return;
  561. }
  562. VOID
  563. BdSaveKframe(
  564. IN OUT PKTRAP_FRAME TrapFrame,
  565. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  566. IN PCONTEXT ContextFrame
  567. )
  568. /*++
  569. Routine Description:
  570. This routine moves the selected contents of the specified trap and exception
  571. frames into the specified context frame according to the specified context
  572. flags.
  573. Arguments:
  574. TrapFrame - Supplies a pointer to a trap frame from which volatile context
  575. should be copied into the context record.
  576. ExceptionFrame - Supplies a pointer to an exception frame from which context
  577. should be copied into the context record.
  578. ContextFrame - Supplies a pointer to the context frame that receives the
  579. context copied from the trap and exception frames.
  580. Return Value:
  581. None.
  582. --*/
  583. {
  584. ULONGLONG IntNats1, IntNats2;
  585. USHORT R1Offset, R4Offset;
  586. USHORT RNatSaveIndex;
  587. SHORT BsFrameSize;
  588. SHORT TempFrameSize;
  589. ULONG ContextFlags=CONTEXT_FULL;
  590. //
  591. // Set control information if specified.
  592. //
  593. if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  594. ContextFrame->IntGp = TrapFrame->IntGp;
  595. ContextFrame->IntSp = TrapFrame->IntSp;
  596. ContextFrame->ApUNAT = TrapFrame->ApUNAT;
  597. ContextFrame->BrRp = TrapFrame->BrRp;
  598. ContextFrame->ApCCV = TrapFrame->ApCCV;
  599. ContextFrame->ApDCR = TrapFrame->ApDCR;
  600. ContextFrame->StFPSR = TrapFrame->StFPSR;
  601. ContextFrame->StIPSR = TrapFrame->StIPSR;
  602. ContextFrame->StIIP = TrapFrame->StIIP;
  603. ContextFrame->StIFS = TrapFrame->StIFS;
  604. //
  605. // Set RSE control states from the trap frame.
  606. //
  607. ContextFrame->RsPFS = TrapFrame->RsPFS;
  608. BsFrameSize = (SHORT)(TrapFrame->StIFS & PFS_SIZE_MASK);
  609. RNatSaveIndex = (USHORT) (TrapFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG;
  610. TempFrameSize = BsFrameSize - RNatSaveIndex;
  611. while (TempFrameSize > 0) {
  612. BsFrameSize++;
  613. TempFrameSize -= NAT_BITS_PER_RNAT_REG;
  614. }
  615. ContextFrame->RsBSP = TrapFrame->RsBSP - BsFrameSize * 8;
  616. ContextFrame->RsBSPSTORE = ContextFrame->RsBSP;
  617. ContextFrame->RsRSC = TrapFrame->RsRSC;
  618. ContextFrame->RsRNAT = TrapFrame->RsRNAT;
  619. #if DEBUG
  620. DbgPrint("KeContextFromKFrames: RsRNAT = 0x%I64x\n",
  621. ContextFrame->RsRNAT);
  622. #endif // DEBUG
  623. //
  624. // Set preserved applicaton registers from exception frame.
  625. //
  626. ContextFrame->ApLC = ExceptionFrame->ApLC;
  627. ContextFrame->ApEC = (ExceptionFrame->ApEC >> PFS_EC_SHIFT) & PFS_EC_MASK;
  628. //
  629. // Get iA status from the application registers
  630. //
  631. ContextFrame->StFCR = __getReg(CV_IA64_AR21);
  632. ContextFrame->Eflag = __getReg(CV_IA64_AR24);
  633. ContextFrame->SegCSD = __getReg(CV_IA64_AR25);
  634. ContextFrame->SegSSD = __getReg(CV_IA64_AR26);
  635. ContextFrame->Cflag = __getReg(CV_IA64_AR27);
  636. ContextFrame->StFSR = __getReg(CV_IA64_AR28);
  637. ContextFrame->StFIR = __getReg(CV_IA64_AR29);
  638. ContextFrame->StFDR = __getReg(CV_IA64_AR30);
  639. }
  640. //
  641. // Set integer register contents if specified.
  642. //
  643. if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  644. ContextFrame->IntT0 = TrapFrame->IntT0;
  645. ContextFrame->IntT1 = TrapFrame->IntT1;
  646. ContextFrame->IntT2 = TrapFrame->IntT2;
  647. ContextFrame->IntT3 = TrapFrame->IntT3;
  648. ContextFrame->IntT4 = TrapFrame->IntT4;
  649. ContextFrame->IntV0 = TrapFrame->IntV0;
  650. ContextFrame->IntTeb = TrapFrame->IntTeb;
  651. ContextFrame->Preds = TrapFrame->Preds;
  652. //
  653. // t5 - t22
  654. //
  655. memcpy(&ContextFrame->IntT5, &TrapFrame->IntT5, 18*sizeof(ULONGLONG));
  656. //
  657. // Set branch registers from trap frame & exception frame
  658. //
  659. ContextFrame->BrT0 = TrapFrame->BrT0;
  660. ContextFrame->BrT1 = TrapFrame->BrT1;
  661. memcpy(&ContextFrame->BrS0, &ExceptionFrame->BrS0, 5*sizeof(ULONGLONG));
  662. //
  663. // Set integer registers s0 - s3 from exception frame.
  664. //
  665. ContextFrame->IntS0 = ExceptionFrame->IntS0;
  666. ContextFrame->IntS1 = ExceptionFrame->IntS1;
  667. ContextFrame->IntS2 = ExceptionFrame->IntS2;
  668. ContextFrame->IntS3 = ExceptionFrame->IntS3;
  669. //
  670. // Set the integer nats field in the context
  671. //
  672. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  673. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  674. ALIGN_NATS(IntNats1, TrapFrame->IntNats, 1, R1Offset, 0xFFFFFF0E);
  675. ALIGN_NATS(IntNats2, ExceptionFrame->IntNats, 4, R4Offset, 0xF0);
  676. ContextFrame->IntNats = IntNats1 | IntNats2;
  677. #if DEBUG
  678. DbgPrint("KeContextFromKFrames: TF->IntNats = 0x%I64x, R1OffSet = 0x%x, R4Offset = 0x%x\n",
  679. TrapFrame->IntNats, R1Offset, R4Offset);
  680. DbgPrint("KeContextFromKFrames: CF->IntNats = 0x%I64x, IntNats1 = 0x%I64x, IntNats2 = 0x%I64x\n",
  681. ContextFrame->IntNats, IntNats1, IntNats2);
  682. #endif // DEBUG
  683. }
  684. //
  685. // Set lower floating register contents if specified.
  686. //
  687. if ((ContextFrame->ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  688. //
  689. // Set EM + ia32 FP status
  690. //
  691. ContextFrame->StFPSR = TrapFrame->StFPSR;
  692. //
  693. // Set floating registers fs0 - fs19 from exception frame.
  694. //
  695. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS0,
  696. &ExceptionFrame->FltS0,
  697. sizeof(FLOAT128) * (4));
  698. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS4,
  699. &ExceptionFrame->FltS4,
  700. 16*sizeof(FLOAT128));
  701. //
  702. // Set floating registers ft0 - ft9 from trap frame.
  703. //
  704. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltT0,
  705. &TrapFrame->FltT0,
  706. sizeof(FLOAT128) * (10));
  707. }
  708. #if 0
  709. if ((ContextFrame->ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  710. ContextFrame->StFPSR = TrapFrame->StFPSR;
  711. //
  712. // Set floating regs f32 - f127 from higher floating point save area
  713. //
  714. if (TrapFrame->PreviousMode == UserMode) {
  715. RtlCopyIa64FloatRegisterContext(
  716. &ContextFrame->FltF32,
  717. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(),
  718. 96*sizeof(FLOAT128)
  719. );
  720. }
  721. }
  722. //
  723. // Get user debug registers from save area in kernel stack.
  724. // Note: PSR.db must be set to activate the debug registers.
  725. //
  726. if ((ContextFrame->ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  727. BdGetDebugContext(TrapFrame, ContextFrame);
  728. }
  729. #endif
  730. return;
  731. }