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.

1305 lines
30 KiB

  1. //++
  2. //
  3. // Module Name:
  4. //
  5. // miscs.s
  6. //
  7. // Abstract:
  8. //
  9. // This module implements machine dependent miscellaneous kernel functions.
  10. // Functions are provided to request a software interrupt, continue thread
  11. // execution, flush TLBs and write buffers, and perform last chance
  12. // exception processing.
  13. //
  14. // Author:
  15. //
  16. // William K. Cheung (wcheung) 3-Nov-1995
  17. //
  18. // Environment:
  19. //
  20. // Kernel mode only.
  21. //
  22. // Revision History:
  23. //
  24. // 7-Jul-1997 bl Updated to EAS2.3
  25. //
  26. // 27-Feb-1996 wc Updated to EAS2.1
  27. //
  28. // 11-Jan-1996 wc Set up register sp to point to the exception frame
  29. // on the stack before calling KiSaveExceptionFrame and
  30. // branching directly to KiExceptionExit.
  31. //
  32. //--
  33. #include "ksia64.h"
  34. #define IPI_FREEZE_SHIFT 2
  35. #if IPI_FREEZE != 1 << IPI_FREEZE_SHIFT
  36. #error IPI_FREEZE_SHIFT incorrect!
  37. #endif
  38. //
  39. // Global symbols
  40. //
  41. PublicFunction(KiContinue)
  42. PublicFunction(KiSaveExceptionFrame)
  43. PublicFunction(KeTestAlertThread)
  44. PublicFunction(KiExceptionExit)
  45. PublicFunction(KiRaiseException)
  46. PublicFunction(KiLoadKernelDebugRegisters)
  47. PublicFunction(KeIsExecutingDpc)
  48. //
  49. //++
  50. //
  51. // NTSTATUS
  52. // NtContinue (
  53. // IN PCONTEXT ContextRecord,
  54. // IN BOOLEAN TestAlert
  55. // )
  56. //
  57. // Routine Description:
  58. //
  59. // This routine is called as a system service to continue execution after
  60. // an exception has occurred. Its functions is to transfer information from
  61. // the specified context record into the trap frame that was built when the
  62. // system service was executed, and then exit the system as if an exception
  63. // had occurred.
  64. //
  65. // Arguments:
  66. //
  67. // ContextRecord (a0) - Supplies a pointer to a context record.
  68. //
  69. // TestAlert (a1) - Supplies a boolean value that specifies whether alert
  70. // should be tested for the previous processor mode.
  71. //
  72. // N.B. Register t0 is assumed to contain the address of a trap frame.
  73. //
  74. // Return Value:
  75. //
  76. // Normally there is no return from this routine. However, if the specified
  77. // context record is misaligned or is not accessible, then the appropriate
  78. // status code is returned.
  79. //
  80. //--
  81. NESTED_ENTRY(NtContinue)
  82. NESTED_SETUP(2,4,3,0)
  83. .fframe ExceptionFrameLength
  84. add sp = -ExceptionFrameLength, sp
  85. PROLOGUE_END
  86. //
  87. // Transfer information from the context record to the exception and trap
  88. // frames.
  89. //
  90. // N.B. Must zero the loadrs bit-field of Context->RsRSC
  91. //
  92. add t1 = TrStIPSR, t0 // -> TrapFrame->StIPSR
  93. mov loc2 = t0
  94. ;;
  95. ld8 loc3 = [t1] // load TrapFrame->StIPSR
  96. mov out0 = a0 // context frame address
  97. ;;
  98. add out1 = STACK_SCRATCH_AREA, sp // -> exception frame
  99. mov out2 = t0 // trap frame address
  100. br.call.sptk.many brp = KiContinue
  101. ;;
  102. //
  103. // If KiContinue() returns success, then exit via the exception exit code.
  104. // Otherwise, return to the system service dispatcher.
  105. //
  106. // Check to determine if alert should be tested for the previous processor
  107. // mode and restore the previous mode in the thread object.
  108. //
  109. // Application that invokes the NtContinue() system service must have
  110. // flushed all stacked registers to the backing store. Sanitize the
  111. // bspstore to be equal to bsp; otherwise, some stacked GRs will not be
  112. // restored from the backing store.
  113. //
  114. add t0 = TrStIPSR, loc2
  115. movl t7 = 1 << PSR_TB | 1 << PSR_DB | 1 << PSR_SS | 1 << PSR_PP
  116. ;;
  117. ld8 t8 = [t0]
  118. cmp.ne pt0 = zero, v0 // if ne, transfer failed.
  119. ;;
  120. (pt0) dep t7 = 1, t7, PSR_LP, 1 // capture psr.lp if failed
  121. ;;
  122. add t2 = TrTrapFrame, loc2
  123. // andcm t8 = t8, t7 // Clear old values
  124. and loc3 = t7, loc3 // capture psr.tb, db, ss, pp
  125. ;;
  126. or t8 = loc3, t8
  127. ;;
  128. st8 [t0] = t8
  129. add t3 = TrRsRSC, loc2
  130. (pt0) br.cond.spnt Nc10 // jump to Nc10 if pt0 is TRUE
  131. ;;
  132. //
  133. // Restore the nonvolatile machine state from the exception frame
  134. // and exit the system via the exception exit code.
  135. //
  136. ld8 t5 = [t2] // get old trap frame address
  137. movl t1 = KiPcr + PcCurrentThread // -> current thread
  138. ;;
  139. ld8 t0 = [t3], TrPreviousMode-TrRsRSC // load TrapFrame->RsRSC
  140. ld8 t4 = [t1] // get current thread address
  141. cmp4.ne pt1 = zero, a1 // if ne, test for alert
  142. ;;
  143. ld4 t6 = [t3], TrRsRSC-TrPreviousMode // get old previous mode
  144. dep t0 = r0, t0, RSC_MBZ1, RSC_LOADRS_LEN // zero preload field
  145. add t7 = ThPreviousMode, t4
  146. ;;
  147. (pt1) ld1 out0 = [t7] // get current previous mode
  148. st8 [t3] = t0 // save TrapFrame->RsRSC
  149. add t8 = ThTrapFrame, t4
  150. ;;
  151. st8 [t8] = t5 // restore old trap frame addr
  152. st1 [t7] = t6 // restore old previous mode
  153. (pt1) br.call.spnt.many brp = KeTestAlertThread
  154. ;;
  155. //
  156. // sp -> stack scratch area/FP save area/exception frame/trap frame
  157. //
  158. // Set up for branch to KiExceptionExit
  159. //
  160. // s0 = trap frame
  161. // s1 = exception frame
  162. //
  163. // N.B. predicate register alias pUstk & pKstk must be the same as trap.s
  164. // and they must be set up correctly upon entry into KiExceptionExit.
  165. //
  166. // N.B. The exception exit code will restore the exception frame & trap frame
  167. // and then rfi to user code. pUstk is set to 1 while pKstk is set to 0.
  168. //
  169. pUstk = ps3
  170. pKstk = ps4
  171. //
  172. // Interrupts must be disabled before calling KiExceptionExit
  173. // because the unwind code cannot unwind from that point.
  174. //
  175. FAST_DISABLE_INTERRUPTS
  176. cmp.eq pUstk, pKstk = zero, zero
  177. add s1 = STACK_SCRATCH_AREA, sp
  178. mov s0 = loc2
  179. br KiExceptionExit
  180. Nc10:
  181. .restore
  182. add sp = ExceptionFrameLength, sp
  183. NESTED_RETURN
  184. NESTED_EXIT(NtContinue)
  185. //++
  186. //
  187. // NTSTATUS
  188. // NtRaiseException (
  189. // IN PEXCEPTION_RECORD ExceptionRecord,
  190. // IN PCONTEXT ContextRecord,
  191. // IN BOOLEAN FirstChance
  192. // )
  193. //
  194. // Routine Description:
  195. //
  196. // This routine is called as a system service to raise an exception.
  197. // The exception can be raised as a first or second chance exception.
  198. //
  199. // Arguments:
  200. //
  201. // ExceptionRecord (a0) - Supplies a pointer to an exception record.
  202. //
  203. // ContextRecord (a1) - Supplies a pointer to a context record.
  204. //
  205. // FirstChance (a2) - Supplies a boolean value that determines whether
  206. // this is the first (TRUE) or second (FALSE) chance for dispatching
  207. // the exception.
  208. //
  209. // N.B. Register t0 is assumed to contain the address of a trap frame.
  210. //
  211. // Return Value:
  212. //
  213. // Normally there is no return from this routine. However, if the specified
  214. // context record or exception record is misaligned or is not accessible,
  215. // then the appropriate status code is returned.
  216. //
  217. //--
  218. NESTED_ENTRY(NtRaiseException)
  219. NESTED_SETUP(3,3,5,0)
  220. .fframe ExceptionFrameLength
  221. add sp = -ExceptionFrameLength, sp
  222. ;;
  223. PROLOGUE_END
  224. //
  225. // Pop this trap frame off the thread list.
  226. //
  227. add t2 = TrTrapFrame, t0
  228. movl t1 = KiPcr + PcCurrentThread
  229. ;;
  230. ld8 t1 = [t1]; // Get current thread.
  231. ld8 t2 = [t2]; // Load previous trap frame
  232. ;;
  233. add t1 = ThTrapFrame, t1
  234. //
  235. // Save nonvolatile states.
  236. //
  237. add out0 = STACK_SCRATCH_AREA, sp
  238. mov loc2 = t0 // save pointer to trap frame
  239. ;;
  240. st8 [t1] = t2
  241. br.call.sptk brp = KiSaveExceptionFrame
  242. //
  243. // Call the raise exception kernel routine wich will marshall the argments
  244. // and then call the exception dispatcher.
  245. //
  246. add out2 = STACK_SCRATCH_AREA, sp // -> exception frame
  247. mov out1 = a1
  248. mov out0 = a0
  249. add out4 = zero, a2
  250. mov out3 = t0
  251. br.call.sptk.many brp = KiRaiseException
  252. //
  253. // If the raise exception routine returns success, then exit via the exception
  254. // exit code. Otherwise, return to the system service dispatcher.
  255. //
  256. // N.B. The exception exit code will restore the exception frame & trap frame
  257. // and then rfi to user code.
  258. //
  259. // Set up for branch to KiExceptionExit
  260. //
  261. // s0 = trap frame
  262. // s1 = exception frame
  263. //
  264. pUstk = ps3
  265. pKstk = ps4
  266. cmp4.ne p0, pt1 = zero, v0 // if ne, dispatch failed.
  267. ;;
  268. //
  269. // Interrupts must be disabled before calling KiExceptionExit
  270. // because the unwind code cannot unwind from that point.
  271. //
  272. (pt1) FAST_DISABLE_INTERRUPTS
  273. (pt1) mov s0 = loc2 // copy trap frame pointer
  274. (pt1) add s1 = STACK_SCRATCH_AREA, sp
  275. (pt1) cmp.eq pUstk, pKstk = zero, zero
  276. (pt1) br.cond.sptk.many KiExceptionExit
  277. .restore
  278. add sp = ExceptionFrameLength, sp
  279. NESTED_RETURN
  280. NESTED_EXIT(NtRaiseException)
  281. //++
  282. //
  283. // VOID
  284. // KeFillLargeEntryTb (
  285. // IN HARDWARE_PTE Pte[],
  286. // IN PVOID Virtual,
  287. // IN ULONG PageSize
  288. // )
  289. //
  290. // Routine Description:
  291. //
  292. // This function fills a large translation buffer entry.
  293. //
  294. // N.B. It is assumed that the large entry is not in the TB and therefore
  295. // the TB is not probed.
  296. //
  297. // Arguments:
  298. //
  299. // Pte (a0) - Supplies a pointer to the page table entries that are to be
  300. // written into the TB.
  301. //
  302. // Virtual (a1) - Supplies the virtual address of the entry that is to
  303. // be filled in the translation buffer.
  304. //
  305. // PageSize (a2) - Supplies the size of the large page table entry.
  306. //
  307. // Return Value:
  308. //
  309. // None.
  310. //
  311. //--
  312. LEAF_ENTRY(KeFillLargeEntryTb)
  313. rPte = t0
  314. rScnd = t1
  315. ridtr = t2
  316. rid = t3
  317. rDtr = t4
  318. rTb = t6
  319. rTbPFN = t7
  320. rpAttr = t8
  321. rAttrOffset = t9
  322. shr.u rScnd = a2, 6 // mask off page size fields
  323. ;;
  324. shl rScnd = rScnd, 6 //
  325. ;;
  326. and rScnd = a1, rScnd // examine the virtual address bit
  327. ;;
  328. cmp.eq pt0, pt1 = r0, rScnd
  329. shl ridtr = a2, PS_SHIFT
  330. mov rDtr = DTR_VIDEO_INDEX
  331. ;;
  332. rsm 1 << PSR_I // turn off interrupts
  333. (pt0) add a0 = (1 << PTE_SHIFT), a0
  334. ;;
  335. ld8 rPte = [a0] // load PTE
  336. rsm 1 << PSR_IC // interrupt is off, now reset PSR.ic
  337. ;;
  338. srlz.d // serialize
  339. mov cr.itir = ridtr // idtr for insertion
  340. mov cr.ifa = a1 // ifa for insertion
  341. ;;
  342. itr.d dtr[rDtr] = rPte
  343. ssm 1 << PSR_IC // set PSR.ic bit again
  344. ;;
  345. srlz.i // I serialize
  346. ssm 1 << PSR_I
  347. LEAF_RETURN
  348. LEAF_EXIT(KeFillLargeEntryTb) // return
  349. //++
  350. //
  351. // VOID
  352. // KeFillFixedEntryTb (
  353. // IN HARDWARE_PTE Pte[],
  354. // IN PVOID Virtual,
  355. // IN ULONG PageSize,
  356. // IN ULONG Index
  357. // )
  358. //
  359. // Routine Description:
  360. //
  361. // This function fills a fixed translation buffer entry.
  362. //
  363. // Arguments:
  364. //
  365. // Pte (a0) - Supplies a pointer to the page table entries that are to be
  366. // written into the TB.
  367. //
  368. // Virtual (a1) - Supplies the virtual address of the entry that is to
  369. // be filled in the translation buffer.
  370. //
  371. // Index (a2) - Supplies the index where the TB entry is to be written.
  372. //
  373. // Return Value:
  374. //
  375. // None.
  376. //
  377. // Comments:
  378. //
  379. //
  380. //
  381. //--
  382. LEAF_ENTRY(KeFillFixedEntryTb)
  383. rPte = t0
  384. rScnd = t1
  385. ridtr = t2
  386. rid = t3
  387. rIndex = t4
  388. rTb = t6
  389. rTbPFN = t7
  390. rpAttr = t8
  391. rAttrOffset = t9
  392. rsm 1 << PSR_I // reset PSR.i
  393. ld8 rPte = [a0] // load PTE
  394. shl ridtr = a2, PS_SHIFT
  395. ;;
  396. rsm 1 << PSR_IC // interrupt is off, now reset PSR.ic
  397. tbit.z pt0, pt1 = a3, 31 // check the sign bit
  398. // if 1 ITR, otherwise DTR
  399. ;;
  400. srlz.d // serialize
  401. and rIndex = 0xf, a3
  402. ;;
  403. mov cr.itir = ridtr // idtr for insertion
  404. mov cr.ifa = a1 // ifa for insertion
  405. ;;
  406. (pt0) itr.d dtr[rIndex] = rPte // insert into DTR
  407. (pt1) itr.i itr[rIndex] = rPte // insert into ITR
  408. ssm 1 << PSR_IC // set PSR.ic bit again
  409. ;;
  410. srlz.i // I serialize
  411. #if DBG
  412. mov t10 = PbProcessorState+KpsSpecialRegisters+KsTrD0
  413. movl t13 = KiPcr + PcPrcb
  414. ;;
  415. ld8 t13 = [t13]
  416. mov t14 = PbProcessorState+KpsSpecialRegisters+KsTrI0
  417. ;;
  418. add t10 = t10, t13
  419. add t14 = t14, t13
  420. ;;
  421. (pt0) shladd t15 = rIndex, 3, t10
  422. (pt1) shladd t15 = rIndex, 3, t14
  423. ;;
  424. (pt0) st8 [t15] = rPte
  425. (pt1) st8 [t15] = rPte
  426. ;;
  427. #endif
  428. ssm 1 << PSR_I
  429. LEAF_RETURN
  430. LEAF_EXIT(KeFillFixedEntryTb)
  431. //++
  432. //
  433. // VOID
  434. // KeFillFixedLargeEntryTb (
  435. // IN HARDWARE_PTE Pte[],
  436. // IN PVOID Virtual,
  437. // IN ULONG PageSize,
  438. // IN ULONG Index
  439. // )
  440. //
  441. // Routine Description:
  442. //
  443. // This function fills a fixed translation buffer entry with a large page
  444. // size.
  445. //
  446. // Arguments:
  447. //
  448. // Pte (a0) - Supplies a pointer to the page table entries that are to be
  449. // written into the TB.
  450. //
  451. // Virtual (a1) - Supplies the virtual address of the entry that is to
  452. // be filled in the translation buffer.
  453. //
  454. // PageSize (a2) - Supplies the size of the large page table entry.
  455. //
  456. // Index (a3) - Supplies the index where the TB entry is to be written.
  457. //
  458. // Return Value:
  459. //
  460. // None.
  461. //
  462. // Comments:
  463. //
  464. // Yet to be implemented.
  465. //
  466. //--
  467. LEAF_ENTRY(KeFillFixedLargeEntryTb)
  468. rPte = t0
  469. rScnd = t1
  470. ridtr = t2
  471. rid = t3
  472. rIndex = t4
  473. rTb = t6
  474. rTbPFN = t7
  475. rpAttr = t8
  476. rAttrOffset = t9
  477. rsm 1 << PSR_I // reset PSR.i
  478. ld8 rPte = [a0] // load PTE
  479. shl ridtr = a2, PS_SHIFT
  480. ;;
  481. rsm 1 << PSR_IC // interrupt is off, now reset PSR.ic
  482. and rIndex = 0xf, a3 // set the DTR index
  483. tbit.z pt0, pt1 = a3, 31 // check the sign bit
  484. ;;
  485. srlz.d // serialize
  486. mov cr.itir = ridtr // idtr for insertion
  487. mov cr.ifa = a1 // ifa for insertion
  488. ;;
  489. (pt0) itr.d dtr[rIndex] = rPte // insert into DTR
  490. (pt1) itr.i itr[rIndex] = rPte // insert into ITR
  491. ssm 1 << PSR_IC // set PSR.ic bit again
  492. ;;
  493. srlz.i // I serialize
  494. ssm 1 << PSR_I
  495. LEAF_RETURN
  496. LEAF_EXIT(KeFillFixedLargeEntryTb) // return
  497. //++
  498. //
  499. // VOID
  500. // KeFillInstEntryTb (
  501. // IN HARDWARE_PTE Pte[],
  502. // IN PVOID Virtual,
  503. // )
  504. //
  505. // Routine Description:
  506. //
  507. // This function fills a large translation buffer entry.
  508. //
  509. // N.B. It is assumed that the large entry is not in the TB and therefore
  510. // the TB is not probed.
  511. //
  512. // Arguments:
  513. //
  514. // Pte (a0) - Supplies a page table entry that is to be
  515. // written into the Inst TB.
  516. //
  517. // Virtual (a1) - Supplies the virtual address of the entry that is to
  518. // be filled in the translation buffer.
  519. //
  520. // Return Value:
  521. //
  522. // None.
  523. //
  524. //--
  525. LEAF_ENTRY(KeFillInstEntryTb)
  526. riitr = t2
  527. rid = t3
  528. rsm 1 << PSR_I // reset PSR.i
  529. ;;
  530. rsm 1 << PSR_IC // interrupt is off, now reset PSR.ic
  531. mov riitr = PAGE_SIZE << PS_LEN
  532. ;;
  533. srlz.d // serialize
  534. mov cr.ifa = a1 // set va to install
  535. mov cr.itir = riitr // iitr for insertion
  536. ;;
  537. itc.i a0
  538. ;;
  539. ssm 1 << PSR_IC // set PSR.ic bit again
  540. ;;
  541. srlz.i // I serialize
  542. ssm 1 << PSR_I
  543. LEAF_RETURN
  544. LEAF_EXIT(KeFillInstEntryTb) // return
  545. //++
  546. //
  547. // VOID
  548. // KeBreakinBreakpoint
  549. // VOID
  550. // )
  551. //
  552. // Routine Description:
  553. //
  554. // This function causes a BREAKIN breakpoint.
  555. //
  556. // Arguments:
  557. //
  558. // None.
  559. //
  560. // Return Value:
  561. //
  562. // None.
  563. //
  564. //--
  565. LEAF_ENTRY(KeBreakinBreakpoint)
  566. //
  567. // Flush the RSE or the kernel debugger is unable to do a stack unwind
  568. //
  569. flushrs
  570. ;;
  571. break.i BREAKPOINT_BREAKIN
  572. LEAF_RETURN
  573. LEAF_EXIT(KeBreakinBreakpoint)
  574. #ifdef WX86
  575. //++
  576. //
  577. // VOID
  578. // KiIA32RegistersInit
  579. // VOID
  580. // )
  581. //
  582. // Routine Description:
  583. //
  584. // This function to Initialize per processor IA32 related registers
  585. // These registers do not saved/restored on context switch time
  586. //
  587. // Arguments:
  588. //
  589. // None.
  590. //
  591. // Return Value:
  592. //
  593. // None.
  594. //
  595. //--
  596. LEAF_ENTRY(KiIA32RegistersInit)
  597. mov t0 = TeGdtDescriptor
  598. mov iA32iobase = 0
  599. ;;
  600. mov iA32index = t0
  601. LEAF_RETURN
  602. LEAF_EXIT(KiIA32RegistersInit)
  603. #endif // WX86
  604. //++
  605. //
  606. // PKTHREAD
  607. // KeGetCurrentThread (VOID)
  608. //
  609. // Routine Description:
  610. //
  611. // Arguments:
  612. //
  613. // None.
  614. //
  615. // Return Value:
  616. //
  617. // Returns a pointer to the executing thread object.
  618. //
  619. //--
  620. LEAF_ENTRY(KeGetCurrentThread)
  621. movl v0 = KiPcr + PcCurrentThread // -> current thread
  622. ;;
  623. ld8 v0 = [v0]
  624. br.ret.sptk brp
  625. LEAF_EXIT(KeGetCurrentThread)
  626. //++
  627. //
  628. // BOOLEAN
  629. // KeIsExecutingDpc (VOID)
  630. //
  631. // Routine Description:
  632. //
  633. // Arguments:
  634. //
  635. // None.
  636. //
  637. // Return Value:
  638. //
  639. // Return a value which indicates if we are currently in a DPC.
  640. //
  641. //--
  642. LEAF_ENTRY(KeIsExecutingDpc)
  643. rsm 1 << PSR_I // disable interrupt
  644. movl v0 = KiPcr + PcPrcb
  645. ;;
  646. ld8 v0 = [v0]
  647. ;;
  648. add v0 = PbDpcRoutineActive, v0
  649. ;;
  650. ld8 t0 = [v0]
  651. ssm 1 << PSR_I // enable interrupt
  652. ;;
  653. cmp.eq pt1 = t0, zero
  654. mov v0 = 1
  655. ;;
  656. (pt1) mov v0 = 0
  657. br.ret.sptk brp
  658. LEAF_EXIT(KeIsExecutingDpc)
  659. //++
  660. //
  661. // Routine Description:
  662. //
  663. // This routine saves the thread's current non-volatile NPX state,
  664. // and sets a new initial floating point state for the caller.
  665. //
  666. // This is intended for use by kernel-mode code that needs to use
  667. // the floating point registers. Must be paired with
  668. // KeRestoreFloatingPointState
  669. //
  670. // Arguments:
  671. //
  672. // a0 - Supplies pointer to KFLOATING_SAVE structure
  673. //
  674. // Return Value:
  675. //
  676. // None.
  677. //
  678. //--
  679. LEAF_ENTRY(KeSaveFloatingPointState)
  680. mov v0 = zero
  681. LEAF_RETURN
  682. LEAF_EXIT(KeSaveFloatingPointState)
  683. //++
  684. //
  685. // Routine Description:
  686. //
  687. // This routine restores the thread's current non-volatile NPX state,
  688. // to the passed in state.
  689. //
  690. // This is intended for use by kernel-mode code that needs to use
  691. // the floating point registers. Must be paired with
  692. // KeSaveFloatingPointState
  693. //
  694. // Arguments:
  695. //
  696. // a0 - Supplies pointer to KFLOATING_SAVE structure
  697. //
  698. // Return Value:
  699. //
  700. // None.
  701. //
  702. //--
  703. LEAF_ENTRY(KeRestoreFloatingPointState)
  704. mov v0 = zero
  705. LEAF_RETURN
  706. LEAF_EXIT(KeRestoreFloatingPointState)
  707. //++
  708. //
  709. // Routine Description:
  710. //
  711. // This routine flush all the dirty registers to the backing store
  712. // and invalidate them.
  713. //
  714. // Arguments:
  715. //
  716. // None.
  717. //
  718. // Return Value:
  719. //
  720. // None.
  721. //
  722. //--
  723. LEAF_ENTRY(KiFlushRse)
  724. flushrs
  725. mov t1 = ar.rsc
  726. mov t0 = RSC_KERNEL_DISABLED
  727. ;;
  728. mov ar.rsc = t0
  729. ;;
  730. loadrs
  731. ;;
  732. mov ar.rsc = t1
  733. ;;
  734. br.ret.sptk brp
  735. LEAF_EXIT(KiFlushRse)
  736. #if 0
  737. //++
  738. //
  739. // Routine Description:
  740. //
  741. // This routine invalidate all the physical stacked registers.
  742. //
  743. // Arguments:
  744. //
  745. // None.
  746. //
  747. // Return Value:
  748. //
  749. // None.
  750. //
  751. //--
  752. LEAF_ENTRY(KiInvalidateStackedRegisters)
  753. mov t1 = ar.rsc
  754. mov t0 = RSC_KERNEL_DISABLED
  755. ;;
  756. mov ar.rsc = t0
  757. ;;
  758. loadrs
  759. ;;
  760. mov ar.rsc = t1
  761. ;;
  762. br.ret.sptk brp
  763. LEAF_EXIT(KiInvalidateStackedRegisters)
  764. #endif // 0
  765. //++
  766. //
  767. // VOID
  768. // KeSetLowPsrBit (
  769. // UCHAR BitPosition,
  770. // BOOLEAN Value
  771. // )
  772. //
  773. // Routine Description:
  774. //
  775. // This routine set one of the low psr bits to the specified value.
  776. //
  777. // Arguments:
  778. //
  779. // a0 - bit position
  780. // a1 - 1 or 0
  781. //
  782. // Return Value:
  783. //
  784. // None.
  785. //
  786. //--
  787. LEAF_ENTRY(KeSetLowPsrBit)
  788. mov t1 = psr
  789. mov t2 = 1
  790. cmp.ne pt1, pt0 = r0, a1
  791. ;;
  792. shl t2 = t2, a0
  793. ;;
  794. (pt1) or t3 = t1, t2
  795. (pt0) andcm t3 = t1, t2
  796. ;;
  797. mov psr.l = t3
  798. ;;
  799. srlz.i
  800. br.ret.sptk brp
  801. LEAF_EXIT(KeSetLowPsrBit)
  802. //++
  803. //
  804. // PVOID
  805. // KiGetPhysicalAddress(
  806. // PVOID Virtual
  807. // )
  808. //
  809. // Routine Description:
  810. //
  811. // This routine translates to physical address uing TPA instruction.
  812. //
  813. // Arguments:
  814. //
  815. // a0 - virtual address to be translated to physical address.
  816. //
  817. // Return Value:
  818. //
  819. // physical address
  820. //
  821. //--
  822. LEAF_ENTRY(KiGetPhysicalAddress)
  823. tpa r8 = a0
  824. LEAF_RETURN
  825. LEAF_EXIT(KiGetPhysicalAddress)
  826. //++
  827. //
  828. // VOID
  829. // KiSetRegionRegister(
  830. // PVOID Region,
  831. // ULONGLONG Contents
  832. // )
  833. //
  834. // Routine Description:
  835. //
  836. // This routine sets the value of a region register.
  837. //
  838. // Arguments:
  839. //
  840. // a0 - Supplies the region register #
  841. //
  842. // a1 - Supplies the value to be stored in the specified region register
  843. //
  844. // Return Value:
  845. //
  846. // None.
  847. //
  848. //--
  849. LEAF_ENTRY(KiSetRegionRegister)
  850. mov rr[a0] = a1
  851. ;;
  852. srlz.i
  853. LEAF_RETURN
  854. LEAF_EXIT(KiSetRegionId)
  855. //++
  856. //
  857. // VOID
  858. // KiSaveProcessorControlState(
  859. // PKPROCESSOR_STATE ProcessorState
  860. // )
  861. //
  862. // Routine Description:
  863. //
  864. // This routine captures some of the special registers into the supplied
  865. // ProcessorState.
  866. //
  867. // It is called indirectly by the debugger through KeFreezeTargetExecution.
  868. // It is also called during bugcheck processing.
  869. //
  870. // Arguments:
  871. //
  872. // a0 - Pointer to ProcessorState in Prcb.
  873. //
  874. // Return Value:
  875. //
  876. // None.
  877. //
  878. //--
  879. LEAF_ENTRY(KiSaveProcessorControlState)
  880. //
  881. // save region registers
  882. //
  883. add t2 = KpsSpecialRegisters+KsRr0, a0
  884. dep.z t0 = 0, RR_INDEX, RR_INDEX_LEN
  885. ;;
  886. mov t1 = rr[t0]
  887. dep.z t3 = 1, RR_INDEX, RR_INDEX_LEN
  888. ;;
  889. mov t4 = rr[t3]
  890. st8 [t2] = t1, KsRr1-KsRr0
  891. dep.z t0 = 2, RR_INDEX, RR_INDEX_LEN
  892. ;;
  893. mov t1 = rr[t0]
  894. st8 [t2] = t4, KsRr2-KsRr1
  895. dep.z t3 = 3, RR_INDEX, RR_INDEX_LEN
  896. ;;
  897. mov t4 = rr[t3]
  898. st8 [t2] = t1, KsRr3-KsRr2
  899. dep.z t0 = 4, RR_INDEX, RR_INDEX_LEN
  900. ;;
  901. mov t1 = rr[t0]
  902. st8 [t2] = t4, KsRr4-KsRr3
  903. dep.z t3 = 5, RR_INDEX, RR_INDEX_LEN
  904. ;;
  905. mov t4 = rr[t3]
  906. st8 [t2] = t1, KsRr5-KsRr4
  907. dep.z t0 = 6, RR_INDEX, RR_INDEX_LEN
  908. ;;
  909. mov t1 = rr[t0]
  910. st8 [t2] = t4, KsRr6-KsRr5
  911. dep.z t3 = 7, RR_INDEX, RR_INDEX_LEN
  912. ;;
  913. mov t4 = rr[t3]
  914. st8 [t2] = t1, KsRr7-KsRr6
  915. ;;
  916. st8 [t2] = t4
  917. //
  918. // save ITC, ITM, IVA, PTA and TPR
  919. //
  920. mov t0 = ar.itc
  921. mov t1 = cr.itm
  922. add t3 = KpsSpecialRegisters+KsApITC, a0
  923. add t4 = KpsSpecialRegisters+KsApITM, a0
  924. ;;
  925. mov t5 = cr.iva
  926. mov t6 = cr.pta
  927. st8 [t3] = t0, KsApIVA-KsApITC
  928. st8 [t4] = t1, KsApPTA-KsApITM
  929. ;;
  930. mov t0 = cr.tpr
  931. mov t1 = ar.k0
  932. st8 [t3] = t5, KsSaTPR-KsApIVA
  933. st8 [t4] = t6, KsApKR0-KsApPTA
  934. ;;
  935. mov t5 = ar.k1
  936. mov t6 = ar.k2
  937. st8 [t3] = t0, KsApKR1-KsSaTPR
  938. st8 [t4] = t1, KsApKR2-KsApKR0
  939. ;;
  940. mov t0 = ar.k3
  941. mov t1 = ar.k4
  942. st8 [t3] = t5, KsApKR3-KsApKR1
  943. st8 [t4] = t6, KsApKR4-KsApKR2
  944. ;;
  945. mov t5 = ar.k5
  946. mov t6 = ar.k6
  947. st8 [t3] = t0, KsApKR5-KsApKR3
  948. st8 [t4] = t1, KsApKR6-KsApKR4
  949. ;;
  950. mov t0 = ar.k7
  951. mov t1 = cr.lid
  952. st8 [t3] = t5, KsApKR7-KsApKR5
  953. st8 [t4] = t6, KsSaLID-KsApKR6
  954. ;;
  955. mov t5 = cr.irr0
  956. mov t6 = cr.irr1
  957. st8 [t3] = t0, KsSaIRR0-KsApKR7
  958. st8 [t4] = t1, KsSaIRR1-KsSaLID
  959. ;;
  960. mov t0 = cr.irr2
  961. mov t1 = cr.irr3
  962. st8 [t3] = t5, KsSaIRR2-KsSaIRR0
  963. st8 [t4] = t6, KsSaIRR3-KsSaIRR1
  964. ;;
  965. mov t5 = cr.itv
  966. mov t6 = cr.pmv
  967. st8 [t3] = t0, KsSaITV-KsSaIRR2
  968. st8 [t4] = t1, KsSaPMV-KsSaIRR3
  969. ;;
  970. mov t0 = cr.cmcv
  971. mov t1 = cr.lrr0
  972. st8 [t3] = t5, KsSaCMCV-KsSaITV
  973. st8 [t4] = t6, KsSaLRR0-KsSaPMV
  974. ;;
  975. mov t5 = cr.lrr1
  976. mov t6 = cr.gpta
  977. st8 [t3] = t0, KsSaLRR1-KsSaCMCV
  978. st8 [t4] = t1, KsApGPTA-KsSaLRR0
  979. mov t7 = 0
  980. mov t8 = 1
  981. ;;
  982. mov t0 = cpuid[t7]
  983. mov t1 = cpuid[t8]
  984. st8 [t3] = t5
  985. st8 [t4] = t6
  986. mov t9 = 2
  987. mov t10 = 3
  988. add t3 = KpsSpecialRegisters+KsApCPUID0, a0
  989. add t4 = KpsSpecialRegisters+KsApCPUID1, a0
  990. ;;
  991. mov t5 = cpuid[t9]
  992. mov t6 = cpuid[t10]
  993. st8 [t3] = t0, KsApCPUID2-KsApCPUID0
  994. st8 [t4] = t1, KsApCPUID3-KsApCPUID1
  995. mov t7 = 4
  996. mov t8 = 652
  997. ;;
  998. mov t0 = cpuid[t7]
  999. st8 [t3] = t5, KsApCPUID4-KsApCPUID2
  1000. st8 [t4] = t6
  1001. ;;
  1002. st8 [t3] = t0
  1003. LEAF_RETURN
  1004. LEAF_EXIT(KiSaveProcessorControlState)
  1005. NESTED_ENTRY(KiRestoreProcessorControlState)
  1006. NESTED_SETUP(0,2,0,0)
  1007. ;;
  1008. br.call.spnt brp = KiLoadKernelDebugRegisters
  1009. ;;
  1010. NESTED_RETURN
  1011. NESTED_EXIT(KiRestoreProcessorControlState)
  1012. PublicFunction(KiSaveExceptionFrame)
  1013. PublicFunction(KiRestoreExceptionFrame)
  1014. PublicFunction(KiIpiProcessRequests)
  1015. PublicFunction(KiFreezeTargetExecution)
  1016. NESTED_ENTRY(KeIpiInterrupt)
  1017. NESTED_SETUP(1, 3, 1, 0)
  1018. PROLOGUE_END
  1019. ;;
  1020. //
  1021. // Process all requests except freeze requests.
  1022. //
  1023. mov out0 = a0 // -> trap frame
  1024. mov loc2 = gp
  1025. br.call.sptk brp = KiIpiProcessRequests
  1026. ;;
  1027. tbit.nz pt1 = v0, IPI_FREEZE_SHIFT
  1028. mov gp = loc2
  1029. mov out0 = a0 // -> trap frame
  1030. (pt1) br.call.dpnt brp = KiFreezeCurrentProcessor
  1031. ;;
  1032. NESTED_RETURN
  1033. NESTED_EXIT(KeIpiInterrupt)
  1034. NESTED_ENTRY(KiFreezeCurrentProcessor)
  1035. NESTED_SETUP(1, 2, 2, 0)
  1036. .fframe ExceptionFrameLength
  1037. add sp = -ExceptionFrameLength, sp
  1038. ;;
  1039. PROLOGUE_END
  1040. add out0 = STACK_SCRATCH_AREA, sp // -> exception frame
  1041. br.call.sptk brp = KiSaveExceptionFrame
  1042. ;;
  1043. add out1 = STACK_SCRATCH_AREA, sp // -> exception frame
  1044. mov out0 = a0 // -> trap frame
  1045. br.call.sptk brp = KiFreezeTargetExecution
  1046. ;;
  1047. add out0 = STACK_SCRATCH_AREA, sp // -> exception frame
  1048. br.call.sptk brp = KiRestoreExceptionFrame
  1049. ;;
  1050. add sp = ExceptionFrameLength, sp
  1051. NESTED_RETURN
  1052. NESTED_EXIT(KiFreezeCurrentProcessor)
  1053. LEAF_ENTRY(KiReadMsr)
  1054. mov v0 = msr[a0]
  1055. LEAF_RETURN
  1056. LEAF_EXIT(KiReadMsr)
  1057. LEAF_ENTRY(KiWriteMsr)
  1058. mov msr[a0] = a1
  1059. LEAF_RETURN
  1060. LEAF_EXIT(KiWriteMsr)
  1061. LEAF_ENTRY(KeYieldProcessor)
  1062. YIELD
  1063. LEAF_RETURN
  1064. LEAF_EXIT(KeYieldProcessor)