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.

6296 lines
192 KiB

  1. //++
  2. //
  3. // Module Name:
  4. // trap.s
  5. //
  6. // Abstract:
  7. // Low level interruption handlers
  8. //
  9. // Author:
  10. // Bernard Lint 12-Jun-1995
  11. //
  12. // Environment:
  13. // Kernel mode only
  14. //
  15. // Revision History:
  16. //
  17. //
  18. // Open Design Issues:
  19. //
  20. //--
  21. #if 1 // interruption logging is enabled in checked and free builds
  22. #define INTERRUPTION_LOGGING 1
  23. #endif // DBG
  24. #include "ksia64.h"
  25. .file "trap.s"
  26. .explicit
  27. //
  28. // Globals imported:
  29. //
  30. PublicFunction(KeBugCheckEx)
  31. PublicFunction(KiApcInterrupt)
  32. PublicFunction(KiCheckForSoftwareInterrupt)
  33. PublicFunction(KiDispatchException)
  34. PublicFunction(KiExternalInterruptHandler)
  35. PublicFunction(KiFloatTrap)
  36. PublicFunction(KiFloatFault)
  37. PublicFunction(KiGeneralExceptions)
  38. PublicFunction(KiUnimplementedAddressTrap)
  39. PublicFunction(KiNatExceptions)
  40. PublicFunction(KiMemoryFault)
  41. PublicFunction(KiOtherBreakException)
  42. PublicFunction(KiPanicHandler)
  43. PublicFunction(KiSingleStep)
  44. PublicFunction(KiUnalignedFault)
  45. PublicFunction(PsConvertToGuiThread)
  46. PublicFunction(ExpInterlockedPopEntrySListFault)
  47. PublicFunction(KiDebugFault)
  48. PublicFunction(KeSetLowPsrBit)
  49. PublicFunction(KiTestGdiBatchCount)
  50. PublicFunction(KeCopySafe)
  51. PublicFunction(KiIA32ExceptionVectorHandler)
  52. PublicFunction(KiIA32InterruptionVectorHandler)
  53. PublicFunction(KiIA32InterceptionVectorHandler)
  54. .global KiSystemServiceHandler
  55. .global KeServiceDescriptorTableShadow
  56. .global KeGdiFlushUserBatch
  57. .global KdDebuggerEnabled
  58. .global MiDefaultPpe
  59. // For Conditional Interrupt Logging
  60. #define UserSystemcallBit 61
  61. #define ExternalInterruptBit 62
  62. .global KiVectorLogMask
  63. //
  64. // Register aliases used throughout the entire module
  65. //
  66. //
  67. // Banked general registers
  68. //
  69. // h16-h23 can only be used when psr.ic=1.
  70. //
  71. // h24-h31 can only be used when psr.ic=0 (these are reserved for tlb
  72. // and pal/machine check handlers when psr.ic=1).
  73. //
  74. //
  75. // Shown below are aliases of bank 0 registers used in the low level handlers
  76. // by macros ALLOCATE_TRAP_FRAME, SAVE_INTERRUPTION_RESOURCES, and
  77. // RETURN_FROM_INTERRUPTION. When the code in the macros are changes, these
  78. // register aliases must be reviewed.
  79. //
  80. rHIPSR = h16
  81. rHpT2 = h16
  82. rHIIPA = h17
  83. rHRSC = h17
  84. rHDfhPFS = h17 // used to preserve pfs in KiDisabledFpRegisterVector
  85. rHIIP = h18
  86. rHFPSR = h18
  87. rHOldPreds = h19
  88. rHBrp = h19
  89. rHRNAT = h19
  90. rHIFS = h20
  91. rHPFS = h20
  92. rHBSP = h20
  93. rHISR = h21
  94. rHUNAT = h21
  95. rHBSPSTORE = h21
  96. rHpT3 = h21
  97. rHSp = h22
  98. rHDfhBrp = h22 // used to preserve brp in KiDisabledFpRegisterVector
  99. rHpT4 = h22
  100. rHpT1 = h23
  101. rTH3 = h24
  102. rHHandler = h25
  103. rTH1 = h26
  104. rTH2 = h27
  105. rHIIM = h28
  106. rHIFA = h28
  107. rHEPCVa = h29
  108. rHEPCVa2 = h30
  109. rPanicCode = h30
  110. rTH4 = h31
  111. //
  112. // General registers used through out module
  113. //
  114. pApc = ps0 // User Apc Pending
  115. pUser = ps1 // mode on entry was user
  116. pKrnl = ps2 // mode on entry was kernel
  117. pUstk = ps3
  118. pKstk = ps4
  119. pEM = ps5 // EM ISA on kernel entry
  120. pIA = ps6 // X86 ISA on kernel entry
  121. pKDbg = ps7 // Kernel debug Active
  122. pUDbg = ps8 // Kernel debug Active
  123. //
  124. // Kernel registers used through out module
  125. //
  126. rkHandler = k6 // specific exception handler
  127. //
  128. // Macro definitions for this module only
  129. //
  130. //
  131. // Define vector/exception entry/exit macros.
  132. // N.B. All HANDLER_ENTRY functions go into .nsc section with
  133. // KiNormalSystemCall being the first.
  134. //
  135. #define HANDLER_ENTRY(Name) \
  136. .##global Name; \
  137. .##proc Name; \
  138. Name::
  139. #define HANDLER_ENTRY_EX(Name, Handler) \
  140. .##global Name; \
  141. .##proc Name; \
  142. .##type Handler, @function; \
  143. .##personality Handler; \
  144. Name::
  145. #define VECTOR_ENTRY(Offset, Name, Extra0) \
  146. .##org Offset; \
  147. .##global Name; \
  148. .##proc Name; \
  149. Name::
  150. #define VECTOR_EXIT(Name) \
  151. .##endp Name
  152. #define HANDLER_EXIT(Name) \
  153. .##endp Name
  154. //++
  155. // Routine:
  156. //
  157. // IO_END_OF_INTERRUPT(rVector,rT1,rT2,pEOI)
  158. //
  159. // Routine Description:
  160. //
  161. // HalEOITable Entry corresponding to the vectorNo is tested.
  162. // If the entry is nonzero, then vectorNo is stored to the location
  163. // specified in the entry. If the entry is zero, return.
  164. //
  165. // Arguements:
  166. //
  167. //
  168. // Notes:
  169. //
  170. // MS preprocessor requires /* */ style comments
  171. //
  172. //--
  173. #define IO_END_OF_INTERRUPT(rVector,rT1,rT2,pEOI) ;\
  174. movl rT1 = KiPcr+PcEOITable ;\
  175. ;; ;\
  176. ld8 rT1 = [rT1] ;\
  177. ;; ;\
  178. shladd rT2 = rVector,3,rT1 ;\
  179. ;; ;\
  180. ld8 rT1 = [rT2] ;\
  181. ;; ;\
  182. cmp.ne pEOI = zero, rT1 ;\
  183. ;; ;\
  184. (pEOI) st4.rel [rT1] = rVector
  185. //++
  186. // Routine:
  187. //
  188. // VECTOR_CALL_HANDLER(Handler, SpecificHandler)
  189. //
  190. // Routine Description:
  191. //
  192. // Common code for transfer to heavyweight handlers from
  193. // interruption vectors. Put RSE in store intensive mode,
  194. // cover current frame and call handler.
  195. //
  196. // Arguments:
  197. //
  198. // Handler: First level handler for this vector
  199. // SpecificHandler: Specific handler to be called by the generic
  200. // exception handler.
  201. //
  202. // Return Value:
  203. //
  204. // None
  205. //
  206. // Notes:
  207. // Uses just the kernel banked registers (h16-h31)
  208. //
  209. // MS preprocessor requires /* */ style comments
  210. //--
  211. #define VECTOR_CALL_HANDLER(Handler,SpecificHandler) ;\
  212. mov rHIFA = cr##.##ifa ;\
  213. movl rHHandler = SpecificHandler ;\
  214. br##.##sptk Handler ;\
  215. ;;
  216. //++
  217. // Routine:
  218. //
  219. // ALLOCATE_TRAP_FRAME
  220. //
  221. // Routine Description:
  222. //
  223. // Common code for allocating trap frame on kernel entry for heavyweight
  224. // handler.
  225. //
  226. // On entry:
  227. //
  228. // On exit: sp -> trap frame; any instruction that depends on sp must be
  229. // placed in the new instruction group. Interruption resources
  230. // ipsr, iipa, iip, predicates, isr, sp, ifs are captured in
  231. // seven of the banked registers h16-23. The last one is used
  232. // by SAVE_INTERRUPTION_STATE as a pointer to save these resources
  233. // in the trap frame.
  234. //
  235. // Return Value:
  236. //
  237. // None
  238. //
  239. // Notes:
  240. // Uses just the kernel banked registers (h16-h31)
  241. //
  242. // MS preprocessor requires /* */ style comments below
  243. //--
  244. #define ALLOCATE_TRAP_FRAME ;\
  245. ;\
  246. pOverflow1 = pt2 ;\
  247. pOverflow2 = pt3 ;\
  248. pOverflow3 = pt4 ;\
  249. ;\
  250. mov rHIPSR = cr##.##ipsr ;\
  251. movl rTH1 = KiPcr+PcInitialStack ;\
  252. ;\
  253. mov rHIIP = cr##.##iip ;\
  254. mov rHOldPreds = pr ;\
  255. cover /* cover and save IFS */;\
  256. ;; ;\
  257. ;\
  258. ld8 rTH4 = [rTH1], PcBStoreLimit-PcInitialStack ;\
  259. mov rTH3 = ar##.##bsp ;\
  260. tbit##.##z pt1, pt0 = sp, 63 ;\
  261. ;; ;\
  262. ;\
  263. mov rHIIPA = cr##.##iipa ;\
  264. ld8 rTH2 = [rTH1], PcStackLimit-PcBStoreLimit ;\
  265. ;\
  266. mov rHIFS = cr##.##ifs ;\
  267. mov rHSp = sp ;\
  268. extr##.##u rHpT1 = rHIPSR, PSR_CPL, PSR_CPL_LEN /* get mode */;\
  269. ;; ;\
  270. ;\
  271. cmp4##.##eq pKrnl, pUser = PL_KERNEL, rHpT1 /* set mode pred */;\
  272. cmp4##.##eq pKstk, pUstk = PL_KERNEL, rHpT1 /* set stack pred */;\
  273. add rHpT1 = PcKernelDebugActive-PcStackLimit, rTH1 ;\
  274. ;; ;\
  275. ;\
  276. (pKstk) ld8 rTH1 = [rTH1] ;\
  277. (pKstk) cmp##.##geu##.##unc pOverflow2 = rTH3, rTH2 ;\
  278. (pKstk) add sp = -TrapFrameLength, sp /* allocate TF */;\
  279. ;; ;\
  280. ;\
  281. ld1 rHpT1 = [rHpT1] /* load kernel db state */;\
  282. (pKstk) cmp##.##leu##.##unc pOverflow1 = sp, rTH1 ;\
  283. (pKstk) cmp##.##geu##.##unc pOverflow3 = sp, rTH3 ;\
  284. ;; ;\
  285. ;\
  286. mov rHISR = cr##.##isr ;\
  287. cmp##.##ne##.##or pKDbg = r0, rHpT1 /* kernel debug active? */;\
  288. mov rPanicCode = PANIC_STACK_SWITCH ;\
  289. ;\
  290. (pUstk) add sp = -ThreadStateSaveAreaLength-TrapFrameLength, rTH4 ;\
  291. (pOverflow1) br.spnt.few KiPanicHandler ;\
  292. (pOverflow2) br.spnt.few KiPanicHandler ;\
  293. (pOverflow3) br.spnt.few KiPanicHandler
  294. //++
  295. // Routine:
  296. //
  297. // SAVE_INTERRUPTION_STATE(Label)
  298. //
  299. // Routine Description:
  300. //
  301. // Common code for saving interruption state on entry to a heavyweight
  302. // handler.
  303. //
  304. // Arguments:
  305. //
  306. // Label: label for branching around BSP switch
  307. //
  308. // On entry:
  309. //
  310. // sp -> trap frame
  311. //
  312. // On exit:
  313. //
  314. // Static registers gp, teb, sp, fpsr spilled into the trap frame.
  315. // Registers gp, teb, fpsr are set up for kernel mode execution.
  316. //
  317. // Return Value:
  318. //
  319. // None
  320. //
  321. // Notes:
  322. //
  323. // Interruption resources already captured in bank 0 registers h16-h23.
  324. // It's safe to take data TLB fault when saving them into the trap
  325. // frame because kernel stack is always resident in memory. This macro
  326. // is carefully constructed to save the bank registers' contents in
  327. // the trap frame and reuse them to capture other register states as
  328. // soon as they are available. Until we have a virtual register
  329. // allocation scheme in place, the bank 0 register aliases defined at
  330. // the beginning of the file must be updated when this macro is modified.
  331. //
  332. // MS preprocessor requires /* */ style comments below
  333. //--
  334. #define SAVE_INTERRUPTION_STATE(Label) ;\
  335. ;\
  336. /* Save interruption resources in trap frame */ ;\
  337. ;\
  338. ;\
  339. ssm (1 << PSR_IC) | (1 << PSR_DFH) | (1 << PSR_AC) ;\
  340. add rHpT1 = TrStIPSR, sp /* -> IPSR */;\
  341. ;; ;\
  342. srlz##.##d ;\
  343. st8 [rHpT1] = rHIPSR, TrStISR-TrStIPSR /* save IPSR */;\
  344. add rHpT2 = TrPreds, sp /* -> Preds */;\
  345. ;; ;\
  346. ;\
  347. st8 [rHpT1] = rHISR, TrStIIP-TrStISR /* save ISR */;\
  348. st8 [rHpT2] = rHOldPreds, TrBrRp-TrPreds ;\
  349. ;; ;\
  350. ;\
  351. mov rHUNAT = ar##.##unat ;\
  352. st8 [rHpT1] = rHIIP, TrStIFS-TrStIIP /* save IIP */;\
  353. mov rHBrp = brp ;\
  354. ;; ;\
  355. ;\
  356. mov rHFPSR = ar##.##fpsr ;\
  357. st8 [rHpT1] = rHIFS, TrStIIPA-TrStIFS /* save IFS */;\
  358. mov rHPFS = ar##.##pfs ;\
  359. ;; ;\
  360. ;\
  361. st8 [rHpT1] = rHIIPA, TrStFPSR-TrStIIPA /* save IIPA */;\
  362. st8 [rHpT2] = rHBrp, TrRsPFS-TrBrRp ;\
  363. ;; ;\
  364. ;\
  365. mov rHRSC = ar##.##rsc ;\
  366. st8 [rHpT2] = rHPFS /* save PFS */;\
  367. add rHpT2 = TrApUNAT, sp ;\
  368. ;\
  369. mov rHBSP = ar##.##bsp ;\
  370. ;; ;\
  371. ;\
  372. mov ar##.##rsc = r0 /* put RSE in lazy mode */;\
  373. st8 [rHpT2] = rHUNAT, TrIntGp-TrApUNAT /* save UNAT */;\
  374. ;; ;\
  375. ;\
  376. mov rHBSPSTORE = ar##.##bspstore /* get user bspstore point */;\
  377. st8 [rHpT1] = rHFPSR, TrRsBSP-TrStFPSR /* save FPSR */;\
  378. ;; ;\
  379. ;\
  380. st8##.##spill [rHpT2] = gp, TrIntTeb-TrIntGp /* spill GP */;\
  381. st8 [rHpT1] = rHBSP /* save BSP */;\
  382. ;; ;\
  383. ;\
  384. st8##.##spill [rHpT2] = teb, TrIntSp-TrIntTeb /* spill TEB (r13) */;\
  385. (pUstk) mov teb = kteb /* sanitize teb */;\
  386. sub rHBSP = rHBSP, rHBSPSTORE /* size of dirty region */;\
  387. ;; ;\
  388. ;\
  389. st8##.##spill [rHpT2] = rHSp, TrApDCR-TrIntSp /* spill SP */;\
  390. movl rHpT1 = KiPcr + PcKernelGP ;\
  391. ;; ;\
  392. ;\
  393. (pUstk) mov rHRNAT = ar##.##rnat /* get RNAT */;\
  394. movl rHFPSR = FPSR_FOR_KERNEL /* initial fpsr value */;\
  395. ;; ;\
  396. ;\
  397. mov ar##.##fpsr = rHFPSR /* set fpsr */;\
  398. add rHpT2 = TrRsRSC, sp ;\
  399. dep rHRSC = rHBSP, rHRSC, RSC_MBZ1, RSC_LOADRS_LEN ;\
  400. ;; ;\
  401. ;\
  402. ld8 gp = [rHpT1], PcInitialBStore-PcKernelGP /* load GP */;\
  403. st8 [rHpT2] = rHRSC, TrRsBSPSTORE-TrRsRSC ;\
  404. (pKstk) br##.##dpnt Label /* br if on kernel stack */;\
  405. ;; ;\
  406. ;\
  407. /* */;\
  408. /* If previous mode is user, switch to kernel backing store */;\
  409. /* -- uses the "loadrs" approach. Note that we do not save the */;\
  410. /* BSP/BSPSTORE in the trap frame if prvious mode was kernel */;\
  411. /* */;\
  412. ;\
  413. ld8 rHpT4 = [rHpT1] /* load kernel bstore */;\
  414. st8 [rHpT2] = rHBSPSTORE, TrRsRNAT-TrRsBSPSTORE ;\
  415. ;; ;\
  416. ;\
  417. st8 [rHpT2] = rHRNAT /* save user RNAT */;\
  418. dep rHpT4 = rHBSPSTORE, rHpT4, 0, 9 ;\
  419. /* adjust kernel BSPSTORE */;\
  420. /* for NAT collection */;\
  421. ;; ;\
  422. ;\
  423. /* */;\
  424. /* Now running on kernel backing store */;\
  425. /* */;\
  426. ;\
  427. Label: ;\
  428. (pUstk) mov ar##.##bspstore = rHpT4 /* switch to kernel BSP */;\
  429. (pUstk) mov ar##.##rsc = RSC_KERNEL /* turn rse on, kernel mode */;\
  430. bsw##.##1 /* switch back to user bank */;\
  431. ;; /* stop bit required */;\
  432. //++
  433. // Routine:
  434. //
  435. // RETURN_FROM_INTERRUPTION
  436. //
  437. // Routine Description:
  438. //
  439. // Common handler code to restore trap frame and resume execution
  440. // at the interruption address.
  441. //
  442. // Arguments:
  443. //
  444. // Label
  445. //
  446. // Return Value:
  447. //
  448. // None
  449. //
  450. // Note:
  451. //
  452. // On entry: interrrupts disabled, sp -> trap frame
  453. // On exit:
  454. // MS preprocessor requires /* */ style comments below
  455. //--
  456. #define RETURN_FROM_INTERRUPTION(Label) ;\
  457. ;\
  458. .##regstk 0,4,2,0 /* must match the alloc instruction below */ ;\
  459. ;\
  460. rBSP = loc0 ;\
  461. rRnat = loc1 ;\
  462. ;\
  463. rpT1 = t1 ;\
  464. rpT2 = t2 ;\
  465. rpT3 = t3 ;\
  466. rpT4 = t4 ;\
  467. rThread = t6 ;\
  468. rApcFlag = t7 ;\
  469. rT1 = t8 ;\
  470. rT2 = t9 ;\
  471. ;\
  472. ;\
  473. alloc rT1 = 0,4,2,0 ;\
  474. movl rpT1 = KiPcr + PcCurrentThread /* ->PcCurrentThread */;\
  475. ;; ;\
  476. ;\
  477. invala ;\
  478. (pUstk) ld8 rThread = [rpT1], PcDebugActive-PcCurrentThread ;\
  479. (pKstk) br##.##call##.##spnt brp = KiRestoreTrapFrame ;\
  480. ;; ;\
  481. ;\
  482. (pUstk) ld1 rT1 = [rpT1] /* load user debug active state */;\
  483. (pUstk) add rpT1 = ThApcState+AsUserApcPending, rThread ;\
  484. (pKstk) br##.##spnt Label##CriticalExitCode ;\
  485. ;; ;\
  486. ;\
  487. ld1 rApcFlag = [rpT1], ThAlerted-ThApcState-AsUserApcPending ;\
  488. add rBSP = TrRsBSP, sp ;\
  489. add rRnat = TrRsRNAT, sp /* -> user RNAT */;\
  490. ;; ;\
  491. ;\
  492. st1.nta [rpT1] = zero ;\
  493. cmp##.##ne pApc = zero, rApcFlag ;\
  494. cmp##.##ne pUDbg = zero, rT1 /* if ne, user debug active */;\
  495. ;; ;\
  496. ;\
  497. PSET_IRQL (pApc, APC_LEVEL) ;\
  498. movl gp = _gp /* restore to kernel gp value */;\
  499. ;\
  500. (pApc) FAST_ENABLE_INTERRUPTS ;\
  501. (pApc) mov out1 = sp ;\
  502. (pApc) br##.##call##.##sptk brp = KiApcInterrupt ;\
  503. ;; ;\
  504. ;\
  505. ld8 rBSP = [rBSP] /* user BSP */;\
  506. ld8 rRnat = [rRnat] /* user RNAT */;\
  507. ;\
  508. (pApc) FAST_DISABLE_INTERRUPTS ;\
  509. PSET_IRQL (pApc, zero) ;\
  510. (pUDbg) br##.##call##.##spnt brp = KiLoadUserDebugRegisters ;\
  511. ;; ;\
  512. ;\
  513. br##.##call##.##sptk brp = KiRestoreTrapFrame ;\
  514. ;; ;\
  515. ;\
  516. ;\
  517. Label##CriticalExitCode: ;\
  518. ;\
  519. add loc2 = TrBrRp, sp ;\
  520. add loc3 = TrRsRSC, sp ;\
  521. bsw##.##0 ;\
  522. ;; ;\
  523. ;\
  524. ld8 rHBrp = [loc2], TrStIPSR-TrBrRp ;\
  525. ld8 rHRSC = [loc3] ;\
  526. mov loc3 = RSC_KERNEL_DISABLED ;\
  527. ;; ;\
  528. ;\
  529. ld8 rHIPSR = [loc2], TrRsPFS-TrStIPSR ;\
  530. movl rHpT1 = KiPcr+PcHighFpOwner ;\
  531. ;; ;\
  532. ;\
  533. ld8 rHPFS = [loc2] ;\
  534. ld8 rHpT4 = [rHpT1], PcCurrentThread-PcHighFpOwner ;\
  535. extr.u loc2 = rHRSC, RSC_MBZ1, RSC_LOADRS_LEN ;\
  536. ;; ;\
  537. ;\
  538. sub rHBSPSTORE = rBSP, loc2 ;\
  539. dep loc3 = loc2, loc3, RSC_LOADRS, RSC_LOADRS_LEN ;\
  540. ;; ;\
  541. ;\
  542. mov ar##.##rsc = loc3 /* RSE off */ ;\
  543. mov brp = rHBrp ;\
  544. mov rHRNAT = rRnat ;\
  545. ;; ;\
  546. ;\
  547. alloc rTH1 = 0,0,0,0 ;\
  548. ;; ;\
  549. ;\
  550. loadrs /* pull in user regs */;\
  551. /* up to tear point */ ;\
  552. dep rHRSC = r0, rHRSC, RSC_MBZ1, RSC_LOADRS_LEN ;\
  553. ;; ;\
  554. ;\
  555. (pUstk) mov ar##.##bspstore = rHBSPSTORE /* restore user BSP */ ;\
  556. ld8 rHpT3 = [rHpT1], PcKernelDebugActive-PcCurrentThread ;\
  557. mov ar##.##pfs = rHPFS /* restore PFS */;\
  558. ;; ;\
  559. ;\
  560. (pUstk) mov ar##.##rnat = rHRNAT /* restore user RNAT */;\
  561. ld1 rHpT1 = [rHpT1] ;\
  562. add rHIFS = TrStIFS, sp ;\
  563. ;; ;\
  564. ;\
  565. ld8 rHIFS = [rHIFS] /* load IFS */;\
  566. cmp##.##ne pt0, pt1 = rHpT4, rHpT3 ;\
  567. dep rHpT4 = 0, rHIPSR, PSR_MFH, 1 ;\
  568. ;; ;\
  569. ;\
  570. mov ar.rsc = rHRSC /* restore user RSC */;\
  571. (pKstk) cmp##.##ne##.##unc pKDbg, pt2 = rHpT1, r0 /* hardware debug? */ ;\
  572. (pUstk) dep rHpT4 = 1, rHpT4, PSR_DFH, 1 ;\
  573. ;; ;\
  574. ;\
  575. (pt0) mov rHIPSR = rHpT4 ;\
  576. add rHpT4 = TrApUNAT, sp /* -> previous UNAT */;\
  577. add rHpT1 = TrStIIPA, sp ;\
  578. ;; ;\
  579. ;\
  580. ld8 rHUNAT = [rHpT4],TrPreds-TrApUNAT ;\
  581. ld8 rHIIPA = [rHpT1], TrStIIP-TrStIIPA ;\
  582. (pKDbg) dep rHIPSR = 1, rHIPSR, PSR_DB, 1 ;\
  583. ;; ;\
  584. ;\
  585. ld8 rHOldPreds = [rHpT4], TrIntSp-TrPreds ;\
  586. ld8 rHIIP = [rHpT1], TrStIFS-TrStIIP /* load IIP */;\
  587. (pt2) dep rHIPSR = 0, rHIPSR, PSR_DB, 1 ;\
  588. ;; ;\
  589. ;\
  590. ld8##.##fill sp = [rHpT4], TrStIFS-TrIntSp ;\
  591. rsm 1 << PSR_IC /* reset ic bit */;\
  592. ;; ;\
  593. ;\
  594. srlz##.##d /* must serialize */;\
  595. ;\
  596. /* */;\
  597. /* Restore status registers */;\
  598. /* */;\
  599. ;\
  600. mov cr##.##ipsr = rHIPSR /* restore previous IPSR */;\
  601. mov cr##.##iipa = rHIIPA /* restore previous IIPA */;\
  602. ;\
  603. mov cr##.##ifs = rHIFS /* restore previous IFS */;\
  604. mov cr##.##iip = rHIIP /* restore previous IIP */;\
  605. mov pr = rHOldPreds, -1 /* restore preds */;\
  606. ;; ;\
  607. ;\
  608. /* */;\
  609. /* Resume at point of interruption (rfi must be at end of instruction group)*/;\
  610. /* */;\
  611. mov ar##.##unat = rHUNAT /* restore UNAT */;\
  612. mov h17 = r0 /* clear TB loop count */;\
  613. rfi ;\
  614. ;;
  615. //
  616. // Interruption Vector Table. First level interruption vectors.
  617. // This section must be 32K aligned. The special section ".drectve"
  618. // is used to pass the align command to the linker.
  619. //
  620. .section .drectve, "MI", "progbits"
  621. string "-section:.ivt,,align=0x8000"
  622. .section .ivt = "ax", "progbits"
  623. KiIvtBase:: // symbol for start of IVT
  624. //++
  625. //
  626. // KiVhptTransVector
  627. //
  628. // Cause: The hardware VHPT walker encountered a TLB miss while attempting to
  629. // reference the virtuall addressed VHPT linear table.
  630. //
  631. // Parameters: cr.iip - address of bundle for which the hardware VHPT walker was
  632. // trying to resolve the TLB miss
  633. //
  634. // cr.ipsr - copy of PSR at the time of the fault
  635. //
  636. // cr.idtr - default translation inforamtion for the address that caused
  637. // a VHPT translation fault
  638. //
  639. // cr.ifa - original faulting address
  640. //
  641. // cr.isr - original faulting status information
  642. //
  643. // Handle: Extracts the PDE index from cr.iha (PTE address in VHPT) and
  644. // generates a PDE address by adding to VHPT_DIRBASE. When accesses
  645. // a page directory entry (PDE), there might be a TLB miss on the
  646. // page directory table and returns a NaT on ld8.s. If so, branches
  647. // to KiPageDirectoryTableFault. If the page-not-present bit of the
  648. // PDE is not set, branches to KiPageNotPresentFault. Otherwise,
  649. // inserts the PDE entry into the data TC (translation cache).
  650. //
  651. //--
  652. VECTOR_ENTRY(0x0000, KiVhptTransVector, cr.ifa)
  653. #if 1
  654. rva = h24
  655. riha = h25
  656. rpr = h26
  657. rPte = h27
  658. rPte2 = h28
  659. rps = h29
  660. risr = h30
  661. riha2 = h31
  662. rCache = h28
  663. mov rva = cr.ifa // M0
  664. mov riha = cr.iha // M0
  665. mov rpr = pr // I
  666. mov risr = cr.isr // M0
  667. ;;
  668. #ifndef NO_IHA_CHECK
  669. thash riha2 = rva // M0, for extra IHA checking
  670. #endif
  671. ld8.s rPte = [riha] // M
  672. tbit.z pt3, pt4 = risr, ISR_X // I
  673. ;;
  674. tnat.nz pt0 = rPte // I
  675. tbit.z pt1 = rPte, PTE_VALID // I
  676. (pt0) br.cond.spnt KiPageTableFault // B
  677. (pt1) br.cond.spnt KiPteNotPresentFault // B
  678. extr.u rCache = rPte, 2, 3 // I
  679. ;;
  680. cmp.eq pt5 = 1, rCache // A
  681. (pt5) br.cond.spnt KiPageTableFault // B
  682. ;;
  683. .pred.rel "mutex",pt3,pt4
  684. (pt4) itc.i rPte // M
  685. ;;
  686. (pt3) itc.d rPte // M
  687. ;;
  688. #if !defined(NT_UP)
  689. ld8.s rPte2 = [riha] // M
  690. mov rps = PAGE_SHIFT << PS_SHIFT // I
  691. cmp.ne pt0 = zero, zero // I
  692. ;;
  693. cmp.ne.or pt0 = rPte2, rPte // M
  694. #ifndef NO_IHA_CHECK
  695. cmp.ne.or pt0 = riha, riha2 // M, check if IHA is correct
  696. #endif
  697. tnat.nz.or pt0 = rPte2 // I
  698. ;;
  699. (pt0) ptc.l rva, rps // M
  700. #else
  701. #ifndef NO_IHA_CHECK
  702. cmp.ne pt0 = riha, riha2 // M, check if IHA is correct
  703. mov rps = PAGE_SHIFT << PS_SHIFT // I
  704. ;;
  705. (pt0) ptc.l rva, rps // M
  706. #endif
  707. #endif
  708. mov pr = rpr, -1 // I
  709. rfi;; // B
  710. #else
  711. rva = h24
  712. riha = h25
  713. rpr = h26
  714. rpPde = h27
  715. rPde = h28
  716. rPde2 = h29
  717. rps = h30
  718. mov riha = cr.iha // M
  719. mov rva = cr.ifa // M
  720. mov rpr = pr // I
  721. ;;
  722. thash rpPde = riha // M
  723. ;;
  724. ld8.s rPde = [rpPde] // M, load PDE
  725. ;;
  726. tnat.nz pt0, p0 = rPde // I
  727. tbit.z pt1, p0 = rPde, PTE_VALID // I, if non-present page fault
  728. (pt0) br.cond.spnt KiPageDirectoryFault // B
  729. (pt1) br.cond.spnt KiPdeNotPresentFault // B
  730. mov cr.ifa = riha // M
  731. ;;
  732. itc.d rPde // M
  733. ;;
  734. #if !defined(NT_UP)
  735. ld8.s rPde2 = [rpPde] // M
  736. mov rps = PAGE_SHIFT << PS_SHIFT // I
  737. cmp.ne pt0 = zero, zero // I
  738. ;;
  739. cmp.ne.or pt0 = rPde2, rPde // M, if PTEs are different
  740. tnat.nz.or pt0 = rPde2 // I
  741. ;;
  742. (pt0) ptc.l riha, rps // M, purge it
  743. #endif
  744. mov pr = rpr, -1 // I
  745. rfi // B
  746. ;;
  747. #endif
  748. VECTOR_EXIT(KiVhptTransVector)
  749. //++
  750. //
  751. // KiInstTlbVector
  752. //
  753. // Cause: The VHPT walker aborted the search for the instruction translation.
  754. //
  755. // Parameters: cr.iip - address of bundle for which the hardware VHPT walker was
  756. // trying to resolve the TLB miss
  757. //
  758. // cr.ipsr - copy of PSR at the time of the fault
  759. //
  760. // cr.iha - PTE address in the VHPT which the VHPT walker was attempting to
  761. // reference
  762. //
  763. // cr.iitr - default translation inforamtion for the address that caused
  764. // a instruction TLB miss
  765. //
  766. // cr.isr - faulting status information
  767. //
  768. // Handle: As the VHPT has aborted the search or the implemenation does not
  769. // support the h/w page table walk, the handler needs to emulates the
  770. // function. Since the offending PTE address is already available
  771. // with cr.iha, the handler can access the PTE without performing THASH.
  772. // Accessing a PTE with ld8.s may return a NaT. If so, it branches to
  773. // KiPageTableFault. If the page-not-present bit of the PTE is not set,
  774. // it branches to KiPageFault.
  775. //
  776. // Comments: Merced never casues this fault since it never abort the search on the
  777. // VHPT.
  778. //
  779. //--
  780. VECTOR_ENTRY(0x0400, KiInstTlbVector, cr.iipa)
  781. rva = h24
  782. riha = h25
  783. rpr = h26
  784. rPte = h27
  785. rPte2 = h28
  786. rps = h29
  787. rCache = h28
  788. KiInstTlbVector0:
  789. mov riha = cr.iha // M
  790. mov rva = cr.ifa // M
  791. mov rpr = pr // I
  792. ;;
  793. ld8.s rPte = [riha] // M
  794. ;;
  795. tnat.nz pt0, p0 = rPte // I
  796. tbit.z pt1, p0 = rPte, PTE_VALID // I
  797. (pt0) br.cond.spnt KiPageTableFault // B
  798. (pt1) br.cond.spnt KiPteNotPresentFault // B
  799. extr.u rCache = rPte, 2, 3 // I
  800. ;;
  801. cmp.eq pt3 = 1, rCache // A
  802. (pt3) br.cond.spnt Ki4KInstTlbFault // B
  803. itc.i rPte // M
  804. ;;
  805. #if !defined(NT_UP)
  806. ld8.s rPte2 = [riha] // M
  807. mov rps = PAGE_SHIFT << PS_SHIFT // I
  808. cmp.ne pt0 = zero, zero // I
  809. ;;
  810. cmp.ne.or pt0 = rPte2, rPte // M
  811. tnat.nz.or pt0 = rPte2 // I
  812. ;;
  813. (pt0) ptc.l rva, rps // M
  814. #endif
  815. mov pr = rpr, -1 // I
  816. rfi;; // B
  817. VECTOR_EXIT(KiInstTlbVector)
  818. //++
  819. //
  820. // KiDataTlbVector
  821. //
  822. // Cause: The VHPT walker aborted the search for the data translation.
  823. //
  824. // Parameters: cr.iip - address of bundle for which the hardware VHPT walker was
  825. // trying to resolve the TLB miss
  826. //
  827. // cr.ipsr - copy of PSR at the time of the fault
  828. //
  829. // cr.iha - PTE address in the VHPT which the VHPT walker was attempting to
  830. // reference
  831. //
  832. // cr.idtr - default translation inforamtion for the address that caused
  833. // a data TLB miss
  834. //
  835. // cr.ifa - address that caused a data TLB miss
  836. //
  837. // cr.isr - faulting status information
  838. //
  839. // Handle: As the VHPT has aborted the search or the implemenation does not
  840. // support the h/w page table walk, the handler needs to emulates the
  841. // function. Since the offending PTE address is already available
  842. // with cr.iha, the handler can access the PTE without performing THASH.
  843. // Accessing a PTE with ld8.s may return a NaT. If so, it branches to
  844. // KiPageTableFault. If the page-not-present bit of the PTE is not set,
  845. // it branches to KiPageFault.
  846. //
  847. // Comments: Merced never casues instruction TLB faults since the VHPT search always
  848. // sucesses.
  849. //
  850. //--
  851. VECTOR_ENTRY(0x0800, KiDataTlbVector, cr.ifa)
  852. rva = h24
  853. riha = h25
  854. rpr = h26
  855. rPte = h27
  856. rPte2 = h28
  857. rps = h29
  858. rCache = h28
  859. KiDataTlbVector0:
  860. mov riha = cr.iha // M
  861. mov rva = cr.ifa // M
  862. mov rpr = pr // I
  863. ;;
  864. ld8.s rPte = [riha] // M
  865. ;;
  866. extr.u rCache = rPte, 2, 3 // I
  867. ;;
  868. cmp.eq pt3 = 1, rCache // A
  869. (pt3) br.cond.spnt Ki4KDataTlbFault // B
  870. tnat.nz pt0, p0 = rPte // I
  871. tbit.z pt1, p0 = rPte, PTE_VALID // I
  872. (pt0) br.cond.spnt KiPageTableFault // B
  873. (pt1) br.cond.spnt KiPteNotPresentFault // B
  874. itc.d rPte // M
  875. ;;
  876. #if !defined(NT_UP)
  877. ld8.s rPte2 = [riha] // M
  878. mov rps = PAGE_SHIFT << PS_SHIFT // I
  879. cmp.ne pt0 = zero, zero // I
  880. ;;
  881. cmp.ne.or pt0 = rPte2, rPte // M
  882. tnat.nz.or pt0 = rPte2 // I
  883. ;;
  884. (pt0) ptc.l rva, rps // M
  885. #endif
  886. mov pr = rpr, -1 // I
  887. rfi;; // B
  888. VECTOR_EXIT(KiDataTlbVector)
  889. //++
  890. //
  891. // KiAltTlbVector
  892. //
  893. // Cause: There was a TLB miss for instruction execution and the VHPT
  894. // walker was not enabled for the referenced region.
  895. //
  896. // Parameters: cr.iip - address of bundle that caused a TLB miss
  897. //
  898. // cr.ipsr - copy of PSR at the time of the fault
  899. //
  900. // cr.idtr - default translation inforamtion for the address that caused
  901. // the fault.
  902. //
  903. // cr.isr - faulting status information
  904. //
  905. // Handle: Currently, NT does not have any use of this vector.
  906. //
  907. //--
  908. VECTOR_ENTRY(0x0c00, KiAltInstTlbVector, cr.iipa)
  909. rva = h24
  910. riha = h25
  911. mov rva = cr.ifa
  912. ;;
  913. thash riha = rva
  914. ;;
  915. mov cr.iha = riha
  916. ;;
  917. srlz.d
  918. br.sptk KiInstTlbVector0
  919. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  920. VECTOR_EXIT(KiAltInstTlbVector)
  921. //++
  922. //
  923. // KiAltDataTlbVector
  924. //
  925. // Cause: There was a data TLB miss and the VHPT walker was not enabled for
  926. // the referenced region.
  927. //
  928. // Parameters: cr.iip - address of bundle that caused a TLB miss
  929. //
  930. // cr.ipsr - copy of PSR at the time of the fault
  931. //
  932. // cr.idtr - default translation inforamtion for the address that caused
  933. // the fault.
  934. //
  935. // cr.isr - faulting status information
  936. //
  937. // Handle: Currently, NT does not have any use of this vector.
  938. //
  939. //--
  940. VECTOR_ENTRY(0x1000, KiAltDataTlbVector, cr.ifa)
  941. rva = h24
  942. riha = h25
  943. rpr = h26
  944. rPte = h27
  945. rKseglimit = h28
  946. rIPSR = h30
  947. rISR = h29
  948. rVrn = h31
  949. #if NO_VHPT_WALKER
  950. rRR = h30
  951. mov rva = cr.ifa // M
  952. mov rpr = pr // I
  953. ;;
  954. mov rRR = rr[rva]
  955. movl rKseglimit = KSEG3_LIMIT
  956. ;;
  957. thash riha = rva
  958. tbit.z pt4 = rRR, 0
  959. mov rIPSR = cr.ipsr
  960. shr.u rVrn = rva, VRN_SHIFT // I, get VPN
  961. (pt4) br.cond.spnt AltFault
  962. ;;
  963. mov cr.iha = riha
  964. ;;
  965. srlz.d
  966. mov pr = rpr, -1
  967. br.sptk KiDataTlbVector0
  968. ;;
  969. AltFault:
  970. #else
  971. mov rva = cr.ifa // M
  972. movl rKseglimit = KSEG3_LIMIT
  973. ;;
  974. mov rIPSR = cr.ipsr
  975. mov rpr = pr // I
  976. shr.u rVrn = rva, VRN_SHIFT // I, get VPN
  977. ;;
  978. #endif
  979. extr.u rIPSR = rIPSR, PSR_CPL, PSR_CPL_LEN
  980. ;;
  981. cmp.ne pt1 = PL_KERNEL, rIPSR
  982. cmp.ne pt2 = KSEG3_VRN, rVrn // M/I
  983. cmp.eq pt4 = KSEG4_VRN, rVrn
  984. (pt1) br.cond.spnt KiCallMemoryFault // if it was User
  985. (pt4) br.cond.spnt KiKseg4Fault
  986. (pt2) br.cond.spnt NoKsegFault // B
  987. cmp.leu pt0 = rKseglimit, rva
  988. (pt0) br.cond.spnt NoKsegFault
  989. mov rISR = cr.isr // M
  990. movl rPte = VALID_KERNEL_PTE // L
  991. mov rIPSR = cr.ipsr // M
  992. shr.u rva = rva, PAGE_SHIFT // I
  993. ;;
  994. tbit.z pt2, pt3 = rISR, ISR_SP // I
  995. dep.z rva = rva, PAGE_SHIFT, 32 // I
  996. ;;
  997. or rPte = rPte, rva // I
  998. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  999. ;;
  1000. (pt2) itc.d rPte // M
  1001. ;;
  1002. (pt3) mov cr.ipsr = rIPSR // M
  1003. ;;
  1004. mov pr = rpr, -1 // I
  1005. rfi // B
  1006. ;;
  1007. NoKsegFault:
  1008. rPdeUtbase = h27
  1009. rva0 = h29
  1010. rPpe = h30
  1011. oldgp = h31
  1012. shr.u rva0 = rva, PAGE_SHIFT
  1013. movl rPdeUtbase = KiPcr+PcPdeUtbase
  1014. mov oldgp = gp
  1015. movl gp = _gp
  1016. ;;
  1017. ld8 rPdeUtbase = [rPdeUtbase]
  1018. add rPpe = @gprel(MiDefaultPpe), gp
  1019. dep.z rva0 = rva0, PAGE_SHIFT, VRN_SHIFT-PAGE_SHIFT
  1020. ;;
  1021. ld8 rPpe = [rPpe]
  1022. cmp.ne pt3, p0 = rva0, rPdeUtbase
  1023. mov gp = oldgp
  1024. (pt3) br.cond.spnt KiPageFault
  1025. ;;
  1026. itc.d rPpe
  1027. ;;
  1028. mov pr = rpr, -1
  1029. rfi;;
  1030. VECTOR_EXIT(KiAltDataTlbVector)
  1031. //++
  1032. //
  1033. // KiNestedTlbVector
  1034. //
  1035. // Cause: Instruction/Data TLB miss handler encountered a TLB miss while
  1036. // attempting to reference the PTE in the virtuall addressed
  1037. // VHPT linear table.
  1038. //
  1039. // Parameters: cr.iip - address of bundle for which the hardware VHPT walker was
  1040. // trying to resolve the TLB miss
  1041. //
  1042. // cr.ipsr - copy of PSR at the time of VHPT translation fault
  1043. //
  1044. // cr.iha - address in VHPT which the VHPT walker was attempting to
  1045. // reference
  1046. //
  1047. // cr.idtr - default translation inforamtion for the virtual address
  1048. // contained in cr.iha
  1049. //
  1050. // cr.ifa - original faulting address
  1051. //
  1052. // cr.isr - faulting status information
  1053. //
  1054. // h16(riha) - PTE address in the VHPT which caused the Nested miss
  1055. //
  1056. // Handle: Currently, there is no use for Nested TLB vector. This should be
  1057. // a bug fault. Call KiPanicHandler.
  1058. //
  1059. //--
  1060. VECTOR_ENTRY(0x1400, KiNestedTlbVector, cr.ifa)
  1061. ALLOCATE_TRAP_FRAME
  1062. br.sptk KiPanicHandler
  1063. VECTOR_EXIT(KiNestedTlbVector)
  1064. //++
  1065. //
  1066. // KiInstKeyMissVector
  1067. //
  1068. // Cause: There was a instruction key miss in the translation. Since the
  1069. // architecture allows an implementation to choose a unified TC
  1070. // structure, the hyper space translation brought by the data
  1071. // access-bit may cause a instruction key miss fault. Only erroneous
  1072. // user code tries to execute the NT page table and hyper space.
  1073. //
  1074. // Parameters: cr.iip - address of bundle which caused a instruction key miss fault
  1075. //
  1076. // cr.ipsr - copy of PSR at the time of the data key miss fault
  1077. //
  1078. // cr.idtr - default translation inforamtion of the address that caused
  1079. // the fault.
  1080. //
  1081. // cr.isr - faulting status information
  1082. //
  1083. // Handle: Save the whole register state and call MmAccessFault().
  1084. //
  1085. //--
  1086. VECTOR_ENTRY(0x1800, KiInstKeyMissVector, cr.iipa)
  1087. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1088. VECTOR_EXIT(KiInstKeyMissVector)
  1089. //++
  1090. //
  1091. // KiDataKeyMissVector
  1092. //
  1093. // Cause: The referenced translation had the different key ID from the one
  1094. // specified the key permission register. This is an indication of
  1095. // TLB miss on the NT page table and hyperspace.
  1096. //
  1097. // Parameters: cr.iip - address of bundle which caused the fault
  1098. //
  1099. // cr.ipsr - copy of PSR at the time of the data key miss fault
  1100. //
  1101. // cr.idtr - default translation inforamtion of the address that caused
  1102. // the fault.
  1103. //
  1104. // cr.ifa - address that caused a data key miss
  1105. //
  1106. // cr.isr - faulting status information
  1107. //
  1108. // Handle: The handler needs to purge the faulting translation and install
  1109. // a new PTE by loading it from the VHPT. The key ID of the IDTR
  1110. // for the installing translation should be modified to be the same
  1111. // ID as the local region ID. This effectively creates a local
  1112. // space within the global kernel space.
  1113. //
  1114. //--
  1115. VECTOR_ENTRY(0x1c00, KiDataKeyMissVector, cr.ifa)
  1116. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1117. VECTOR_EXIT(KiDataKeyMissVector)
  1118. //++
  1119. //
  1120. // KiDirtyBitVector
  1121. //
  1122. // Cause: The refereced data translation did not have the dirty-bit set and
  1123. // a write operation was made to this page.
  1124. //
  1125. // Parameters: cr.iip - address of bundle which caused a dirty bit fault
  1126. //
  1127. // cr.ipsr - copy of PSR at the time of a data access fault
  1128. //
  1129. // cr.idtr - default translation inforamtion for the address that
  1130. // caused the fault
  1131. //
  1132. // cr.ifa - referenced data address that caused the dirty-bit fault
  1133. //
  1134. // cr.isr - faulting status information
  1135. //
  1136. // Handle: Save the whole register state and call MmAccessFault().
  1137. //
  1138. // Comments: There is always a TLB coherency problem on a multiprocessor
  1139. // system. Rather than implementing an atomic operation of setting
  1140. // dirty-bit within this handler, the handler instead calls the high
  1141. // level C routine, MmAccessFault(), to perform locking the page table
  1142. // and setting the dirty-bit of the PTE.
  1143. //
  1144. // It is too much effort to implement the atomic operation of setting
  1145. // the dirty-bit using cmpxchg; a potential nested TLB miss on load/store
  1146. // and restoring ar.ccv complicate the design of the handler.
  1147. //
  1148. //--
  1149. VECTOR_ENTRY(0x2000, KiDirtyBitVector, cr.ifa)
  1150. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1151. VECTOR_EXIT(KiDirtyBitVector)
  1152. //++
  1153. //
  1154. // KiInstAccessBitVector
  1155. //
  1156. // Cause: There is a access-bit fault on the instruction translation. This only
  1157. // happens if the erroneous user mistakenly accesses the NT page table and
  1158. // hyper space.
  1159. //
  1160. // Parameters: cr.iip - address of bundle which caused a instruction access bit fault
  1161. //
  1162. // cr.ipsr - copy of PSR at the time of a data access fault
  1163. //
  1164. // cr.idtr - default translation inforamtion for the address that
  1165. // caused the fault
  1166. //
  1167. // cr.ifa - referenced data address that caused the data access-bit fault
  1168. //
  1169. // cr.isr - faulting status information
  1170. //
  1171. // Handle: Save the whole register state and call MmAccessFault().
  1172. //
  1173. //--
  1174. VECTOR_ENTRY(0x2400, KiInstAccessBitVector, cr.iipa)
  1175. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1176. VECTOR_EXIT(KiInstAccessBitVector)
  1177. //++
  1178. //
  1179. // KiDataBitAccessVector
  1180. //
  1181. // Cause: The reference-bit in the the referenced translation was zero,
  1182. // indicating there was a TLB miss on the NT page table or hyperspace.
  1183. //
  1184. // Parameters: cr.iip - address of bundle which caused a data access bit fault
  1185. //
  1186. // cr.ipsr - copy of PSR at the time of a data access fault
  1187. //
  1188. // cr.idtr - default translation inforamtion for the address that
  1189. // caused the fault
  1190. //
  1191. // cr.ifa - referenced data address that caused the data access-bit fault
  1192. //
  1193. // cr.isr - faulting status information
  1194. //
  1195. // Handle: The reference-bit is used to fault on PTEs for the NT page table and
  1196. // hyperspace. On a data access-bit fault, the handler needs to change the
  1197. // the default key ID of the IDTR to be the local key ID. This effectively
  1198. // creates the local space within the global kernel space.
  1199. //
  1200. //--
  1201. VECTOR_ENTRY(0x2800, KiDataAccessBitVector, cr.ifa)
  1202. rva = h24
  1203. rpr = h26
  1204. rIPSR = h27
  1205. rISR = h31
  1206. //
  1207. // check to see if non-present fault occurred on a speculative load.
  1208. // if so, set IPSR.ed bit. This forces to generate a NaT on ld.s after
  1209. // rfi
  1210. //
  1211. mov rpr = pr
  1212. mov rISR = cr.isr // M
  1213. mov rIPSR = cr.ipsr // M
  1214. ;;
  1215. tbit.z pt0, p0 = rISR, ISR_SP // I
  1216. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  1217. (pt0) br.cond.spnt KiCallMemoryFault // B
  1218. ;;
  1219. mov cr.ipsr = rIPSR // M
  1220. ;;
  1221. mov pr = rpr, -1 // I
  1222. rfi // B
  1223. ;;
  1224. VECTOR_EXIT(KiDataBitAccessVector)
  1225. //--------------------------------------------------------------------
  1226. // Routine:
  1227. //
  1228. // KiBreakVector
  1229. //
  1230. // Description:
  1231. //
  1232. // Interruption vector for break instruction.
  1233. //
  1234. // On entry:
  1235. //
  1236. // IIM contains break immediate value:
  1237. // -- BREAK_SYSCALL -> standard system call
  1238. // interrupts disabled
  1239. // r16-r31 switched to kernel bank
  1240. // r16-r31 all available since no TLB faults at this point
  1241. //
  1242. // Return value:
  1243. //
  1244. // if system call, sys call return value in v0.
  1245. //
  1246. // Process:
  1247. //--------------------------------------------------------------------
  1248. VECTOR_ENTRY(0x2C00, KiBreakVector, cr.iim)
  1249. mov rHIIM = cr.iim // get break value
  1250. movl rTH1 = KiPcr+PcSavedIIM
  1251. ;;
  1252. st8 [rTH1] = rHIIM
  1253. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiOtherBreakException)
  1254. //
  1255. // Do not return from handler
  1256. //
  1257. VECTOR_EXIT(KiBreakVector)
  1258. //--------------------------------------------------------------------
  1259. // Routine:
  1260. //
  1261. // KiExternalInterruptVector
  1262. //
  1263. // Routine Description:
  1264. //
  1265. // Interruption vector for External Interrrupt
  1266. //
  1267. // On entry:
  1268. //
  1269. // interrupts disabled
  1270. // r16-r31 switched to kernel bank
  1271. //
  1272. // Return value:
  1273. //
  1274. // none
  1275. //
  1276. // Process:
  1277. //--------------------------------------------------------------------
  1278. VECTOR_ENTRY(0x3000, KiExternalInterruptVector, r0)
  1279. mov h24 = cr.iip
  1280. movl h25 = MM_EPC_VA+0x20
  1281. ;;
  1282. mov h26 = pr
  1283. cmp.ne pt0 = h25, h24
  1284. add h25 = 0x10, h25
  1285. ;;
  1286. mov h27 = cr.ipsr
  1287. (pt0) cmp.ne pt0 = h25, h24
  1288. ;;
  1289. dep h27 = 0, h27, PSR_I, 1
  1290. (pt0) br.cond.sptk kei_taken
  1291. ;;
  1292. mov cr.ipsr = h27
  1293. ;;
  1294. mov pr = h26, -1
  1295. rfi
  1296. ;;
  1297. kei_taken:
  1298. mov pr = h26, -1
  1299. ;;
  1300. ALLOCATE_TRAP_FRAME
  1301. ;;
  1302. SAVE_INTERRUPTION_STATE(Keih_SaveTrapFrame)
  1303. br.many KiExternalInterruptHandler
  1304. ;;
  1305. //
  1306. // Do not return (rfi from handler)
  1307. //
  1308. VECTOR_EXIT(KiExternalInterruptVector)
  1309. //++
  1310. //
  1311. // KiPageNotPresentVector
  1312. //
  1313. // Cause: The translation for the referenced page did not have a present-bit
  1314. // set.
  1315. //
  1316. // Parameters: cr.iip - address of bundle which caused a page not present fault
  1317. //
  1318. // cr.ipsr - copy of PSR at the time of a page not present ault
  1319. //
  1320. // cr.idtr - default translation inforamtion for the address that
  1321. // caused the fault
  1322. //
  1323. // cr.ifa - referenced data address if the fault occurred on the data
  1324. // reference
  1325. //
  1326. // cr.isr - faulting status information
  1327. //
  1328. // Handle: This is the page fault. The handler saves the register context and
  1329. // calls MmAccessFault().
  1330. //
  1331. //--
  1332. VECTOR_ENTRY(0x5000, KiPageNotPresentVector, cr.ifa)
  1333. rva = h24
  1334. riha = h25
  1335. rpr = h26
  1336. rPte = h27
  1337. rps = h29
  1338. mov rva = cr.ifa // M
  1339. mov rpr = pr // I
  1340. ;;
  1341. thash riha = rva // M
  1342. cmp.ne pt1 = r0, r0
  1343. mov rps = PAGE_SHIFT << PS_SHIFT // I
  1344. ;;
  1345. ld8.s rPte = [riha] // M
  1346. ;;
  1347. tnat.nz pt0, p0 = rPte // I
  1348. tbit.z.or pt1, p0 = rPte, PTE_ACCESS
  1349. tbit.z.or pt1, p0 = rPte, PTE_VALID // I, if non-present page fault
  1350. (pt0) br.cond.spnt KiPageTableFault // B
  1351. (pt1) br.cond.spnt KiPteNotPresentFault // B
  1352. //
  1353. // if we find a valid PTE that is speculatively fetched into the TLB
  1354. // then, purge it and return.
  1355. //
  1356. ptc.l rva, rps // M
  1357. ;;
  1358. mov pr = rpr, -1 // I
  1359. rfi;; // B
  1360. VECTOR_EXIT(KiPageNotPresentVector)
  1361. //++
  1362. //
  1363. // KiKeyPermVector
  1364. //
  1365. // Cause: Read, write or execution key permissions were violated.
  1366. //
  1367. // Parameters: cr.iip - address of bundle which caused a key permission fault
  1368. //
  1369. // cr.ipsr - copy of PSR at the time of a key permission fault
  1370. //
  1371. // cr.idtr - default translation inforamtion for the address that
  1372. // caused the fault
  1373. //
  1374. // cr.ifa - referenced data address if the key permission occurred on
  1375. // the data reference
  1376. //
  1377. // cr.isr - faulting status information
  1378. //
  1379. // Handle: This should not happen. The EM/NT does not utilize the key permissions.
  1380. // The handler saves the register state and calls the bug check.
  1381. //
  1382. //--
  1383. VECTOR_ENTRY(0x5100, KiKeyPermVector, cr.ifa)
  1384. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1385. VECTOR_EXIT(KiKeyPermVector)
  1386. //++
  1387. //
  1388. // KiInstAccessRightsVector
  1389. //
  1390. // Cause: The referenced page had a access rights violation.
  1391. //
  1392. // Parameters: cr.iip - address of bundle which caused a data access bit fault
  1393. //
  1394. // cr.ipsr - copy of PSR at the time of a data access fault
  1395. //
  1396. // cr.idtr - default translation inforamtion for the address that
  1397. // caused the fault
  1398. //
  1399. // cr.ifa - referenced data address that caused the data ccess-bit fault
  1400. //
  1401. // cr.isr - faulting status information
  1402. //
  1403. // Handle: The handler saves the register context and calls MmAccessFault().
  1404. //
  1405. //--
  1406. VECTOR_ENTRY(0x5200, KiInstAccessRightsVector, cr.iipa)
  1407. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  1408. VECTOR_EXIT(KiInstAccessRightsVector)
  1409. //++
  1410. //
  1411. // KiDataAccessRightsVector
  1412. //
  1413. // Cause: The referenced page had a data access rights violation.
  1414. //
  1415. // Parameters: cr.iip - address of bundle which caused a data access rights fault
  1416. //
  1417. // cr.ipsr - copy of PSR at the time of a data access rights fault
  1418. //
  1419. // cr.idtr - default translation inforamtion for the address that
  1420. // caused the fault
  1421. //
  1422. // cr.ifa - referenced data address that caused the data access rights
  1423. // fault
  1424. //
  1425. // cr.isr - faulting status information
  1426. //
  1427. // Handle: The handler saves the register context and calls MmAccessFault().
  1428. //
  1429. //--
  1430. VECTOR_ENTRY(0x5300, KiDataAccessRightsVector, cr.ifa)
  1431. rva = h24
  1432. rpr = h26
  1433. rIPSR = h27
  1434. rISR = h31
  1435. //
  1436. // check to see if non-present fault occurred on a speculative load.
  1437. // if so, set IPSR.ed bit. This forces to generate a NaT on ld.s after
  1438. // rfi
  1439. //
  1440. mov rpr = pr
  1441. mov rISR = cr.isr // M
  1442. mov rIPSR = cr.ipsr // M
  1443. ;;
  1444. tbit.z pt0, p0 = rISR, ISR_SP // I
  1445. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  1446. (pt0) br.cond.spnt KiCallMemoryFault // B
  1447. ;;
  1448. mov cr.ipsr = rIPSR // M
  1449. ;;
  1450. mov pr = rpr, -1 // I
  1451. rfi // B
  1452. ;;
  1453. VECTOR_EXIT(KiDataAccessRightsVector)
  1454. //--------------------------------------------------------------------
  1455. // Routine:
  1456. //
  1457. // KiGeneralExceptionsVector
  1458. //
  1459. // Description:
  1460. //
  1461. // Interruption vector for General Exceptions
  1462. //
  1463. // On entry:
  1464. // interrupts disabled
  1465. // r16-r31 switched to kernel bank
  1466. //
  1467. // Return value:
  1468. //
  1469. // none
  1470. //
  1471. // Process:
  1472. //--------------------------------------------------------------------
  1473. VECTOR_ENTRY(0x5400, KiGeneralExceptionsVector, cr.isr)
  1474. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiGeneralExceptions)
  1475. //
  1476. // Do not return (rfi from handler)
  1477. //
  1478. VECTOR_EXIT(KiGeneralExceptionsVector)
  1479. //--------------------------------------------------------------------
  1480. // Routine:
  1481. //
  1482. // KiDisabledFpRegisterVector
  1483. //
  1484. // Description:
  1485. //
  1486. // Interruption vector for Disabled FP-register vector
  1487. //
  1488. // On entry:
  1489. // interrupts disabled
  1490. // r16-r31 switched to kernel bank
  1491. //
  1492. // Return value:
  1493. //
  1494. // none
  1495. //
  1496. // Process:
  1497. //--------------------------------------------------------------------
  1498. VECTOR_ENTRY(0x5500, KiDisabledFpRegisterVector, cr.isr)
  1499. mov rHIPSR = cr.ipsr
  1500. mov rHIIP = cr.iip
  1501. cover
  1502. ;;
  1503. mov rHIFS = cr.ifs
  1504. extr.u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN
  1505. mov rHOldPreds = pr
  1506. ;;
  1507. cmp4.eq pKrnl, pUser = PL_KERNEL, rTH1
  1508. ;;
  1509. (pUser) tbit.z.unc pt0, pt1 = rHIPSR, PSR_DFH // if dfh not set,
  1510. // dfl must be set
  1511. (pKrnl) br.spnt.few Kdfrv10 // Kernel mode should never get here.
  1512. ;;
  1513. (pt1) ssm 1 << PSR_IC // set ic bit
  1514. (pt1) mov rHDfhPFS = ar.pfs
  1515. (pt1) mov rHDfhBrp = brp
  1516. ;;
  1517. (pt1) srlz.d
  1518. (pt1) br.call.sptk.many brp = KiRestoreHigherFPVolatile
  1519. (pt0) br.spnt.few Kdfrv10
  1520. ;;
  1521. rsm 1 << PSR_IC // reset ic bit
  1522. dep rHIPSR = 0, rHIPSR, PSR_DFH, 1 // reset dfh bit
  1523. mov brp = rHDfhBrp
  1524. ;;
  1525. srlz.d
  1526. mov cr.ifs = rHIFS
  1527. mov ar.pfs = rHDfhPFS
  1528. mov cr.ipsr = rHIPSR
  1529. mov cr.iip = rHIIP
  1530. mov pr = rHOldPreds, -1
  1531. ;;
  1532. rfi
  1533. ;;
  1534. Kdfrv10:
  1535. mov pr = rHOldPreds, -1
  1536. movl rHHandler = KiGeneralExceptions
  1537. br.sptk KiGenericExceptionHandler
  1538. ;;
  1539. VECTOR_EXIT(KiDisabledFpRegisterVector)
  1540. //--------------------------------------------------------------------
  1541. // Routine:
  1542. //
  1543. // KiNatConsumptionVector
  1544. //
  1545. // Description:
  1546. //
  1547. // Interruption vector for Nat Consumption Vector
  1548. //
  1549. // On entry:
  1550. // interrupts disabled
  1551. // r16-r31 switched to kernel bank
  1552. //
  1553. // Return value:
  1554. //
  1555. // none
  1556. //
  1557. // Process:
  1558. //--------------------------------------------------------------------
  1559. VECTOR_ENTRY(0x5600, KiNatConsumptionVector, cr.isr)
  1560. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiNatExceptions)
  1561. //
  1562. // Do not return (rfi from handler)
  1563. //
  1564. VECTOR_EXIT(KiNatConsumptionVector)
  1565. //++
  1566. //
  1567. // KiSpeculationVector
  1568. //
  1569. // Cause: CHK.S, CHK.A, FCHK detected an exception condition.
  1570. //
  1571. // Parameters: cr.iip - address of bundle which caused a speculation fault
  1572. //
  1573. // cr.ipsr - copy of PSR at the time of a speculation fault
  1574. //
  1575. // cr.iipa - address of bundle containing the last
  1576. // successfully executed instruction
  1577. //
  1578. // cr.iim - contains the immediate value in either
  1579. // CHK.S, CHK.A, or FCHK opecode
  1580. //
  1581. // cr.isr - faulting status information
  1582. //
  1583. // Handle: The handler implements a branch operation to the
  1584. // recovery code specified by the IIM IP-offset.
  1585. //
  1586. // Note: This code will not be exercised until the compiler
  1587. // generates the speculation code.
  1588. //
  1589. // TBD: Need to check for taken branch trap.
  1590. //
  1591. //--
  1592. VECTOR_ENTRY(0x5700, KiSpeculationVector, cr.iim)
  1593. mov h16 = cr.iim // get imm offset
  1594. mov h17 = cr.iip // get IIP
  1595. ;;
  1596. extr h16 = h16, 0, 21 // get sign-extended
  1597. mov h18 = cr.ipsr
  1598. ;;
  1599. shladd h16 = h16, 4, h17 // get addr for recovery handler
  1600. dep h18 = 0, h18, PSR_RI, 2 // zero target slot number
  1601. ;;
  1602. mov cr.ipsr = h18
  1603. mov cr.iip = h16
  1604. ;;
  1605. rfi
  1606. ;;
  1607. VECTOR_EXIT(KiSpeculationVector)
  1608. //++
  1609. //
  1610. // KiDebugFaultVector
  1611. //
  1612. // Cause: A unaligned data access fault has occured
  1613. //
  1614. // Parameters: cr.iip - address of bundle causing the fault.
  1615. //
  1616. // cr.ipsr - copy of PSR at the time of interruption.
  1617. //
  1618. // cr.iipa - address of bundle containing the last
  1619. // successfully executed instruction
  1620. //
  1621. // cr.isr - faulting status information. ISR.ei bits are
  1622. // set to indicate which instruction caused the
  1623. // exception.
  1624. // The ISR.code contains information about the
  1625. // FP exception fault. See trapc.c and the EAS
  1626. //
  1627. //--
  1628. VECTOR_ENTRY(0x5900, KiDebugFaultVector, cr.isr)
  1629. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiDebugFault)
  1630. //
  1631. // Do not return (rfi from handler)
  1632. //
  1633. VECTOR_EXIT(KiDebugFaultVector)
  1634. //++
  1635. //
  1636. // KiUnalignedFaultVector
  1637. //
  1638. // Cause: A unaligned data access fault has occured
  1639. //
  1640. // Parameters: cr.iip - address of bundle causing the fault.
  1641. //
  1642. // cr.ipsr - copy of PSR at the time of interruption.
  1643. //
  1644. // cr.iipa - address of bundle containing the last
  1645. // successfully executed instruction
  1646. //
  1647. // cr.isr - faulting status information. ISR.ei bits are
  1648. // set to indicate which instruction caused the
  1649. // exception.
  1650. // The ISR.code contains information about the
  1651. // FP exception fault. See trapc.c and the EAS
  1652. //
  1653. //--
  1654. VECTOR_ENTRY(0x5a00, KiUnalignedFaultVector, cr.ifa)
  1655. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiUnalignedFault)
  1656. //
  1657. // Do not return (rfi from handler)
  1658. //
  1659. VECTOR_EXIT(KiUnalignedFaultVector)
  1660. //++
  1661. //
  1662. // KiFloatFaultVector
  1663. //
  1664. // Cause: A floating point fault has occured
  1665. //
  1666. // Parameters: cr.iip - address of bundle causing the fault.
  1667. //
  1668. // cr.ipsr - copy of PSR at the time of interruption.
  1669. //
  1670. // cr.iipa - address of bundle containing the last
  1671. // successfully executed instruction
  1672. //
  1673. // cr.isr - faulting status information. ISR.ei bits are
  1674. // set to indicate which instruction caused the
  1675. // exception.
  1676. // The ISR.code contains information about the
  1677. // FP exception fault. See trapc.c and the EAS
  1678. //
  1679. //--
  1680. VECTOR_ENTRY(0x5c00, KiFloatFaultVector, cr.isr)
  1681. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiFloatFault)
  1682. //
  1683. // Do not return (rfi from handler)
  1684. //
  1685. VECTOR_EXIT(KiFloatFaultVector)
  1686. //++
  1687. //
  1688. // KiFloatTrapVector
  1689. //
  1690. // Cause: A floating point trap has occured
  1691. //
  1692. // Parameters: cr.iip - address of bundle with the instruction to be
  1693. // executed next.
  1694. //
  1695. // cr.ipsr - copy of PSR at the time of interruption.
  1696. //
  1697. // cr.iipa - address of bundle containing the last
  1698. // successfully executed instruction
  1699. //
  1700. // cr.isr - faulting status information. ISR.ei bits are
  1701. // set to indicate which instruction caused the
  1702. // exception.
  1703. // The ISR.code contains information about the
  1704. // FP trap. See trapc.c and the EAS
  1705. //
  1706. //--
  1707. VECTOR_ENTRY(0x5d00, KiFloatTrapVector, cr.isr)
  1708. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiFloatTrap)
  1709. //
  1710. // Do not return (rfi from handler)
  1711. //
  1712. VECTOR_EXIT(KiFloatTrapVector)
  1713. //++
  1714. //
  1715. // KiLowerPrivilegeVector
  1716. //
  1717. // Cause: A branch lowers the privilege level and PSR.lp is 1.
  1718. // Or an attempt made to execute an instruction
  1719. // in the unimplemented address space.
  1720. // This trap is higher priority than taken branch
  1721. // or single step traps.
  1722. //
  1723. // Parameters: cr.iip - address of bundle containing the instruction to
  1724. // be executed next.
  1725. //
  1726. // cr.ipsr - copy of PSR at the time of interruption.
  1727. //
  1728. // cr.iipa - address of bundle containing the last
  1729. // successfully executed instruction
  1730. //
  1731. // cr.isr - faulting status information. The ISR.code
  1732. // contains a bit vector for all traps which
  1733. // occurred in the trapping bundle.
  1734. //
  1735. //--
  1736. VECTOR_ENTRY(0x5e00, KiLowerPrivilegeVector, cr.iipa)
  1737. mov rHISR = cr.isr
  1738. mov rHOldPreds = pr
  1739. mov rHIIPA = cr.iipa
  1740. mov rHIPSR = cr.ipsr
  1741. ;;
  1742. tbit.z pt1, pt0 = rHISR, ISR_UI_TRAP
  1743. (pt1) br.cond.spnt Klpv10
  1744. ;;
  1745. mov rHIFA = cr.iip
  1746. movl rHHandler = KiUnimplementedAddressTrap
  1747. mov pr = rHOldPreds, -2 // must restore predicates
  1748. br.sptk KiGenericExceptionHandler
  1749. ;;
  1750. Klpv10:
  1751. mov rPanicCode = UNEXPECTED_KERNEL_MODE_TRAP
  1752. br.sptk KiPanicHandler
  1753. VECTOR_EXIT(KiLowerPrivilegeVector)
  1754. //++
  1755. //
  1756. // KiTakenBranchVector
  1757. //
  1758. // Cause: A taken branch was successfully execcuted and the PSR.tb
  1759. // bit is 1. This trap is higher priority than single step trap.
  1760. //
  1761. // Parameters: cr.iip - address of bundle containing the instruction to
  1762. // be executed next.
  1763. //
  1764. // cr.ipsr - copy of PSR at the time of interruption.
  1765. //
  1766. // cr.iipa - address of bundle containing the last
  1767. // successfully executed instruction
  1768. //
  1769. // cr.isr - faulting status information. The ISR.code
  1770. // contains a bit vector for all traps which
  1771. // occurred in the trapping bundle.
  1772. //
  1773. //--
  1774. VECTOR_ENTRY(0x5f00, KiTakenBranchVector, cr.iipa)
  1775. mov rHIPSR = cr.ipsr
  1776. movl rHEPCVa = MM_EPC_VA+0x20 // user system call entry point
  1777. mov rHIIP = cr.iip
  1778. movl rHpT1 = KiPcr+PcInitialStack
  1779. ;;
  1780. ld8 rHpT1 = [rHpT1]
  1781. extr.u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN
  1782. mov rHOldPreds = pr
  1783. ;;
  1784. cmp.eq pt0 = rHEPCVa, rHIIP
  1785. movl rHHandler = KiSingleStep
  1786. ;;
  1787. (pt0) ssm 1 << PSR_IC
  1788. (pt0) movl rHpT3 = 1 << PSR_LP
  1789. ;;
  1790. (pt0) or rHpT3 = rHIPSR, rHpT3
  1791. (pt0) srlz.d
  1792. add rHpT1=-ThreadStateSaveAreaLength-TrapFrameLength+TrStIPSR,rHpT1
  1793. (pt0) br.spnt.few Ktbv10
  1794. mov pr = rHOldPreds, -2
  1795. br.sptk KiGenericExceptionHandler
  1796. ;;
  1797. Ktbv10:
  1798. st8 [rHpT1] = rHpT3
  1799. movl rHpT3 = 1 << PSR_SS | 1 << PSR_TB | 1 << PSR_DB
  1800. ;;
  1801. rsm 1 << PSR_IC
  1802. mov pr = rHOldPreds, -2
  1803. andcm rHIPSR = rHIPSR, rHpT3 // clear ss, tb, db bits
  1804. ;;
  1805. srlz.d
  1806. mov cr.ipsr = rHIPSR
  1807. ;;
  1808. rfi
  1809. ;;
  1810. VECTOR_EXIT(KiTakenBranchVector)
  1811. //++
  1812. //
  1813. // KiSingleStepVector
  1814. //
  1815. // Cause: An instruction was successfully execcuted and the PSR.ss
  1816. // bit is 1.
  1817. //
  1818. // Parameters: cr.iip - address of bundle containing the instruction to
  1819. // be executed next.
  1820. //
  1821. // cr.ipsr - copy of PSR at the time of interruption.
  1822. //
  1823. // cr.iipa - address of bundle containing the last
  1824. // successfully executed instruction
  1825. //
  1826. // cr.isr - faulting status information. The ISR.code
  1827. // contains a bit vector for all traps which
  1828. // occurred in the trapping bundle.
  1829. //
  1830. //--
  1831. VECTOR_ENTRY(0x6000, KiSingleStepVector, cr.iipa)
  1832. mov rHIPSR = cr.ipsr
  1833. movl rHEPCVa = MM_EPC_VA+0x20 // user system call entry point
  1834. mov rHIIP = cr.iip
  1835. movl rHpT1 = KiPcr+PcInitialStack
  1836. ;;
  1837. ld8 rHpT1 = [rHpT1]
  1838. extr.u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN
  1839. mov rHOldPreds = pr
  1840. ;;
  1841. cmp.eq pt0 = rHEPCVa, rHIIP
  1842. movl rHHandler = KiSingleStep
  1843. ;;
  1844. (pt0) ssm 1 << PSR_IC
  1845. (pt0) movl rHpT3 = 1 << PSR_LP
  1846. ;;
  1847. (pt0) or rHpT3 = rHIPSR, rHpT3
  1848. (pt0) srlz.d
  1849. add rHpT1=-ThreadStateSaveAreaLength-TrapFrameLength+TrStIPSR,rHpT1
  1850. (pt0) br.spnt.few Kssv10
  1851. mov pr = rHOldPreds, -2
  1852. br.sptk KiGenericExceptionHandler
  1853. ;;
  1854. Kssv10:
  1855. st8 [rHpT1] = rHpT3
  1856. movl rHpT3 = 1 << PSR_SS | 1 << PSR_DB
  1857. ;;
  1858. rsm 1 << PSR_IC
  1859. mov pr = rHOldPreds, -2
  1860. andcm rHIPSR = rHIPSR, rHpT3 // clear ss, db bits
  1861. ;;
  1862. srlz.d
  1863. mov cr.ipsr = rHIPSR
  1864. ;;
  1865. rfi
  1866. ;;
  1867. VECTOR_EXIT(KiSingleStepVector)
  1868. //++
  1869. //
  1870. // KiIA32ExceptionVector
  1871. //
  1872. // Cause: A fault or trap was generated while executing from the
  1873. // iA-32 instruction set.
  1874. //
  1875. // Parameters: cr.iip - address of the iA-32 instruction causing interruption
  1876. //
  1877. // cr.ipsr - copy of PSR at the time of the instruction
  1878. //
  1879. // cr.iipa - Address of the last successfully executed
  1880. // iA-32 or EM instruction
  1881. //
  1882. // cr.isr - The ISR.ei exception indicator is cleared.
  1883. // ISR.iA_vector contains the iA-32 interruption vector
  1884. // number. ISR.code contains the iA-32 16-bit error cod
  1885. //
  1886. // Handle: Save the whole register state and
  1887. // call KiIA32ExceptionVectorHandler()().
  1888. //
  1889. //--
  1890. VECTOR_ENTRY(0x6900, KiIA32ExceptionVector, r0)
  1891. mov rHIIM = cr.iim // save info from IIM
  1892. movl rTH1 = KiPcr+PcSavedIIM
  1893. ;;
  1894. st8 [rTH1] = rHIIM
  1895. VECTOR_CALL_HANDLER(KiGenericExceptionHandler,
  1896. KiIA32ExceptionVectorHandler)
  1897. VECTOR_EXIT(KiIA32ExceptionVector)
  1898. //++
  1899. //
  1900. // KiIA32InterceptionVector
  1901. //
  1902. // Cause: A interception fault or trap was generated while executing
  1903. // from the iA-32 instruction set.
  1904. //
  1905. // Parameters: cr.iip - address of the iA-32 instruction causing interruption
  1906. //
  1907. // cr.ipsr - copy of PSR at the time of the instruction
  1908. //
  1909. // cr.iipa - Address of the last successfully executed
  1910. // iA-32 or EM instruction
  1911. //
  1912. // cr.isr - The ISR.ei exception indicator is cleared.
  1913. // ISR.iA_vector contains the iA-32 interruption vector
  1914. // number. ISR.code contains the iA-32specific
  1915. // interception information
  1916. //
  1917. // Handle: Save the whole register state and
  1918. // call KiIA32InterceptionVectorHandler()().
  1919. //
  1920. //--
  1921. VECTOR_ENTRY(0x6a00, KiIA32InterceptionVector, r0)
  1922. mov rHIIM = cr.iim // save info from IIM
  1923. movl rTH1 = KiPcr+PcSavedIIM
  1924. ;;
  1925. st8 [rTH1] = rHIIM
  1926. VECTOR_CALL_HANDLER(KiGenericExceptionHandler,
  1927. KiIA32InterceptionVectorHandler)
  1928. VECTOR_EXIT(KiIA32InterceptionVector)
  1929. //++
  1930. //
  1931. // KiIA32InterruptionVector
  1932. //
  1933. // Cause: An iA software interrupt was executed
  1934. //
  1935. // Parameters: cr.iip - address of the iA-32 instruction causing interruption
  1936. //
  1937. // cr.ipsr - copy of PSR at the time of the instruction
  1938. //
  1939. // cr.iipa - Address of the last successfully executed
  1940. // iA-32 or EM instruction
  1941. //
  1942. // cr.isr - ISR.iA_vector contains the iA-32 defined vector
  1943. // number. ISR.code contains 0
  1944. // ISR.ei excepting instruction indicator is cleared.
  1945. // ISR.iA_vector contains the iA-32 instruction vector.
  1946. // ISR.code contains iA-32 specific information.
  1947. //
  1948. // Handle: Save the whole register state and
  1949. // call KiIA32InterruptionVectorHandler()().
  1950. //
  1951. //--
  1952. VECTOR_ENTRY(0x6b00, KiIA32InterruptionVector, r0)
  1953. // This one doesn't need IIM, so we won't bother to save it
  1954. VECTOR_CALL_HANDLER(KiGenericExceptionHandler,
  1955. KiIA32InterruptionVectorHandler)
  1956. VECTOR_EXIT(KiIA32InterruptionVector)
  1957. //
  1958. // All non-VECTOR_ENTRY functions must follow KiNormalSystemCall.
  1959. //
  1960. // N.B. KiNormalSystemCall must be the first function body in the .nsc
  1961. // section.
  1962. //
  1963. //--------------------------------------------------------------------
  1964. // Routine:
  1965. //
  1966. // KiNormalSystemCall
  1967. //
  1968. // Description:
  1969. //
  1970. // Handler for normal (not fast) system calls
  1971. //
  1972. // On entry:
  1973. //
  1974. // ic off
  1975. // interrupts disabled
  1976. // v0: contains sys call #
  1977. // cover done by call
  1978. // r32-r39: sys call arguments
  1979. // CFM: sof = # args, ins = 0, outs = # args
  1980. // clear mfh bit (high fp registers are scratch per s/w convention)
  1981. //
  1982. // Return value:
  1983. //
  1984. // v0: system call return value
  1985. //
  1986. // Process:
  1987. //
  1988. //--------------------------------------------------------------------
  1989. .section .drectve, "MI", "progbits"
  1990. string " -section:.nsc,,align=0x2000"
  1991. .section .nsc = "ax", "progbits"
  1992. HANDLER_ENTRY_EX(KiNormalSystemCall, KiSystemServiceHandler)
  1993. .prologue
  1994. .unwabi @nt, EXCEPTION_FRAME
  1995. rPFS = t0
  1996. rThread = t1 // current thread
  1997. rIFS = t1
  1998. rIIP = t2
  1999. rPreds = t3
  2000. rIPSR = t4
  2001. rUNAT = t5
  2002. rSp = t6
  2003. rpT1 = t7
  2004. rpT2 = t8
  2005. rpT3 = t9
  2006. rpT4 = t10
  2007. rT0 = t11
  2008. rT1 = t12
  2009. rT2 = t13
  2010. rT3 = t14
  2011. rT4 = t15
  2012. rKDbgActive = t16
  2013. rIntNats = t17
  2014. rpSd = t16 /* -> service descriptor entry */
  2015. rSdOffset = t17 /* service descriptor offset */
  2016. rArgTable = t18 /* pointer to argument table */
  2017. rArgNum = t20 /* number of arguments */
  2018. rRscD = t16
  2019. rRNAT = t17
  2020. rRscE = t18
  2021. rKBSPStore = t18
  2022. rBSPStore = t19
  2023. rRscDelta = t20
  2024. rBSP = t21
  2025. rPreviousMode = t22
  2026. pInvl = ps9 /* pInvl = not GUI service */
  2027. pVal = pt1
  2028. pGui = pt2 /* true if GUI call */
  2029. pNoGui = pt3 /* true if no GUI call */
  2030. pNatedArg = pt4 /* true if any input argument */
  2031. /* register is Nat'ed */
  2032. pNoCopy = pt5 /* no in-memory arguments to copy */
  2033. pCopy = pt6
  2034. pNatedSp = pt7
  2035. mov rUNAT = ar.unat
  2036. tnat.nz pNatedSp = sp
  2037. mov rPreviousMode = KernelMode
  2038. mov rIPSR = psr
  2039. rsm 1 << PSR_I | 1 << PSR_MFH
  2040. br.sptk Knsc_Allocate
  2041. ;;
  2042. //
  2043. // N.B. KiUserSystemCall is at an offset of 0x20 from KiNormalSystemCall.
  2044. // Whenever this offset is changed, the definition of kernel system call
  2045. // stub in services.stb must be updated to reflect the new value.
  2046. //
  2047. ALTERNATE_ENTRY(KiUserSystemCall)
  2048. mov rUNAT = ar.unat
  2049. mov rPreviousMode = UserMode
  2050. epc
  2051. ;;
  2052. mov rIPSR = psr
  2053. rsm (1 << PSR_I) | (1 << PSR_BE)
  2054. tnat.nz pNatedSp = sp
  2055. ;; // stop bit needed to ensure interrupt is off
  2056. Knsc_Allocate::
  2057. #if defined(INTERRUPTION_LOGGING)
  2058. // For Conditional Interrupt Logging
  2059. mov rT3 = gp
  2060. movl gp = _gp
  2061. ;;
  2062. add rpT1 = @gprel(KiVectorLogMask), gp
  2063. ;;
  2064. ld8 rT1 = [rpT1]
  2065. mov gp = rT3
  2066. ;;
  2067. tbit.z pt1 = rT1, UserSystemcallBit
  2068. (pt1) br.cond.sptk EndOfLogging1
  2069. mov rT1 = 0x80 // dummy offset for sys call
  2070. movl rpT1 = KiPcr+PcInterruptionCount
  2071. mov rT2 = b0
  2072. mov rT3 = MAX_NUMBER_OF_IHISTORY_RECORDS - 1
  2073. ;;
  2074. ld4.nt1 rT4 = [rpT1] // get current count
  2075. or rT1 = rT1, rPreviousMode // kernel/user
  2076. ;;
  2077. add rT0 = 1, rT4 // incr count
  2078. and rT4 = rT3, rT4 // index of current entry
  2079. add rpT2 = 0x1000-PcInterruptionCount, rpT1 // base of history
  2080. ;;
  2081. st4.nta [rpT1] = rT0 // save count
  2082. shl rT4 = rT4, 5 // offset of current entry
  2083. ;;
  2084. add rpT2 = rpT2, rT4 // address of current entry
  2085. ;;
  2086. st8 [rpT2] = rT1, 8 // save sys call offset
  2087. ;;
  2088. st8 [rpT2] = rT2, 8 // save return address
  2089. ;;
  2090. st8 [rpT2] = rIPSR, 8 // save psr
  2091. ;;
  2092. st8 [rpT2] = v0; // save sys call number
  2093. ;;
  2094. // For Conditional Interrupt Logging
  2095. EndOfLogging1:
  2096. #endif // INTERRUPTION_LOGGING
  2097. //
  2098. // if sp is Nat'ed return to caller with an error status
  2099. // N.B. sp is not spilled and a value of zero is saved in the IntNats field
  2100. //
  2101. mov rT1 = cr.dcr
  2102. movl rpT4 = KiPcr+PcInitialStack
  2103. mov rSp = sp
  2104. (pNatedSp) movl rT4 = Knsc_ErrorReturn
  2105. ;;
  2106. mov rPreds = pr
  2107. nop.f 0
  2108. cmp.eq pUser, pKrnl = UserMode, rPreviousMode
  2109. mov rBSP = ar.bsp
  2110. (pNatedSp) movl v0 = STATUS_IA64_INVALID_STACK
  2111. ;;
  2112. (pUser) ld8 sp = [rpT4], PcInitialBStore-PcInitialStack // set new sp
  2113. mov rIIP = brp
  2114. mov rPFS = ar.pfs
  2115. ;;
  2116. mov rT2 = ar.rsc
  2117. (pUser) ld8 rKBSPStore = [rpT4], PcKernelDebugActive-PcInitialBStore
  2118. (pNatedSp) mov bt0 = rT4
  2119. ;;
  2120. (pUser) ld1 rKDbgActive = [rpT4], PcCurrentThread-PcKernelDebugActive
  2121. (pKrnl) add rpT4 = PcCurrentThread-PcInitialStack, rpT4
  2122. extr rIFS = rPFS, 0, 38
  2123. mov rT0 = ar.fpsr
  2124. (pUser) movl rT3 = 1 << PSR_SS | 1 << PSR_DB | 1 << PSR_TB | 1 << PSR_LP
  2125. (pUser) mov ar.rsc = r0 // put RSE in lazy mode
  2126. (pUser) add sp = -ThreadStateSaveAreaLength-TrapFrameLength, sp
  2127. (pKrnl) add sp = -TrapFrameLength, sp // allocate TF
  2128. ;;
  2129. (pUser) mov rBSPStore = ar.bspstore // get user bsp store point
  2130. add rpT1 = TrStIPSR, sp // -> IPSR
  2131. add rpT2 = TrIntSp, sp // -> IntSp
  2132. ;;
  2133. (pUser) ld8 rT4 = [rpT1]
  2134. st8 [rpT2] = rSp, TrApUNAT-TrIntSp // sp is not Nat'ed
  2135. add rpT3 = TrStIFS, sp // -> IFS
  2136. dep rIFS = 1, rIFS, 63, 1 // set IFS.v
  2137. ;;
  2138. st8 [rpT2] = rUNAT, TrApDCR-TrApUNAT
  2139. st8 [rpT3] = rIFS, TrRsPFS-TrStIFS // save IFS
  2140. (pUser) and rT4 = rT3, rT4 // capture psr.db, tb, ss
  2141. ;;
  2142. st8 [rpT2] = rT1, TrPreds-TrApDCR
  2143. st8.nta [rpT3] = rPFS, TrStFPSR-TrRsPFS // save PFS
  2144. (pUser) mov rT3 = rIPSR
  2145. rBspOff = t5
  2146. extr.u rBspOff = rBSP, 0, 9
  2147. extr.u t0 = rIFS, 0, 7
  2148. extr.u rIFS = rIFS, 7, 7
  2149. ;;
  2150. (pUser) mov rRNAT = ar.rnat
  2151. movl rT1 = 1 << PSR_I | 1 << PSR_MFH | 1 << PSR_BE
  2152. sub rIFS = t0, rIFS
  2153. movl t0 = 1 << PSR_I | 1 << PSR_BN
  2154. ;;
  2155. st8 [rpT2] = rPreds, TrIntNats-TrPreds
  2156. (pUser) or rIPSR = rIPSR, rT4
  2157. (pUser) cmp.ne.unc pKDbg, pt2 = zero, rKDbgActive // kernel debug active?
  2158. shladd rBspOff = rIFS, 3, rBspOff
  2159. shladd rBSP = rIFS, 3, rBSP
  2160. mov rIFS = 0x1F8
  2161. (pUser) dep t0 = 1, t0, PSR_CPL, 2
  2162. ;;
  2163. st8 [rpT2] = zero,TrIntGp-TrIntNats // all integer Nats are 0
  2164. st8 [rpT3] = rT0, TrStIIP-TrStFPSR // save FPSR
  2165. (pUser) andcm rT3 = rT3, rT1 // clear i, mfh, be
  2166. cmp.ge pt0 = rBspOff, rIFS
  2167. or rIPSR = t0, rIPSR // set i, cpl, bn for the saved IPSR
  2168. ;;
  2169. st8 [rpT1] = rIPSR // save IPSR
  2170. st8 [rpT3] = rIIP, TrBrRp-TrStIIP // save IIP
  2171. (pt2) dep rT3 = 0, rT3, PSR_DB, 1 // disable db in kernel
  2172. ;;
  2173. st8.nta [rpT3] = rIIP, TrRsBSP-TrBrRp // save BRP
  2174. st8 [rpT2] = gp // Save GP even though it is a temporary
  2175. // If someone does a get/set context and GP
  2176. // is zero in the trap fram then set context
  2177. // will think IIP is a plabel and dereference
  2178. // it.
  2179. (pUser) dep rT3 = 1, rT3, PSR_AC, 1 // enable alignment check
  2180. ;;
  2181. add rpT2 = TrRsRSC, sp
  2182. (pt0) add rBSP = 8, rBSP
  2183. (pUser) mov psr.l = rT3
  2184. ;;
  2185. st8 [rpT3] = rBSP, TrRsBSPSTORE-TrRsBSP
  2186. (pUser) sub rBSP = rBSP, rBSPStore
  2187. ;;
  2188. (pUser) st8 [rpT3] = rBSPStore // save user BSP Store
  2189. (pUser) dep rT2 = rBSP, rT2, RSC_MBZ1, RSC_LOADRS_LEN
  2190. (pUser) mov teb = kteb // get Teb pointer
  2191. movl rT1 = Knsc10 // Leave the EPC page
  2192. ;;
  2193. st8 [rpT2] = rT2, TrRsRNAT-TrRsRSC // save RSC
  2194. (pUser) dep rKBSPStore = rBSPStore, rKBSPStore, 0, 9
  2195. mov b6 = rT1 // Addres of Knsc10 in KSEG0.
  2196. ;;
  2197. (pUser) mov ar.bspstore = rKBSPStore // switch to kernel BSP
  2198. movl gp = _gp // set up kernel gp
  2199. ;;
  2200. (pUser) mov ar.rsc = RSC_KERNEL // turn rse on, in kernel mode
  2201. (pUser) st8 [rpT2] = rRNAT // save RNAT in trap frame
  2202. // for user backing store
  2203. (pNatedSp) br.spnt bt0
  2204. br.sptk b6
  2205. ;;
  2206. Knsc10:
  2207. //
  2208. // Now running with user banked registers and on kernel backing store
  2209. //
  2210. // Can now take TLB faults
  2211. //
  2212. // Preserve the output args (as in's) in the local frame until it's ready to
  2213. // call the specified system service because other calls may have to be made
  2214. // before that. Also allocate locals and one out.
  2215. //
  2216. //
  2217. // Register aliases for rest of procedure
  2218. //
  2219. .regstk 8, 9, 3, 0
  2220. rScallGp = loc0
  2221. rpThObj = loc1 // pointer to thread object
  2222. rSavedV0 = loc2 // saved v0 for GUI thread
  2223. rpEntry = loc3 // syscall routine entry point
  2224. rSnumber = loc4 // service number
  2225. rArgEntry = loc5
  2226. rCount = loc6 /* index of the first Nat'ed input register */
  2227. rUserSp = loc7
  2228. rUserPFS = loc8
  2229. rArgBytes = out2
  2230. //
  2231. // the following code uses the predicates to determine the first of
  2232. // the 8 input argument register whose Nat bit is set. The result
  2233. // is saved in register rCount and used to determine whether to fail
  2234. // the system call in Knsc_CheckArguments.
  2235. //
  2236. alloc rUserPFS = 8, 9, 3, 0
  2237. ld8 rpThObj = [rpT4]
  2238. mov rUserSp = rSp
  2239. add rpT1 = TrEOFMarker, sp
  2240. movl rT1 = FPSR_FOR_KERNEL // initial fpsr value
  2241. ;;
  2242. mov ar.fpsr = rT1 // set fpsr
  2243. movl rT3 = KTRAP_FRAME_EOF | EXCEPTION_FRAME
  2244. ;;
  2245. st8 [rpT1] = rT3
  2246. mov loc0 = pr // save local predicates
  2247. ;;
  2248. mov pr = zero, -1
  2249. add rpT2 = ThServiceTable, rpThObj
  2250. add rpT3 = ThTrapFrame, rpThObj
  2251. ;;
  2252. lfetch [rpT2]
  2253. ld8 rT4 = [rpT3], ThPreviousMode-ThTrapFrame
  2254. cmp.eq p1 = r32, r32
  2255. cmp.eq p9 = r33, r33
  2256. cmp.eq p17 = r34, r34
  2257. cmp.eq p25 = r35, r35
  2258. cmp.eq p33 = r36, r36
  2259. cmp.eq p41 = r37, r37
  2260. cmp.eq p49 = r38, r38
  2261. cmp.eq p57 = r39, r39
  2262. mov rSavedV0 = v0 // save syscall # across call
  2263. ;;
  2264. ld1 rT0 = [rpT3] // rT0 = thread's previous mode
  2265. mov rT1 = pr
  2266. add rpT1 = TrTrapFrame, sp // -> TrTrapFrame
  2267. ;;
  2268. st1 [rpT3] = rPreviousMode // set new thread previous mode
  2269. mov pr = loc0, -1 // restore local predicates
  2270. dep rT1 = 0, rT1, 0, 1 // clear bit 0
  2271. ;;
  2272. st8 [rpT1] = rT4, TrPreviousMode-TrTrapFrame
  2273. czx1.r rCount = rT1 // determine which arg is Nat'ed
  2274. ;;
  2275. st4 [rpT1] = rT0
  2276. FAST_ENABLE_INTERRUPTS
  2277. (pKDbg) br.call.spnt brp = KiLoadKernelDebugRegisters
  2278. ;;
  2279. PROLOGUE_END
  2280. //
  2281. // If the specified system service number is not within range, then
  2282. // attempt to convert the thread to a GUI thread and retry the service
  2283. // dispatch.
  2284. //
  2285. // N.B. The system call arguments, the system service entry point (rpEntry),
  2286. // the service number (Snumber)
  2287. // are implicitly preserved in the register stack while attempting to
  2288. // convert the thread to a GUI thread. v0 and the gp must be preserved
  2289. // explicitly.
  2290. //
  2291. // Validate sys call number
  2292. //
  2293. ALTERNATE_ENTRY(KiSystemServiceRepeat)
  2294. add rpT1 = ThTrapFrame, rpThObj // rpT1 -> ThTrapFrame
  2295. add rpT2 = ThServiceTable,rpThObj // rpT2 -> ThServiceTable
  2296. shr.u rT2 = rSavedV0, SERVICE_TABLE_SHIFT // isolate service descriptor offset
  2297. ;;
  2298. st8 [rpT1] = sp // set trap frame address
  2299. ld8 rT3 = [rpT2] // -> service descriptor table
  2300. and rSdOffset = SERVICE_TABLE_MASK, rT2
  2301. ;;
  2302. cmp4.ne pNoGui, pGui = SERVICE_TABLE_TEST, rSdOffset // check if GUI system service
  2303. add rpT1 = TeGdiBatchCount, teb
  2304. mov rSnumber = SERVICE_NUMBER_MASK
  2305. ;;
  2306. (pGui) lfetch [rpT1]
  2307. add rT2 = rSdOffset, rT3 // rT2 -> service descriptor
  2308. ;;
  2309. add rpSd = SdLimit, rT2 // rpSd -> table limit
  2310. ;;
  2311. ld4 rT1 = [rpSd], SdTableBaseGpOffset-SdLimit // rT1 = table limit
  2312. ;;
  2313. ld4 rScallGp = [rpSd], SdBase-SdTableBaseGpOffset
  2314. and rSnumber = rSnumber, rSavedV0 // rSnumber = service number
  2315. ;;
  2316. ld8 rT4 = [rpSd], SdNumber-SdBase // rT4 = table base
  2317. ;;
  2318. ld8 rArgTable = [rpSd] // -> arg table
  2319. sxt4 rScallGp = rScallGp // sign-extend offset
  2320. ;;
  2321. cmp4.ltu pt1, pt0 = rSnumber, rT1 // pt1 = number < limit
  2322. shladd rpT3 = rSnumber, 3, rT4 // -> entry point address
  2323. add rScallGp = rT4, rScallGp // compute syscall gp
  2324. ;;
  2325. (pt1) ld8 rpEntry = [rpT3] // -> sys call routine plabel
  2326. add rArgEntry = rSnumber, rArgTable // -> # arg bytes
  2327. (pt1) cmp4.ne.unc pNoGui, pGui = SERVICE_TABLE_TEST, rSdOffset
  2328. (pNoGui) br.dptk Knsc_NotGUI // Not a GUI thread
  2329. (pGui) br.dpnt Knsc_GUI // GUI thread
  2330. ;;
  2331. //
  2332. // If rSdOffset == SERVICE_TABLE_TEST then service number is GUI service
  2333. //
  2334. cmp.ne pInvl, pVal = SERVICE_TABLE_TEST, rSdOffset
  2335. mov v0 = 1
  2336. (pVal) br.call.sptk brp = PsConvertToGuiThread
  2337. ;;
  2338. cmp4.eq pVal, p0 = 0, v0 // pVal = 1, if successful
  2339. movl v0 = STATUS_INVALID_SYSTEM_SERVICE // invalid, if not successful
  2340. ;;
  2341. add rpT1 = @gprel(KeServiceDescriptorTableShadow),gp // Load address of table of shadow table
  2342. (pVal) br.sptk KiSystemServiceRepeat // br if successful
  2343. (pInvl) br.spnt Knsc_ErrorReturn // br to KiSystemServiceExit if
  2344. ;; // system call out of range
  2345. //
  2346. // The conversion to a Gui thread failed. The correct return value is encoded
  2347. // in a byte table indexed by the service number that is at the end of the
  2348. // service address table. The encoding is as follows:
  2349. //
  2350. // 0 - return 0.
  2351. // -1 - return -1.
  2352. // 1 - return status code.
  2353. //
  2354. add rpT1 = SERVICE_TABLE_TEST, rpT1 // Get addr of the GUI table
  2355. ;;
  2356. ld8 rpT2 = [rpT1], SdLimit - SdBase // Get the table base.
  2357. ;;
  2358. ld4 rT1 = [rpT1] // Get the limit.
  2359. add rpT2 = rpT2, rSnumber // Index by the server number to the correct byte.
  2360. ;;
  2361. shladd rpT2 = rT1, 3, rpT2 // Calculate the end of the table.
  2362. cmp4.ltu pt1, pt0 = rSnumber, rT1 // pt1 = number < limit
  2363. ;; // pt1 == 0 implies return an ntstatus.
  2364. (pt1) ld1 rT1 = [rpT2] // Load the flag byte if within table
  2365. ;;
  2366. sxt1 rT2 = rT1 // Sign extend the result
  2367. (pt1) cmp.eq pt0, pt1 = 1, rT1 // Test for 1 which means return STATUS_INVALID_SYSTEM_SERVICE
  2368. ;;
  2369. (pt1) mov v0 = rT2 // Use the flag value if needed.
  2370. br.sptk Knsc_ErrorReturn // br to KiSystemServiceExit
  2371. ;;
  2372. Knsc_GUI:
  2373. //
  2374. // If the system service is a GUI service and the GDI user batch queue is
  2375. // not empty, then call the appropriate service to flush the user batch.
  2376. //
  2377. add rpT1 = TeGdiBatchCount, teb // get number of batched calls
  2378. mov rSavedV0 = rpSd // save service descriptor
  2379. ;;
  2380. ld4.s rT1 = [rpT1]
  2381. add rpT3 = @gprel(KeGdiFlushUserBatch), gp
  2382. ;;
  2383. cmp4.ne pGui = rT1, zero // skip if no calls
  2384. tnat.nz pNoGui = rT1 // pGui will be zero if rT1 is Nat
  2385. ;;
  2386. (pGui) ld8 rpT1 = [rpT3] // get KeGdiFlushUserBatch()
  2387. movl rpT2 = Knsc_GUI_Return
  2388. ;;
  2389. (pGui) ld8 rT1 = [rpT1], PlGlobalPointer-PlEntryPoint // get entry point
  2390. mov brp = rpT2
  2391. (pNoGui)br.call.spnt bt0=KiTestGdiBatchCount // This will return to Knsc_GUI_Return
  2392. ;;
  2393. (pGui) ld8 gp = [rpT1] // set global pointer
  2394. (pGui) mov bt0 = rT1
  2395. (pGui) br.call.sptk brp = bt0 // call to KeGdiFlushUserBatch
  2396. ;;
  2397. Knsc_GUI_Return:
  2398. #if DBG
  2399. mov rpSd = rSavedV0 // restore service descriptor
  2400. ;;
  2401. #endif
  2402. //
  2403. // Check for Nat'ed input argument register and
  2404. // Copy in-memory arguments from caller stack to kernel stack
  2405. //
  2406. Knsc_NotGUI:
  2407. #if DBG // checked build code
  2408. add rpT1 = SdCount-SdNumber, rpSd // rpT1 -> count table address
  2409. ;;
  2410. ld8 rpT2 = [rpT1] // service count table address
  2411. ;;
  2412. cmp.ne pt0 = rpT2, zero // if zero, no table defined
  2413. shladd rpT3 = rSnumber, 2, rpT2 // compute service count address
  2414. ;;
  2415. (pt0) ld4 rT1 = [rpT3] // increment count
  2416. ;;
  2417. (pt0) add rT1 = 1, rT1
  2418. ;;
  2419. (pt0) st4 [rpT3] = rT1 // store result
  2420. #endif // DBG
  2421. tbit.z pt0, pt1 = rpEntry, 0
  2422. extr.u rArgNum = rpEntry, 1, 3 // extract # of arguments
  2423. dep rpEntry = 0, rpEntry, 0, 4 // clear least significant 4 bit
  2424. ;;
  2425. (pt1) ld1.nt1 rArgBytes = [rArgEntry] // get # arg bytes
  2426. movl v0 = STATUS_INVALID_PARAMETER_1
  2427. ;;
  2428. cmp.ne pNatedArg = zero, zero // assume no Nat'ed argument
  2429. (pt1) shr rArgNum = rArgBytes, 2
  2430. ;;
  2431. dep rPFS = 0, rUserPFS, 62, 2
  2432. add v0 = rCount, v0 // set return status
  2433. (pt1) add rArgNum = 7, rArgNum // number of in arguments
  2434. ;;
  2435. cmp.geu pNoCopy, pCopy = 8, rArgNum // any in-memory arguments ?
  2436. (pt1) shl rArgBytes = rArgNum, 3 // x2 since args are 8 bytes each, not 4
  2437. ;;
  2438. (pNoCopy) cmp.gt pNatedArg = rArgNum, rCount // any Nat'ed argument ?
  2439. (pCopy) cmp.gt pNatedArg = 8, rCount
  2440. (pCopy) add rArgBytes = -64, rArgBytes // size of in-memory arguments
  2441. ;;
  2442. (pNatedArg) br.spnt Knsc_ErrorReturn // exit if Nat'ed arg found
  2443. (pNoCopy) br.sptk KiSystemServiceEndAddress // skip copy if no memory args
  2444. ;;
  2445. //
  2446. // Get the caller's sp. If caller was user mode, validate the stack pointer
  2447. // ar.unat contains Nat for previous sp (in TrIntSp)
  2448. //
  2449. (pUser) tnat.nz.unc pt1, pt2 = rUserSp // test user sp for Nat
  2450. (pUser) movl rpT2 = MI_USER_PROBE_ADDRESS // User sp limit
  2451. ;;
  2452. (pt2) cmp.geu pt1 = rUserSp, rpT2 // user sp >= PROBE ADDRESS ?
  2453. mov rpT1 = rUserSp // previous sp
  2454. ;;
  2455. (pt1) add rpT1 = -STACK_SCRATCH_AREA,rpT2 // set out of range (includes Nat case)
  2456. ;;
  2457. add out1 = STACK_SCRATCH_AREA, rpT1 // adjust for scratch area
  2458. add out0 = STACK_SCRATCH_AREA, sp // adjust for scratch area
  2459. ;;
  2460. ALTERNATE_ENTRY(KiSystemServiceStartAddress)
  2461. //
  2462. // Call out to C-code so the exception handling works corrrectly.
  2463. // The byte count is in out3 which is rArgBytes.
  2464. //
  2465. br.call.sptk brp=KeCopySafe
  2466. ;;
  2467. dep rPFS = 0, rUserPFS, 62, 2 // rPFS is a temp, recalculate it
  2468. cmp4.ne pt2 = STATUS_SUCCESS, r8 // See if the copy worked.
  2469. (pt2) br.spnt Knsc_ErrorReturn
  2470. ;;
  2471. ALTERNATE_ENTRY(KiSystemServiceEndAddress)
  2472. mov gp = rScallGp
  2473. mov bt0 = rpEntry
  2474. mov rSp = rUserSp
  2475. ;;
  2476. //
  2477. // N.B. t0 is reserved to pass trap frame address to NtContinue()
  2478. //
  2479. alloc rT2 = 0,0,8,0 // output regs are ready
  2480. mov ar.pfs = rPFS
  2481. movl rT1 = KiSystemServiceExit
  2482. ;;
  2483. mov t0 = sp // for NtContinue()
  2484. mov brp = rT1
  2485. br.sptk bt0 // call routine(args)
  2486. ;;
  2487. ALTERNATE_ENTRY(KiSystemServiceExit)
  2488. //
  2489. // make the current bsp the same as the saved BSP in the trap frame
  2490. //
  2491. cover
  2492. ;;
  2493. //
  2494. // At this point:
  2495. // ar.unat contains Nat for previous sp (ar.unat is preserved register)
  2496. // sp -> trap frame
  2497. //
  2498. // Returning from "call": no need to restore volatile state
  2499. // *** TBD *** : zero volatile state for security? PPC does zero, mips does not.
  2500. //
  2501. //
  2502. // Update PbSystemCalls
  2503. //
  2504. //
  2505. // Restore thread previous mode and trap frame address from the trap frame
  2506. //
  2507. add rpT2 = TrStIPSR, sp
  2508. movl rpT1 = KiPcr + PcPrcb // rpT1 -> Prcb
  2509. ;;
  2510. ld8 rpT3 = [rpT1], PcCurrentThread-PcPrcb
  2511. lfetch [rpT2], TrTrapFrame-TrStIPSR
  2512. ;;
  2513. ld8 rThread = [rpT1] // rpT1 -> current thread
  2514. ld8 rT2 = [rpT2], TrPreviousMode-TrTrapFrame
  2515. add rpT3 = PbSystemCalls, rpT3 // pointer to sys call counter
  2516. ;;
  2517. FAST_DISABLE_INTERRUPTS
  2518. ;;
  2519. ld4 rT1 = [rpT3] // rT1.4 = counter value
  2520. ld4 rT3 = [rpT2], TrRsRSC-TrPreviousMode
  2521. add rpT4 = ThTrapFrame, rThread // -> thread trap frame
  2522. add rpT1 = ThApcState+AsUserApcPending, rThread
  2523. ;;
  2524. (pKrnl) ld8 rRscE = [rpT2] // load user RSC
  2525. (pUser) ld1 rT4 = [rpT1], ThAlerted-ThApcState-AsUserApcPending
  2526. add rT1 = 1, rT1 // increment
  2527. ;;
  2528. st8 [rpT4] = rT2, ThPreviousMode-ThTrapFrame
  2529. st4 [rpT3] = rT1 // store
  2530. ;;
  2531. st1 [rpT4] = rT3 // restore prevmode in thread
  2532. mov t0 = sp // set t0 to trap frame
  2533. (pKrnl) br.spnt Knsc_CommonExit // br if returning to kernel
  2534. ;;
  2535. st1 [rpT1] = zero
  2536. cmp4.eq pt0 = zero, rT4
  2537. (pt0) br.sptk KiUserServiceExit
  2538. ;;
  2539. alloc rT1 = ar.pfs, 0, 1, 2, 0
  2540. add loc0 = TrIntV0, sp
  2541. add rpT1 = TrIntTeb, sp
  2542. //
  2543. // v0 is saved in the trap frame so the return status can be restored
  2544. // by NtContinue after the user APC has been dispatched.
  2545. //
  2546. ssm 1 << PSR_I // enable interrupts
  2547. mov rT3 = APC_LEVEL
  2548. ;;
  2549. SET_IRQL (rT3)
  2550. ;;
  2551. st8.nta [loc0] = v0 // save return status in trap frame
  2552. movl gp = _gp // restore to kernel gp value
  2553. st8.nta [rpT1] = teb
  2554. mov out1 = sp
  2555. br.call.sptk brp = KiApcInterrupt
  2556. ;;
  2557. rsm 1 << PSR_I // disable interrupt
  2558. ld8.nta v0 = [loc0] // restore system call return status
  2559. SET_IRQL (zero)
  2560. HANDLER_EXIT(KiNormalSystemCall)
  2561. //
  2562. // KiServiceExit is carefully constructed as a continuation of
  2563. // KiNormalSystemCall. From now on, t0 must be preserved because it is
  2564. // used to hold the trap frame address. v0 must be preserved because it
  2565. // is holding the return status.
  2566. //
  2567. HANDLER_ENTRY_EX(KiServiceExit, KiSystemServiceHandler)
  2568. .prologue
  2569. .unwabi @nt, EXCEPTION_FRAME
  2570. .vframe t0
  2571. mov t0 = sp
  2572. ;;
  2573. ALTERNATE_ENTRY(KiUserServiceExit)
  2574. (pUser) add rpT3 = TrStIPSR, t0
  2575. ;;
  2576. (pUser) ld8 rpT3 = [rpT3]
  2577. invala
  2578. ;;
  2579. (pUser) tbit.nz.unc pUDbg = rpT3, PSR_DB // if user psr.db set, load user DRs
  2580. (pUDbg) br.call.spnt brp = KiLoadUserDebugRegisters
  2581. ;;
  2582. add rpT1 = TrRsRSC, t0 // -> user RSC
  2583. add rpT2 = TrRsBSP, t0 // -> user BSP Store
  2584. ;;
  2585. PROLOGUE_END
  2586. ld8 rRscE = [rpT1], TrRsRNAT-TrRsRSC // load user RSC
  2587. ld8 rBSP = [rpT2]
  2588. mov rRscD = RSC_KERNEL_DISABLED
  2589. ;;
  2590. //
  2591. // Switch to user BSP -- put in load intensive mode to overlap RS restore
  2592. // with volatile state restore.
  2593. //
  2594. ld8 rRNAT = [rpT1] // user RNAT
  2595. extr.u rRscDelta = rRscE, RSC_MBZ1, RSC_LOADRS_LEN
  2596. dep rRscE = r0, rRscE, RSC_MBZ1, RSC_LOADRS_LEN
  2597. ;;
  2598. alloc rT2 = 0,0,0,0
  2599. dep rRscD = rRscDelta, rRscD, RSC_LOADRS, RSC_LOADRS_LEN
  2600. sub rBSPStore = rBSP, rRscDelta
  2601. ;;
  2602. mov ar.rsc = rRscD // turn off RSE
  2603. ;;
  2604. loadrs // pull in user regs
  2605. ;;
  2606. mov ar.bspstore = rBSPStore // restore user BSP
  2607. ;;
  2608. mov ar.rnat = rRNAT // restore user RNAT
  2609. Knsc_CommonExit:
  2610. add rpT1 = TrIntNats, t0
  2611. movl rpT2 = KiPcr+PcCurrentThread
  2612. add rpT4 = TrStIPSR, t0
  2613. add rpT3 = TrRsPFS, t0
  2614. // mov rT0 = (1 << PSR_I) | (1 << PSR_MFH)
  2615. ;;
  2616. ld8 rIntNats = [rpT1], TrIntSp-TrIntNats
  2617. .pred.rel "mutex",pUser,pKrnl
  2618. (pUser) ld8 rT1 = [rpT2], PcHighFpOwner-PcCurrentThread
  2619. (pKrnl) add rpT2 = PcKernelDebugActive-PcCurrentThread, rpT2
  2620. ;;
  2621. ld8 rIPSR = [rpT4]
  2622. (pUser) ld8 rT2 = [rpT2]
  2623. (pKrnl) mov rPreviousMode = KernelMode
  2624. ;;
  2625. ld8 rPFS = [rpT3], TrStIIP-TrRsPFS // get previous PFS
  2626. (pKrnl) ld1 rT2 = [rpT2]
  2627. (pUser) mov rPreviousMode = UserMode
  2628. ;;
  2629. mov ar.rsc = rRscE // restore RSC
  2630. ld8 rIIP = [rpT3], TrStFPSR-TrStIIP
  2631. (pUser) cmp.ne.unc pt0 = rT1, rT2
  2632. ;;
  2633. mov ar.unat = rIntNats
  2634. ld8 rT3 = [rpT3], TrStIFS-TrStFPSR // load fpsr
  2635. (pt0) dep rIPSR = 1, rIPSR, PSR_DFH, 1
  2636. ;;
  2637. ld8.fill rSp = [rpT1], TrPreds-TrIntSp // fill sp
  2638. ld8 rIFS = [rpT3] // load IFS
  2639. // (pUser) dep rIPSR = 0, rIPSR, PSR_TB, 1 // ensure psr.tb is clear
  2640. ;;
  2641. (pKrnl) cmp.ne.unc pKDbg, pt2 = rT2, r0 // hardware debug active?
  2642. dep rIPSR = 0, rIPSR, PSR_MFH, 1 // psr.mfh
  2643. ;;
  2644. ld8 rPreds = [rpT1], TrApUNAT-TrPreds
  2645. (pt2) dep rIPSR = 0, rIPSR, PSR_DB, 1 // disable db in kernel
  2646. (pKDbg) dep rIPSR = 1, rIPSR, PSR_DB, 1 // enable db in kernel
  2647. ;;
  2648. ld8 rUNAT = [rpT1], TrApDCR-TrApUNAT
  2649. mov ar.pfs = rPFS // restore PFS
  2650. ;;
  2651. ld8 rT4 = [rpT1] // load dcr
  2652. // mov psr.l = rIPSR // restore psr settings
  2653. mov pr = rPreds // restore preds
  2654. ;;
  2655. mov cr.dcr = rT4 // restore DCR
  2656. rsm 1 << PSR_IC // disable PSR.ic
  2657. mov ar.unat = rUNAT // restore UNAT
  2658. // mov brp = rIIP // restore brp
  2659. ;;
  2660. srlz.d // must serialize
  2661. mov ar.fpsr = rT3 // restore FPSR
  2662. ;;
  2663. //
  2664. // The system return case must be handle separately from the user return
  2665. // case, so we can determine which stack we are currently using in case
  2666. // a trap is take before we can return.
  2667. //
  2668. mov sp = rSp
  2669. //
  2670. // Restore status registers
  2671. //
  2672. bsw.0
  2673. ;;
  2674. mov cr.ipsr = rIPSR // restore previous IPSR
  2675. mov cr.ifs = rIFS // restore previous IFS
  2676. mov cr.iip = rIIP // restore previous IIP
  2677. ;;
  2678. //
  2679. // Resume at point of interruption (rfi must be at end of instruction group)
  2680. //
  2681. rfi
  2682. ;;
  2683. Knsc_ErrorReturn:
  2684. //
  2685. // N.B. t0 is reserved to pass trap frame address to NtContinue()
  2686. //
  2687. add rPFS = TrRsPFS, sp
  2688. ;;
  2689. ld8 rPFS = [rPFS]
  2690. ;;
  2691. dep rPFS = 0, rPFS, 62, 2
  2692. ;;
  2693. mov ar.pfs = rPFS
  2694. movl rT1 = KiSystemServiceExit
  2695. ;;
  2696. mov brp = rT1
  2697. br.ret.sptk brp
  2698. ;;
  2699. HANDLER_EXIT(KiServiceExit)
  2700. .sdata
  2701. KiSystemServiceExitOffset::
  2702. data4 @secrel(KiSystemServiceExit)
  2703. KiSystemServiceStartOffset::
  2704. data4 @secrel(KiSystemServiceStartAddress)
  2705. KiSystemServiceEndOffset::
  2706. data4 @secrel(KiSystemServiceEndAddress)
  2707. .text
  2708. //++
  2709. //--------------------------------------------------------------------
  2710. // Routine:
  2711. //
  2712. // KiGenericExceptionHandler
  2713. //
  2714. // Description:
  2715. //
  2716. // First level handler for heavyweight exceptions.
  2717. //
  2718. // On entry:
  2719. //
  2720. // ic off
  2721. // interrupts disabled
  2722. // current frame covered
  2723. //
  2724. // Process:
  2725. //
  2726. // Notes:
  2727. //
  2728. // PCR page mapped with TR
  2729. //--------------------------------------------------------------------
  2730. HANDLER_ENTRY(KiGenericExceptionHandler)
  2731. .prologue
  2732. .unwabi @nt, EXCEPTION_FRAME
  2733. ALLOCATE_TRAP_FRAME
  2734. //
  2735. // sp points to trap frame
  2736. //
  2737. // Save exception handler routine in kernel register
  2738. //
  2739. mov rkHandler = rHHandler
  2740. movl rTH3 = KiPcr+PcSavedIFA
  2741. ;;
  2742. st8 [rTH3] = rHIFA
  2743. //
  2744. // Save interruption state in trap frame and switch to user bank registers
  2745. // and switch to kernel backing store.
  2746. //
  2747. SAVE_INTERRUPTION_STATE(Kgeh_SaveTrapFrame)
  2748. //
  2749. // Now running with user banked registers and on kernel stack.
  2750. //
  2751. // Can now take TLB faults
  2752. //
  2753. // sp -> trap frame
  2754. //
  2755. br.call.sptk brp = KiSaveTrapFrame
  2756. ;;
  2757. //
  2758. // Register aliases
  2759. //
  2760. rpT1 = t0
  2761. rpT2 = t1
  2762. rpT3 = t2
  2763. rT1 = t3
  2764. rT2 = t4
  2765. rT3 = t5
  2766. rPreviousMode = t6 // previous mode
  2767. rT4 = t7
  2768. mov rT1 = rkHandler // restore address of interruption routine
  2769. movl rpT1 = KiPcr+PcSavedIIM
  2770. ;;
  2771. ld8 rT2 = [rpT1], PcSavedIFA-PcSavedIIM // load saved IIM
  2772. add rpT2 = TrEOFMarker, sp
  2773. add rpT3 = TrStIIM, sp
  2774. ;;
  2775. ld8 rT4 = [rpT1] // load saved IFA
  2776. movl rT3 = KTRAP_FRAME_EOF | EXCEPTION_FRAME
  2777. ;;
  2778. st8 [rpT2] = rT3, TrHandler-TrEOFMarker
  2779. st8 [rpT3] = rT2, TrStIFA-TrStIIM // save IIM in trap frame
  2780. mov bt0 = rT1 // set destination address
  2781. ;;
  2782. .regstk 0, 1, 2, 0 // must match KiExceptionExit
  2783. alloc out1 = 0,1,2,0
  2784. st8 [rpT3] = rT4 // save IFA in trap frame
  2785. PROLOGUE_END
  2786. //
  2787. // Dispatch the exception via call to address in rkHandler
  2788. //
  2789. .pred.rel "mutex",pUser,pKrnl
  2790. add rpT1 = TrPreviousMode, sp // -> previous mode
  2791. (pUser) mov rPreviousMode = UserMode // set previous mode
  2792. (pKrnl) mov rPreviousMode = KernelMode
  2793. ;;
  2794. st4 [rpT1] = rPreviousMode // save in trap frame
  2795. (pKDbg) br.call.spnt brp = KiLoadKernelDebugRegisters
  2796. ;;
  2797. FAST_ENABLE_INTERRUPTS // enable interrupt
  2798. mov out0 = sp // trap frame pointer
  2799. br.call.sptk brp = bt0 // call handler(tf) (C code)
  2800. ;;
  2801. .pred.rel "mutex",pUser,pKrnl
  2802. cmp.ne pt0, pt1 = v0, zero
  2803. (pUser) mov out1 = UserMode
  2804. (pKrnl) mov out1 = KernelMode
  2805. //
  2806. // does not return
  2807. //
  2808. mov out0 = sp
  2809. (pt1) br.cond.sptk KiAlternateExit
  2810. (pt0) br.call.spnt brp = KiExceptionDispatch
  2811. ;;
  2812. //
  2813. // Interrupts need to be disable be for mess up the stack such that
  2814. // the unwind code does not work.
  2815. //
  2816. FAST_DISABLE_INTERRUPTS
  2817. ;;
  2818. ALTERNATE_ENTRY(KiExceptionExit)
  2819. //++
  2820. //
  2821. // Routine Description:
  2822. //
  2823. // This routine is called to exit from an exception.
  2824. //
  2825. // N.B. This transfer of control occurs from:
  2826. //
  2827. // 1. fall-through from above
  2828. // 2. exit from continue system service
  2829. // 3. exit from raise exception system service
  2830. // 4. exit into user mode from thread startup
  2831. //
  2832. // Arguments:
  2833. //
  2834. // loc0 - pointer to trap frame
  2835. // sp - pointer to high preserved float save area + STACK_SCRATCH_AREA
  2836. //
  2837. // Return Value:
  2838. //
  2839. // Does not return.
  2840. //
  2841. //--
  2842. //
  2843. // upon entry of this block, s0 and s1 must be set to the address of
  2844. // the trap and the exception frames respectively.
  2845. //
  2846. // preserved state is restored here because they may have been modified
  2847. // by SetContext
  2848. //
  2849. LEAF_SETUP(0, 1, 2, 0) // must be in sync with
  2850. // KiGenericExceptionHandler
  2851. mov loc0 = s0 // -> trap frame
  2852. mov out0 = s1 // -> exception frame
  2853. ;;
  2854. br.call.sptk brp = KiRestoreExceptionFrame
  2855. ;;
  2856. mov sp = loc0 // deallocate exception
  2857. // frame by restoring sp
  2858. ALTERNATE_ENTRY(KiAlternateExit)
  2859. //
  2860. // sp -> trap frame addres
  2861. //
  2862. // Interrupts disabled from here to rfi
  2863. //
  2864. FAST_DISABLE_INTERRUPTS
  2865. ;;
  2866. RETURN_FROM_INTERRUPTION(Ked)
  2867. HANDLER_EXIT(KiGenericExceptionHandler)
  2868. //--------------------------------------------------------------------
  2869. // Routine:
  2870. //
  2871. // KiExternalInterruptHandler
  2872. //
  2873. // Description:
  2874. //
  2875. // First level external interrupt handler. Dispatch highest priority
  2876. // pending interrupt.
  2877. //
  2878. // On entry:
  2879. //
  2880. // ic off
  2881. // interrupts disabled
  2882. // current frame covered
  2883. //
  2884. // Process:
  2885. //--------------------------------------------------------------------
  2886. HANDLER_ENTRY(KiExternalInterruptHandler)
  2887. //
  2888. // Now running with user banked registers and on kernel backing store.
  2889. // N.B. sp -> trap frame
  2890. //
  2891. // Can now take TLB faults
  2892. //
  2893. .prologue
  2894. .unwabi @nt, INTERRUPT_FRAME
  2895. .regstk 0, 4, 2, 0
  2896. alloc loc0 = 0, 4, 2, 0
  2897. //
  2898. // Register aliases
  2899. //
  2900. rVector = loc0
  2901. rSaveGP = loc1
  2902. rpSaveIrql = loc2 // -> old irql in trap frame
  2903. rOldIrql = loc3
  2904. rpT1 = t0
  2905. rpT2 = t1
  2906. rpT3 = t2
  2907. rT1 = t3
  2908. rT2 = t4
  2909. rT3 = t5
  2910. rPreviousMode = t6 // previous mode
  2911. rNewIrql = t7
  2912. pEOI = pt1
  2913. //
  2914. // Save kernel gp
  2915. //
  2916. mov rSaveGP = gp
  2917. ;;
  2918. //
  2919. // Get the vector number
  2920. //
  2921. mov rVector = cr.ivr // for A0 2173 workaround
  2922. mov rOldIrql = cr.tpr // get actual tpr value
  2923. br.call.sptk brp = KiSaveTrapFrame
  2924. ;;
  2925. #if defined(INTERRUPTION_LOGGING)
  2926. // For Conditional Interrupt Logging
  2927. mov t2 = gp
  2928. ;;
  2929. movl gp = _gp
  2930. ;;
  2931. add t0 = @gprel(KiVectorLogMask), gp
  2932. ;;
  2933. ld8 t1 = [t0]
  2934. mov gp = t2
  2935. ;;
  2936. tbit.z pt1 = t1, ExternalInterruptBit
  2937. (pt1) br.cond.sptk EndOfLogging2
  2938. movl t0 = KiPcr+PcInterruptionCount
  2939. ;;
  2940. ld4.nt1 t0 = [t0]
  2941. mov t1 = MAX_NUMBER_OF_IHISTORY_RECORDS - 1
  2942. ;;
  2943. add t0 = -1, t0
  2944. movl t2 = KiPcr+0x1000
  2945. ;;
  2946. and t1 = t0, t1
  2947. ;;
  2948. shl t1 = t1, 5
  2949. ;;
  2950. add t0 = t2, t1
  2951. ;;
  2952. add t0 = 24, t0
  2953. ;;
  2954. st8.nta [t0] = rVector // save ivr in the Extra0 field
  2955. // For Conditional Interrupt Logging
  2956. EndOfLogging2:
  2957. #endif // defined(INTERRUPTION_LOGGING)
  2958. //
  2959. // Exit if spurious interrupt vector
  2960. //
  2961. cmp.eq pt0, pt1 = 0xF, rVector
  2962. extr.u rOldIrql = rOldIrql, TPR_MIC, TPR_MIC_LEN
  2963. (pt0) br.spnt Keih_Exit
  2964. ;;
  2965. //
  2966. // sp -> trap frame
  2967. //
  2968. add rpSaveIrql = TrEOFMarker, sp
  2969. movl rT3 = KTRAP_FRAME_EOF | INTERRUPT_FRAME
  2970. ;;
  2971. st8 [rpSaveIrql] = rT3, TrPreviousMode - TrEOFMarker
  2972. .pred.rel "mutex",pUser,pKrnl
  2973. (pUser) mov rPreviousMode = UserMode // set previous mode
  2974. (pKrnl) mov rPreviousMode = KernelMode
  2975. ;;
  2976. st4 [rpSaveIrql] = rPreviousMode, TrOldIrql-TrPreviousMode
  2977. movl rpT3 = KiPcr+PcCurrentIrql
  2978. ;;
  2979. st4 [rpSaveIrql] = rOldIrql // save irql in trap frame
  2980. st1 [rpT3] = rOldIrql // sanitize the shadow copy
  2981. (pKDbg) br.call.spnt brp = KiLoadKernelDebugRegisters
  2982. ;;
  2983. PROLOGUE_END
  2984. Keih_InterruptLoop:
  2985. //
  2986. // Dispatch the interrupt: first raise the IRQL to the level of the new
  2987. // interrupt and enable interrupts.
  2988. //
  2989. GET_IRQL_FOR_VECTOR(p0, rNewIrql, rVector)
  2990. movl rpT3 = KiPcr+PcInterruptRoutine // -> interrupt routine table
  2991. ;;
  2992. shladd rpT3 = rVector, INT_ROUTINES_SHIFT, rpT3 // base + offset
  2993. SET_IRQL (rNewIrql) // raise to new level
  2994. movl rpT1 = KiPcr + PcPrcb // pointer to prcb
  2995. ;;
  2996. ld8 out0 = [rpT3] // out0 -> interrupt dispatcher
  2997. ld8 rpT1 = [rpT1]
  2998. mov out1 = sp // out1 -> trap frame
  2999. ;;
  3000. FAST_ENABLE_INTERRUPTS
  3001. add rpT1 = PbInterruptCount, rpT1 // -> interrupt counter
  3002. ;;
  3003. ld4.nta rT1 = [rpT1] // counter value
  3004. ld8.nta rT2 = [out0], PlGlobalPointer-PlEntryPoint // get entry point
  3005. ;;
  3006. add rT1 = 1, rT1 // increment
  3007. ;;
  3008. //
  3009. // Call the interrupt dispatch routine via a function pointer
  3010. //
  3011. st4.nta [rpT1] = rT1 // store, ignore overflow
  3012. ;;
  3013. ld8.nta gp = [out0], PlEntryPoint-PlGlobalPointer
  3014. mov bt0 = rT2
  3015. br.call.sptk brp = bt0 // call ISR
  3016. ;;
  3017. ld4 rOldIrql = [rpSaveIrql]
  3018. mov gp = rSaveGP
  3019. END_OF_INTERRUPT // end of interrupt processing
  3020. IO_END_OF_INTERRUPT(rVector,rT1,rT2,pEOI)
  3021. ;;
  3022. srlz.d
  3023. //
  3024. // Disable interrupts and restore IRQL level
  3025. //
  3026. FAST_DISABLE_INTERRUPTS
  3027. cmp.gt pt0 = APC_LEVEL, rOldIrql
  3028. mov t0 = APC_LEVEL
  3029. ;;
  3030. (pt0) br.spnt ke_call_apc
  3031. ke_call_apc_resume:
  3032. LOWER_IRQL (rOldIrql)
  3033. //
  3034. // Get the next vector number
  3035. //
  3036. mov rVector = cr.ivr // for A0 2173 workaround
  3037. ;;
  3038. //
  3039. // Loop if more interrupts pending (spurious vector == 0xF)
  3040. //
  3041. cmp.ne pt0 = 0xF, rVector
  3042. ;;
  3043. (pt0) br.spnt Keih_InterruptLoop
  3044. br.sptk Keih_Exit
  3045. ;;
  3046. ke_call_apc:
  3047. LOWER_IRQL (t0)
  3048. ke_call_apc1:
  3049. movl t0 = KiPcr+PcApcInterrupt
  3050. ;;
  3051. ld1 t1 = [t0]
  3052. st1 [t0] = r0
  3053. ;;
  3054. cmp.eq pt0 = r0, t1
  3055. ;;
  3056. (pt0) br.sptk ke_call_apc_resume
  3057. FAST_ENABLE_INTERRUPTS
  3058. mov out1 = sp
  3059. br.call.sptk brp = KiApcInterrupt
  3060. FAST_DISABLE_INTERRUPTS
  3061. br.sptk ke_call_apc1
  3062. Keih_Exit:
  3063. RETURN_FROM_INTERRUPTION(Keih)
  3064. HANDLER_EXIT(KiExternalInterruptHandler)
  3065. //--------------------------------------------------------------------
  3066. // Routine:
  3067. //
  3068. // KiPanicHandler
  3069. //
  3070. // Description:
  3071. //
  3072. // Handler for panic. Call the bug check routine. A place
  3073. // holder for now.
  3074. //
  3075. // On entry:
  3076. //
  3077. // running on kernel memory stack and kernel backing store
  3078. // sp: top of stack -- points to trap frame
  3079. // interrupts enabled
  3080. //
  3081. // IIP: address of bundle causing fault
  3082. //
  3083. // IPSR: copy of PSR at time of interruption
  3084. //
  3085. // Output:
  3086. //
  3087. // sp: top of stack -- points to trap frame
  3088. //
  3089. // Return value:
  3090. //
  3091. // none
  3092. //
  3093. // Notes:
  3094. //
  3095. // If ISR code out of bounds, this code will inovke the panic handler
  3096. //
  3097. //--------------------------------------------------------------------
  3098. HANDLER_ENTRY(KiPanicHandler)
  3099. .prologue
  3100. .unwabi @nt, EXCEPTION_FRAME
  3101. mov rHpT1 = KERNEL_STACK_SIZE
  3102. movl rTH1 = KiPcr+PcPanicStack
  3103. ;;
  3104. ld8 sp = [rTH1], PcInitialStack-PcPanicStack
  3105. movl rTH2 = KiPcr+PcSystemReserved
  3106. ;;
  3107. st4 [rTH2] = rPanicCode
  3108. st8 [rTH1] = sp, PcStackLimit-PcInitialStack
  3109. sub rTH2 = sp, rHpT1
  3110. ;;
  3111. st8 [rTH1] = rTH2, PcInitialBStore-PcStackLimit
  3112. mov rHpT1 = KERNEL_BSTORE_SIZE
  3113. ;;
  3114. st8 [rTH1] = sp, PcBStoreLimit-PcInitialBStore
  3115. add rTH2 = rHpT1, sp
  3116. add sp = -TrapFrameLength, sp
  3117. ;;
  3118. st8 [rTH1] = rTH2
  3119. SAVE_INTERRUPTION_STATE(Kph_SaveTrapFrame)
  3120. //
  3121. // switch to kernel back
  3122. //
  3123. bsw.0
  3124. ;;
  3125. rpRNAT = h16
  3126. rpBSPStore= h17
  3127. rBSPStore = h18
  3128. rKBSPStore= h19
  3129. rRNAT = h20
  3130. rKrnlFPSR = h21
  3131. mov ar.rsc = r0 // put RSE in lazy mode
  3132. movl rKBSPStore = KiPcr+PcInitialBStore
  3133. ;;
  3134. mov rBSPStore = ar.bspstore
  3135. mov rRNAT = ar.rnat
  3136. ;;
  3137. ld8 rKBSPStore = [rKBSPStore]
  3138. add rpRNAT = TrRsRNAT, sp
  3139. add rpBSPStore = TrRsBSPSTORE, sp
  3140. ;;
  3141. st8 [rpRNAT] = rRNAT
  3142. st8 [rpBSPStore] = rBSPStore
  3143. dep rKBSPStore = rBSPStore, rKBSPStore, 0, 9
  3144. ;;
  3145. mov ar.bspstore = rKBSPStore
  3146. mov ar.rsc = RSC_KERNEL
  3147. ;;
  3148. //
  3149. // switch to user bank
  3150. //
  3151. bsw.1
  3152. ;;
  3153. alloc out0 = ar.pfs, 0, 0, 5, 0
  3154. ;;
  3155. PROLOGUE_END
  3156. br.call.sptk brp = KiSaveTrapFrame
  3157. ;;
  3158. movl out0 = KiPcr+PcSystemReserved
  3159. ;;
  3160. ld4 out0 = [out0] // 1st argument: panic code
  3161. mov out1 = sp // 2nd argument: trap frame
  3162. br.call.sptk.many brp = KeBugCheckEx
  3163. ;;
  3164. nop.m 0
  3165. nop.m 0
  3166. nop.i 0
  3167. ;;
  3168. HANDLER_EXIT(KiPanicHandler)
  3169. //++
  3170. //--------------------------------------------------------------------
  3171. // Routine:
  3172. //
  3173. // VOID
  3174. // KiSaveTrapFrame(PKTRAP_FRAME)
  3175. //
  3176. // Description:
  3177. //
  3178. // Save volatile application state in trap frame.
  3179. // Note: sp, brp, UNAT, RSC, predicates, BSP, BSP Store,
  3180. // PFS, DCR, and FPSR saved elsewhere.
  3181. //
  3182. // Input:
  3183. //
  3184. // sp: points to trap frame
  3185. // ar.unat: contains the Nats of sp, gp, teb, which have already
  3186. // been spilled into the trap frame.
  3187. //
  3188. // Output:
  3189. //
  3190. // None
  3191. //
  3192. // Return value:
  3193. //
  3194. // none
  3195. //
  3196. //--------------------------------------------------------------------
  3197. LEAF_ENTRY(KiSaveTrapFrame)
  3198. .regstk 0, 3, 0, 0
  3199. //
  3200. // Local register aliases
  3201. //
  3202. rpTF1 = loc0
  3203. rpTF2 = loc1
  3204. rL1 = t0
  3205. rL2 = t1
  3206. rL3 = t2
  3207. rL4 = t3
  3208. rL5 = t4
  3209. //
  3210. // (ar.unat unchanged from point of save)
  3211. // Spill temporary (volatile) integer registers
  3212. //
  3213. alloc loc2 = 0,3,0,0 // don't destroy static register
  3214. add rpTF1 = TrIntT0, sp // -> t0 save area
  3215. add rpTF2 = TrIntT1, sp // -> t1 save area
  3216. ;;
  3217. .mem.offset 0,0
  3218. st8.spill [rpTF1] = t0, TrIntT2-TrIntT0 // spill t0 - t22
  3219. .mem.offset 8,0
  3220. st8.spill [rpTF2] = t1, TrIntT3-TrIntT1
  3221. ;;
  3222. .mem.offset 0,0
  3223. st8.spill [rpTF1] = t2, TrIntT4-TrIntT2
  3224. .mem.offset 8,0
  3225. st8.spill [rpTF2] = t3, TrIntT5-TrIntT3
  3226. ;;
  3227. .mem.offset 0,0
  3228. st8.spill [rpTF1] = t4, TrIntT6-TrIntT4
  3229. .mem.offset 8,0
  3230. st8.spill [rpTF2] = t5, TrIntT7-TrIntT5
  3231. mov rL2 = bt0
  3232. ;;
  3233. mov rL1 = cr.dcr
  3234. mov rL4 = ar.ccv
  3235. mov rL3 = bt1
  3236. ;;
  3237. .mem.offset 0,0
  3238. st8.spill [rpTF1] = t6, TrIntT8-TrIntT6
  3239. .mem.offset 8,0
  3240. st8.spill [rpTF2] = t7, TrIntT9-TrIntT7
  3241. ;;
  3242. .mem.offset 0,0
  3243. st8.spill [rpTF1] = t8, TrIntT10-TrIntT8
  3244. .mem.offset 8,0
  3245. st8.spill [rpTF2] = t9, TrIntT11-TrIntT9
  3246. ;;
  3247. .mem.offset 0,0
  3248. st8.spill [rpTF1] = t10, TrIntT12-TrIntT10
  3249. .mem.offset 8,0
  3250. st8.spill [rpTF2] = t11, TrIntT13-TrIntT11
  3251. ;;
  3252. .mem.offset 0,0
  3253. st8.spill [rpTF1] = t12, TrIntT14-TrIntT12
  3254. .mem.offset 8,0
  3255. st8.spill [rpTF2] = t13, TrIntT15-TrIntT13
  3256. ;;
  3257. .mem.offset 0,0
  3258. st8.spill [rpTF1] = t14, TrIntT16-TrIntT14
  3259. .mem.offset 8,0
  3260. st8.spill [rpTF2] = t15, TrIntT17-TrIntT15
  3261. ;;
  3262. .mem.offset 0,0
  3263. st8.spill [rpTF1] = t16, TrIntT18-TrIntT16
  3264. .mem.offset 8,0
  3265. st8.spill [rpTF2] = t17, TrIntT19-TrIntT17
  3266. ;;
  3267. .mem.offset 0,0
  3268. st8.spill [rpTF1] = t18, TrIntT20-TrIntT18
  3269. .mem.offset 8,0
  3270. st8.spill [rpTF2] = t19, TrIntT21-TrIntT19
  3271. ;;
  3272. .mem.offset 0,0
  3273. st8.spill [rpTF1] = t20, TrIntT22-TrIntT20
  3274. .mem.offset 8,0
  3275. st8.spill [rpTF2] = t21, TrIntV0-TrIntT21
  3276. ;;
  3277. .mem.offset 0,0
  3278. st8.spill [rpTF1] = t22, TrBrT0-TrIntT22
  3279. .mem.offset 8,0
  3280. st8.spill [rpTF2] = v0, TrBrT1-TrIntV0 // spill old V0
  3281. ;;
  3282. st8 [rpTF1] = rL2, TrApCCV-TrBrT0 // save old bt0 - bt1
  3283. st8 [rpTF2] = rL3
  3284. ;;
  3285. mov rL5 = ar.unat
  3286. st8 [rpTF1] = rL4, TrApDCR-TrApCCV // save ar.ccv
  3287. ;;
  3288. st8 [rpTF1] = rL1 // save cr.dcr
  3289. add rpTF1 = TrFltT0, sp // point to FltT0
  3290. add rpTF2 = TrFltT1, sp // point to FltT1
  3291. ;;
  3292. //
  3293. // Spill temporary (volatile) floating point registers
  3294. //
  3295. stf.spill [rpTF1] = ft0, TrFltT2-TrFltT0 // spill float tmp 0 - 9
  3296. stf.spill [rpTF2] = ft1, TrFltT3-TrFltT1
  3297. ;;
  3298. stf.spill [rpTF1] = ft2, TrFltT4-TrFltT2
  3299. stf.spill [rpTF2] = ft3, TrFltT5-TrFltT3
  3300. ;;
  3301. stf.spill [rpTF1] = ft4, TrFltT6-TrFltT4
  3302. stf.spill [rpTF2] = ft5, TrFltT7-TrFltT5
  3303. ;;
  3304. stf.spill [rpTF1] = ft6, TrFltT8-TrFltT6
  3305. stf.spill [rpTF2] = ft7, TrFltT9-TrFltT7
  3306. add t20 = TrIntNats, sp
  3307. ;;
  3308. stf.spill [rpTF1] = ft8
  3309. stf.spill [rpTF2] = ft9
  3310. ;;
  3311. st8 [t20] = rL5 // save volatile iNats
  3312. LEAF_RETURN
  3313. ;;
  3314. LEAF_EXIT(KiSaveTrapFrame)
  3315. //++
  3316. //--------------------------------------------------------------------
  3317. // Routine:
  3318. //
  3319. // VOID
  3320. // KiRestoreTrapFrame(PKTRAP_FRAME)
  3321. //
  3322. // Description:
  3323. //
  3324. // Restore volatile application state from trap frame. Restore DCR
  3325. // Note: sp, brp, RSC, UNAT, predicates, BSP, BSP Store, PFS,
  3326. // DCR and FPSR not restored here.
  3327. //
  3328. // Input:
  3329. //
  3330. // sp: points to trap frame
  3331. // RSE frame size is zero
  3332. //
  3333. // Output:
  3334. //
  3335. // None
  3336. //
  3337. // Return value:
  3338. //
  3339. // none
  3340. //
  3341. //--------------------------------------------------------------------
  3342. LEAF_ENTRY(KiRestoreTrapFrame)
  3343. LEAF_SETUP(0,2,0,0)
  3344. rpTF1 = loc0
  3345. rpTF2 = loc1
  3346. mov t21 = psr
  3347. add t12 = TrIntNats, sp
  3348. add rpTF2 = TrApCCV, sp
  3349. ;;
  3350. ld8 t0 = [t12], TrBrT0-TrIntNats
  3351. ld8 t1 = [rpTF2], TrBrT1-TrApCCV
  3352. add rpTF1 = TrFltT0, sp
  3353. ;;
  3354. ld8 t2 = [t12], TrStFPSR-TrBrT0
  3355. ld8 t3 = [rpTF2], TrApDCR-TrBrT1
  3356. ;;
  3357. ld8 t10 = [t12]
  3358. ld8 t11 = [rpTF2], TrFltT1-TrApDCR
  3359. ;;
  3360. ldf.fill ft0 = [rpTF1], TrFltT2-TrFltT0
  3361. ldf.fill ft1 = [rpTF2], TrFltT3-TrFltT1
  3362. ;;
  3363. mov ar.unat = t0
  3364. ldf.fill ft2 = [rpTF1], TrFltT4-TrFltT2
  3365. ldf.fill ft3 = [rpTF2], TrFltT5-TrFltT3
  3366. ;;
  3367. ldf.fill ft4 = [rpTF1], TrFltT6-TrFltT4
  3368. ldf.fill ft5 = [rpTF2], TrFltT7-TrFltT5
  3369. ;;
  3370. ldf.fill ft6 = [rpTF1], TrFltT8-TrFltT6
  3371. ldf.fill ft7 = [rpTF2], TrFltT9-TrFltT7
  3372. ;;
  3373. ldf.fill ft8 = [rpTF1], TrIntGp-TrFltT8
  3374. ldf.fill ft9 = [rpTF2], TrIntT0-TrFltT9
  3375. ;;
  3376. mov ar.ccv = t1
  3377. ld8.fill gp = [rpTF1], TrIntT1-TrIntGp
  3378. ;;
  3379. ld8.fill t0 = [rpTF2], TrIntT2-TrIntT0
  3380. ld8.fill t1 = [rpTF1], TrIntT3-TrIntT1
  3381. mov bt0 = t2
  3382. ;;
  3383. mov cr.dcr = t11
  3384. ld8.fill t2 = [rpTF2], TrIntT4-TrIntT2
  3385. mov bt1 = t3
  3386. ;;
  3387. ld8.fill t3 = [rpTF1], TrIntT5-TrIntT3
  3388. tbit.z pt1 = t21, PSR_MFL
  3389. mov ar.fpsr = t10
  3390. ld8.fill t4 = [rpTF2], TrIntT6-TrIntT4
  3391. ;;
  3392. ld8.fill t5 = [rpTF1], TrIntT7-TrIntT5
  3393. ld8.fill t6 = [rpTF2], TrIntT8-TrIntT6
  3394. ;;
  3395. ld8.fill t7 = [rpTF1], TrIntT9-TrIntT7
  3396. ld8.fill t8 = [rpTF2], TrIntT10-TrIntT8
  3397. ;;
  3398. ld8.fill t9 = [rpTF1], TrIntT11-TrIntT9
  3399. ld8.fill t10 = [rpTF2], TrIntT12-TrIntT10
  3400. ;;
  3401. ld8.fill t11 = [rpTF1], TrIntT13-TrIntT11
  3402. ld8.fill t12 = [rpTF2], TrIntT14-TrIntT12
  3403. ;;
  3404. ld8.fill t13 = [rpTF1], TrIntT15-TrIntT13
  3405. ld8.fill t14 = [rpTF2], TrIntT16-TrIntT14
  3406. ;;
  3407. ld8.fill t15 = [rpTF1], TrIntT17-TrIntT15
  3408. ld8.fill t16 = [rpTF2], TrIntT18-TrIntT16
  3409. ;;
  3410. ld8.fill t17 = [rpTF1], TrIntT19-TrIntT17
  3411. ld8.fill t18 = [rpTF2], TrIntT20-TrIntT18
  3412. ;;
  3413. ld8.fill t19 = [rpTF1], TrIntT21-TrIntT19
  3414. ld8.fill t20 = [rpTF2], TrIntT22-TrIntT20
  3415. ;;
  3416. ld8.fill t21 = [rpTF1], TrIntTeb-TrIntT21
  3417. ld8.fill t22 = [rpTF2], TrIntV0-TrIntT22
  3418. ;;
  3419. ld8.fill teb = [rpTF1]
  3420. ld8.fill v0 = [rpTF2]
  3421. br.ret.sptk.many brp
  3422. ;;
  3423. LEAF_EXIT(KiRestoreTrapFrame)
  3424. //++
  3425. //--------------------------------------------------------------------
  3426. // Routine:
  3427. //
  3428. // VOID
  3429. // KiLoadKernelDebugRegisters
  3430. //
  3431. // Description:
  3432. //
  3433. // We maintain two debug register flags:
  3434. // 1. Thread DebugActive: Debug registers active for current thread
  3435. // 2. PCR KernelDebugActive: Debug registers active in kernel mode
  3436. // (setup by kernel debugger)
  3437. //
  3438. // On user -> kernel transitions there are four possibilities:
  3439. //
  3440. // Thread Kernel
  3441. // DebugActive DebugActive Action
  3442. //
  3443. // 1. 0 0 None
  3444. //
  3445. // 2. 1 0 None (kernel PSR.db = 0 by default)
  3446. //
  3447. // 3. 0 1 Set PSR.db = 1 for kernel
  3448. //
  3449. // 4. 1 1 Set PSR.db = 1 for kernel and
  3450. // load kernel debug registers
  3451. //
  3452. // Note we never save the user debug registers:
  3453. // the user cannot change the DRs so the values in the DR save area are
  3454. // always up-to-date (set by SetContext).
  3455. //
  3456. // Input:
  3457. //
  3458. // None (Previous mode is USER)
  3459. //
  3460. // Output:
  3461. //
  3462. // None
  3463. //
  3464. // Return value:
  3465. //
  3466. // none
  3467. //
  3468. //--------------------------------------------------------------------
  3469. NESTED_ENTRY(KiLoadKernelDebugRegisters)
  3470. PROLOGUE_BEGIN
  3471. movl t10 = KiPcr+PcPrcb
  3472. ;;
  3473. ld8 t10 = [t10] // load prcb address
  3474. cmp.eq pt3, pt2 = r0, r0
  3475. ;;
  3476. add t11 = PbProcessorState+KpsSpecialRegisters+KsKernelDbI0,t10
  3477. add t12 = PbProcessorState+KpsSpecialRegisters+KsKernelDbI1,t10
  3478. add t13 = PbProcessorState+KpsSpecialRegisters+KsKernelDbD0,t10
  3479. add t14 = PbProcessorState+KpsSpecialRegisters+KsKernelDbD1,t10
  3480. br Krdr_Common
  3481. ;;
  3482. ALTERNATE_ENTRY(KiLoadUserDebugRegisters)
  3483. //
  3484. // Restore debug registers, if debug active
  3485. //
  3486. cmp.ne pt3, pt2 = r0, r0
  3487. movl t10 = KiPcr+PcCurrentThread
  3488. ;;
  3489. ld8 t10 = [t10] // get current thread pointer
  3490. ;;
  3491. add t10 = ThStackBase, t10
  3492. ;;
  3493. ld8.nta t10 = [t10] // get stack base
  3494. ;;
  3495. add t11 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbI0,t10
  3496. add t12 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbI1,t10
  3497. add t13 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbD0,t10
  3498. add t14 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbD1,t10
  3499. ;;
  3500. Krdr_Common:
  3501. .regstk 0, 2, 2, 0
  3502. .save ar.pfs, savedpfs
  3503. alloc savedpfs = ar.pfs, 0, 2, 2, 0
  3504. .save b0, savedbrp
  3505. mov savedbrp = brp
  3506. .save ar.lc, t22
  3507. mov t22 = ar.lc // save ar.lc
  3508. mov t7 = 0
  3509. mov t8 = 1
  3510. PROLOGUE_END
  3511. mov ar.lc = 1 // 2 pairs of debug registers
  3512. ;;
  3513. Krdr_Loop:
  3514. ld8 t1 = [t11], 16 // get dbr pair
  3515. ld8 t2 = [t12], 16 // step by 16 = 1 pair of DRs
  3516. ld8 t3 = [t13], 16 // get dbr pair
  3517. ld8 t4 = [t14], 16 // step by 16 = 1 pair of DRs
  3518. ;;
  3519. .auto
  3520. mov ibr[t7] = t1 // restore ibr pair
  3521. mov ibr[t8] = t2
  3522. .auto
  3523. mov dbr[t7] = t3 // restore dbr pair
  3524. mov dbr[t8] = t4
  3525. ;;
  3526. #ifndef NO_12241
  3527. srlz.d
  3528. #endif
  3529. .default
  3530. add t7 = 2, t7 // next pair
  3531. add t8 = 2, t8
  3532. br.cloop.sptk Krdr_Loop
  3533. ;;
  3534. mov ar.lc = t22 // restore ar.lc
  3535. (pt2) br.ret.sptk brp // return if loading user
  3536. mov out0 = PSR_DB
  3537. mov out1 = 1
  3538. (pt3) br.call.spnt brp = KeSetLowPsrBit // set psr.db if loading kernel
  3539. ;;
  3540. NESTED_RETURN
  3541. ;;
  3542. NESTED_EXIT(KiLoadKernelDebugRegisters)
  3543. //++
  3544. //--------------------------------------------------------------------
  3545. // Routine:
  3546. //
  3547. // VOID
  3548. // KiSaveExceptionFrame(PKEXCEPTION_FRAME)
  3549. //
  3550. // Description:
  3551. //
  3552. // Save preserved context in exception frame.
  3553. //
  3554. // Input:
  3555. //
  3556. // a0: points to exception frame
  3557. //
  3558. // Output:
  3559. //
  3560. // None
  3561. //
  3562. // Return value:
  3563. //
  3564. // none
  3565. //
  3566. // Note: t0 may contain the trap frame address; don't touch it.
  3567. //
  3568. //--------------------------------------------------------------------
  3569. LEAF_ENTRY(KiSaveExceptionFrame)
  3570. //
  3571. // Local register aliases
  3572. //
  3573. rpEF1 = t10
  3574. rpEF2 = t11
  3575. add rpEF1 = ExIntS0, a0 // -> ExIntS0
  3576. movl t12 = PFS_EC_MASK << PFS_EC_SHIFT
  3577. ;;
  3578. add rpEF2 = ExIntS1, a0 // -> ExIntS1
  3579. mov t3 = ar.pfs
  3580. ;;
  3581. and t3 = t3, t12
  3582. .mem.offset 0,0
  3583. st8.spill [rpEF1] = s0, ExIntS2-ExIntS0
  3584. .mem.offset 8,0
  3585. st8.spill [rpEF2] = s1, ExIntS3-ExIntS1
  3586. mov t4 = ar.lc
  3587. ;;
  3588. .mem.offset 0,0
  3589. st8.spill [rpEF1] = s2, ExApEC-ExIntS2
  3590. .mem.offset 8,0
  3591. st8.spill [rpEF2] = s3, ExApLC-ExIntS3
  3592. mov t5 = bs0
  3593. ;;
  3594. st8 [rpEF1] = t3, ExBrS0-ExApEC
  3595. st8 [rpEF2] = t4, ExBrS1-ExApLC
  3596. mov t6 = bs1
  3597. ;;
  3598. mov t2 = ar.unat // save user nat register for
  3599. mov t7 = bs2
  3600. mov t8 = bs3
  3601. st8 [rpEF1] = t5, ExBrS2-ExBrS0
  3602. st8 [rpEF2] = t6, ExBrS3-ExBrS1
  3603. mov t9 = bs4
  3604. ;;
  3605. st8 [rpEF1] = t7, ExBrS4-ExBrS2
  3606. st8 [rpEF2] = t8, ExIntNats-ExBrS3
  3607. ;;
  3608. st8 [rpEF1] = t9, ExFltS0-ExBrS4
  3609. st8 [rpEF2] = t2, ExFltS1-ExIntNats
  3610. ;;
  3611. stf.spill [rpEF1] = fs0, ExFltS2-ExFltS0
  3612. stf.spill [rpEF2] = fs1, ExFltS3-ExFltS1
  3613. ;;
  3614. stf.spill [rpEF1] = fs2, ExFltS4-ExFltS2
  3615. stf.spill [rpEF2] = fs3, ExFltS5-ExFltS3
  3616. ;;
  3617. stf.spill [rpEF1] = fs4, ExFltS6-ExFltS4
  3618. stf.spill [rpEF2] = fs5, ExFltS7-ExFltS5
  3619. ;;
  3620. stf.spill [rpEF1] = fs6, ExFltS8-ExFltS6
  3621. stf.spill [rpEF2] = fs7, ExFltS9-ExFltS7
  3622. ;;
  3623. stf.spill [rpEF1] = fs8, ExFltS10-ExFltS8
  3624. stf.spill [rpEF2] = fs9, ExFltS11-ExFltS9
  3625. ;;
  3626. stf.spill [rpEF1] = fs10, ExFltS12-ExFltS10
  3627. stf.spill [rpEF2] = fs11, ExFltS13-ExFltS11
  3628. ;;
  3629. stf.spill [rpEF1] = fs12, ExFltS14-ExFltS12
  3630. stf.spill [rpEF2] = fs13, ExFltS15-ExFltS13
  3631. ;;
  3632. stf.spill [rpEF1] = fs14, ExFltS16-ExFltS14
  3633. stf.spill [rpEF2] = fs15, ExFltS17-ExFltS15
  3634. ;;
  3635. stf.spill [rpEF1] = fs16, ExFltS18-ExFltS16
  3636. stf.spill [rpEF2] = fs17, ExFltS19-ExFltS17
  3637. ;;
  3638. stf.spill [rpEF1] = fs18
  3639. stf.spill [rpEF2] = fs19
  3640. LEAF_RETURN
  3641. ;;
  3642. LEAF_EXIT(KiSaveExceptionFrame)
  3643. //--------------------------------------------------------------------
  3644. // Routine:
  3645. //
  3646. // VOID
  3647. // KiRestoreExceptionFrame(PKEXCEPTION_FRAME)
  3648. //
  3649. // Description:
  3650. //
  3651. // Restores preserved context from the exception frame. Also
  3652. // restore volatile part of floating point context not restored with
  3653. // rest of volatile context.
  3654. //
  3655. // Note: This routine does not use v0, t21 or t22. This routine's
  3656. // caller may be dependent on these registers (for performance
  3657. // in the context switch path).
  3658. //
  3659. // Input:
  3660. //
  3661. // a0: points to exception frame
  3662. //
  3663. // Output:
  3664. //
  3665. // None
  3666. //
  3667. // Return value:
  3668. //
  3669. // none
  3670. //
  3671. //--------------------------------------------------------------------
  3672. LEAF_ENTRY(KiRestoreExceptionFrame)
  3673. add t16 = ExIntNats, a0
  3674. movl t12 = PFS_EC_MASK << PFS_EC_SHIFT
  3675. add t17 = ExApEC, a0
  3676. nop.f 0
  3677. mov t13 = ar.pfs
  3678. ;;
  3679. ld8.nta t2 = [t16], ExBrS0-ExIntNats
  3680. ld8.nta t3 = [t17], ExApLC-ExApEC
  3681. ;;
  3682. ld8.nta t5 = [t16], ExBrS1-ExBrS0
  3683. ld8.nta t4 = [t17], ExBrS2-ExApLC
  3684. ;;
  3685. ld8.nta t6 = [t16], ExBrS3-ExBrS1
  3686. ld8.nta t7 = [t17], ExBrS4-ExBrS2
  3687. ;;
  3688. ld8.nta t8 = [t16], ExFltS0-ExBrS3
  3689. ld8.nta t9 = [t17], ExFltS1-ExBrS4
  3690. ;;
  3691. ldf.fill.nta fs0 = [t16], ExFltS2-ExFltS0
  3692. ldf.fill.nta fs1 = [t17], ExFltS3-ExFltS1
  3693. add t18 = ExIntS0, a0
  3694. ;;
  3695. ldf.fill.nta fs2 = [t16], ExFltS4-ExFltS2
  3696. ldf.fill.nta fs3 = [t17], ExFltS5-ExFltS3
  3697. add t19 = ExIntS1, a0
  3698. ;;
  3699. ldf.fill.nta fs4 = [t16], ExFltS6-ExFltS4
  3700. ldf.fill.nta fs5 = [t17], ExFltS7-ExFltS5
  3701. andcm t13 = t13, t12 // zero out EC field
  3702. ;;
  3703. ldf.fill.nta fs6 = [t16], ExFltS8-ExFltS6
  3704. ldf.fill.nta fs7 = [t17], ExFltS9-ExFltS7
  3705. and t3 = t3, t12 // capture EC value
  3706. ;;
  3707. mov ar.unat = t2
  3708. or t13 = t3, t13 // deposit into PFS.EC field
  3709. ;;
  3710. ldf.fill.nta fs8 = [t16], ExFltS10-ExFltS8
  3711. ldf.fill.nta fs9 = [t17], ExFltS11-ExFltS9
  3712. mov ar.pfs = t13
  3713. ;;
  3714. ldf.fill.nta fs10 = [t16], ExFltS12-ExFltS10
  3715. ldf.fill.nta fs11 = [t17], ExFltS13-ExFltS11
  3716. mov ar.lc = t4
  3717. ;;
  3718. ldf.fill.nta fs12 = [t16], ExFltS14-ExFltS12
  3719. ldf.fill.nta fs13 = [t17], ExFltS15-ExFltS13
  3720. mov bs0 = t5
  3721. ;;
  3722. ldf.fill.nta fs14 = [t16], ExFltS16-ExFltS14
  3723. ldf.fill.nta fs15 = [t17], ExFltS17-ExFltS15
  3724. mov bs1 = t6
  3725. ;;
  3726. ldf.fill.nta fs16 = [t16], ExFltS18-ExFltS16
  3727. ldf.fill.nta fs17 = [t17], ExFltS19-ExFltS17
  3728. mov bs2 = t7
  3729. ;;
  3730. ldf.fill.nta fs18 = [t16]
  3731. ldf.fill.nta fs19 = [t17]
  3732. mov bs3 = t8
  3733. ld8.fill.nta s0 = [t18], ExIntS2-ExIntS0
  3734. ld8.fill.nta s1 = [t19], ExIntS3-ExIntS1
  3735. mov bs4 = t9
  3736. ;;
  3737. ld8.fill.nta s2 = [t18]
  3738. ld8.fill.nta s3 = [t19]
  3739. LEAF_RETURN
  3740. ;;
  3741. LEAF_EXIT(KiRestoreExceptionFrame)
  3742. //++
  3743. //--------------------------------------------------------------------
  3744. // Routine:
  3745. //
  3746. // KiSaveHigherFPVolatile(PKHIGHER_FP_SAVEAREA)
  3747. //
  3748. // Description:
  3749. //
  3750. // Save higher FP volatile context in higher FP save area
  3751. //
  3752. // Input:
  3753. //
  3754. // a0: pointer to higher FP save area
  3755. // brp: return address
  3756. //
  3757. // Output:
  3758. //
  3759. // None
  3760. //
  3761. // Return value:
  3762. //
  3763. // None
  3764. //
  3765. //--------------------------------------------------------------------
  3766. NESTED_ENTRY(KiSaveHigherFPVolatile)
  3767. NESTED_SETUP(1, 3, 1, 0)
  3768. PROLOGUE_END
  3769. //
  3770. // Local register aliases
  3771. //
  3772. rpSA1 = t0
  3773. rpSA2 = t1
  3774. //
  3775. // Clear DFH bit so the high floating point set may be saved by the kernel
  3776. // Disable interrupts so that save is atomic
  3777. //
  3778. GET_IRQL (loc2)
  3779. mov t2 = psr.um
  3780. movl t3 = KiPcr+PcCurrentThread
  3781. ;;
  3782. cmp.ge pt2, pt3 = APC_LEVEL, loc2
  3783. ;;
  3784. PSET_IRQL (pt2, DISPATCH_LEVEL)
  3785. ld8 t4 = [t3], PcHighFpOwner-PcCurrentThread
  3786. ;;
  3787. ld8 t5 = [t3]
  3788. ;;
  3789. cmp.ne pt1 = t4, t5
  3790. (pt1) br.cond.spnt Kshfpv20
  3791. ;;
  3792. tbit.z pt0 = t2, PSR_MFH
  3793. (pt0) br.cond.spnt Kshfpv20
  3794. br Kshfpv10
  3795. ;;
  3796. ALTERNATE_ENTRY(KiSaveHigherFPVolatileAtDispatchLevel)
  3797. NESTED_SETUP(1, 3, 1, 0)
  3798. cmp.ne pt2, pt3 = r0, r0 // set pt2 to FALSE, pt3 to TRUE
  3799. PROLOGUE_END
  3800. movl t3 = KiPcr+PcCurrentThread
  3801. ;;
  3802. ld8 t4 = [t3], PcHighFpOwner-PcCurrentThread
  3803. ;;
  3804. ld8 t5 = [t3]
  3805. ;;
  3806. cmp.ne pt1 = t4, t5
  3807. ;;
  3808. (pt1) break.i BREAKPOINT_STOP
  3809. Kshfpv10:
  3810. rsm (1 << PSR_DFH)
  3811. add rpSA1 = HiFltF32, a0 // -> HiFltF32
  3812. add rpSA2 = HiFltF33, a0 // -> HiFltF33
  3813. ;;
  3814. srlz.d
  3815. stf.spill.nta [rpSA1] = f32, HiFltF34-HiFltF32
  3816. stf.spill.nta [rpSA2] = f33, HiFltF35-HiFltF33
  3817. ;;
  3818. stf.spill.nta [rpSA1] = f34, HiFltF36-HiFltF34
  3819. stf.spill.nta [rpSA2] = f35, HiFltF37-HiFltF35
  3820. ;;
  3821. stf.spill.nta [rpSA1] = f36, HiFltF38-HiFltF36
  3822. stf.spill.nta [rpSA2] = f37, HiFltF39-HiFltF37
  3823. ;;
  3824. stf.spill.nta [rpSA1] = f38, HiFltF40-HiFltF38
  3825. stf.spill.nta [rpSA2] = f39, HiFltF41-HiFltF39
  3826. ;;
  3827. stf.spill.nta [rpSA1] = f40, HiFltF42-HiFltF40
  3828. stf.spill.nta [rpSA2] = f41, HiFltF43-HiFltF41
  3829. ;;
  3830. stf.spill.nta [rpSA1] = f42, HiFltF44-HiFltF42
  3831. stf.spill.nta [rpSA2] = f43, HiFltF45-HiFltF43
  3832. ;;
  3833. stf.spill.nta [rpSA1] = f44, HiFltF46-HiFltF44
  3834. stf.spill.nta [rpSA2] = f45, HiFltF47-HiFltF45
  3835. ;;
  3836. stf.spill.nta [rpSA1] = f46, HiFltF48-HiFltF46
  3837. stf.spill.nta [rpSA2] = f47, HiFltF49-HiFltF47
  3838. ;;
  3839. stf.spill.nta [rpSA1] = f48, HiFltF50-HiFltF48
  3840. stf.spill.nta [rpSA2] = f49, HiFltF51-HiFltF49
  3841. ;;
  3842. stf.spill.nta [rpSA1] = f50, HiFltF52-HiFltF50
  3843. stf.spill.nta [rpSA2] = f51, HiFltF53-HiFltF51
  3844. ;;
  3845. stf.spill.nta [rpSA1] = f52, HiFltF54-HiFltF52
  3846. stf.spill.nta [rpSA2] = f53, HiFltF55-HiFltF53
  3847. ;;
  3848. stf.spill.nta [rpSA1] = f54, HiFltF56-HiFltF54
  3849. stf.spill.nta [rpSA2] = f55, HiFltF57-HiFltF55
  3850. ;;
  3851. stf.spill.nta [rpSA1] = f56, HiFltF58-HiFltF56
  3852. stf.spill.nta [rpSA2] = f57, HiFltF59-HiFltF57
  3853. ;;
  3854. stf.spill.nta [rpSA1] = f58, HiFltF60-HiFltF58
  3855. stf.spill.nta [rpSA2] = f59, HiFltF61-HiFltF59
  3856. ;;
  3857. stf.spill.nta [rpSA1] = f60, HiFltF62-HiFltF60
  3858. stf.spill.nta [rpSA2] = f61, HiFltF63-HiFltF61
  3859. ;;
  3860. stf.spill.nta [rpSA1] = f62, HiFltF64-HiFltF62
  3861. stf.spill.nta [rpSA2] = f63, HiFltF65-HiFltF63
  3862. ;;
  3863. stf.spill.nta [rpSA1] = f64, HiFltF66-HiFltF64
  3864. stf.spill.nta [rpSA2] = f65, HiFltF67-HiFltF65
  3865. ;;
  3866. stf.spill.nta [rpSA1] = f66, HiFltF68-HiFltF66
  3867. stf.spill.nta [rpSA2] = f67, HiFltF69-HiFltF67
  3868. ;;
  3869. stf.spill.nta [rpSA1] = f68, HiFltF70-HiFltF68
  3870. stf.spill.nta [rpSA2] = f69, HiFltF71-HiFltF69
  3871. ;;
  3872. stf.spill.nta [rpSA1] = f70, HiFltF72-HiFltF70
  3873. stf.spill.nta [rpSA2] = f71, HiFltF73-HiFltF71
  3874. ;;
  3875. stf.spill.nta [rpSA1] = f72, HiFltF74-HiFltF72
  3876. stf.spill.nta [rpSA2] = f73, HiFltF75-HiFltF73
  3877. ;;
  3878. stf.spill.nta [rpSA1] = f74, HiFltF76-HiFltF74
  3879. stf.spill.nta [rpSA2] = f75, HiFltF77-HiFltF75
  3880. ;;
  3881. stf.spill.nta [rpSA1] = f76, HiFltF78-HiFltF76
  3882. stf.spill.nta [rpSA2] = f77, HiFltF79-HiFltF77
  3883. ;;
  3884. stf.spill.nta [rpSA1] = f78, HiFltF80-HiFltF78
  3885. stf.spill.nta [rpSA2] = f79, HiFltF81-HiFltF79
  3886. ;;
  3887. stf.spill.nta [rpSA1] = f80, HiFltF82-HiFltF80
  3888. stf.spill.nta [rpSA2] = f81, HiFltF83-HiFltF81
  3889. ;;
  3890. stf.spill.nta [rpSA1] = f82, HiFltF84-HiFltF82
  3891. stf.spill.nta [rpSA2] = f83, HiFltF85-HiFltF83
  3892. ;;
  3893. stf.spill.nta [rpSA1] = f84, HiFltF86-HiFltF84
  3894. stf.spill.nta [rpSA2] = f85, HiFltF87-HiFltF85
  3895. ;;
  3896. stf.spill.nta [rpSA1] = f86, HiFltF88-HiFltF86
  3897. stf.spill.nta [rpSA2] = f87, HiFltF89-HiFltF87
  3898. ;;
  3899. stf.spill.nta [rpSA1] = f88, HiFltF90-HiFltF88
  3900. stf.spill.nta [rpSA2] = f89, HiFltF91-HiFltF89
  3901. ;;
  3902. stf.spill.nta [rpSA1] = f90, HiFltF92-HiFltF90
  3903. stf.spill.nta [rpSA2] = f91, HiFltF93-HiFltF91
  3904. ;;
  3905. stf.spill.nta [rpSA1] = f92, HiFltF94-HiFltF92
  3906. stf.spill.nta [rpSA2] = f93, HiFltF95-HiFltF93
  3907. ;;
  3908. stf.spill.nta [rpSA1] = f94, HiFltF96-HiFltF94
  3909. stf.spill.nta [rpSA2] = f95, HiFltF97-HiFltF95
  3910. ;;
  3911. stf.spill.nta [rpSA1] = f96, HiFltF98-HiFltF96
  3912. stf.spill.nta [rpSA2] = f97, HiFltF99-HiFltF97
  3913. ;;
  3914. stf.spill.nta [rpSA1] = f98, HiFltF100-HiFltF98
  3915. stf.spill.nta [rpSA2] = f99, HiFltF101-HiFltF99
  3916. ;;
  3917. stf.spill.nta [rpSA1] = f100, HiFltF102-HiFltF100
  3918. stf.spill.nta [rpSA2] = f101, HiFltF103-HiFltF101
  3919. ;;
  3920. stf.spill.nta [rpSA1] = f102, HiFltF104-HiFltF102
  3921. stf.spill.nta [rpSA2] = f103, HiFltF105-HiFltF103
  3922. ;;
  3923. stf.spill.nta [rpSA1] = f104, HiFltF106-HiFltF104
  3924. stf.spill.nta [rpSA2] = f105, HiFltF107-HiFltF105
  3925. ;;
  3926. stf.spill.nta [rpSA1] = f106, HiFltF108-HiFltF106
  3927. stf.spill.nta [rpSA2] = f107, HiFltF109-HiFltF107
  3928. ;;
  3929. stf.spill.nta [rpSA1] = f108, HiFltF110-HiFltF108
  3930. stf.spill.nta [rpSA2] = f109, HiFltF111-HiFltF109
  3931. ;;
  3932. stf.spill.nta [rpSA1] = f110, HiFltF112-HiFltF110
  3933. stf.spill.nta [rpSA2] = f111, HiFltF113-HiFltF111
  3934. ;;
  3935. stf.spill.nta [rpSA1] = f112, HiFltF114-HiFltF112
  3936. stf.spill.nta [rpSA2] = f113, HiFltF115-HiFltF113
  3937. ;;
  3938. stf.spill.nta [rpSA1] = f114, HiFltF116-HiFltF114
  3939. stf.spill.nta [rpSA2] = f115, HiFltF117-HiFltF115
  3940. ;;
  3941. stf.spill.nta [rpSA1] = f116, HiFltF118-HiFltF116
  3942. stf.spill.nta [rpSA2] = f117, HiFltF119-HiFltF117
  3943. ;;
  3944. stf.spill.nta [rpSA1] = f118, HiFltF120-HiFltF118
  3945. stf.spill.nta [rpSA2] = f119, HiFltF121-HiFltF119
  3946. ;;
  3947. stf.spill.nta [rpSA1] = f120, HiFltF122-HiFltF120
  3948. stf.spill.nta [rpSA2] = f121, HiFltF123-HiFltF121
  3949. ;;
  3950. stf.spill.nta [rpSA1] = f122, HiFltF124-HiFltF122
  3951. stf.spill.nta [rpSA2] = f123, HiFltF125-HiFltF123
  3952. ;;
  3953. stf.spill.nta [rpSA1] = f124, HiFltF126-HiFltF124
  3954. stf.spill.nta [rpSA2] = f125, HiFltF127-HiFltF125
  3955. ;;
  3956. stf.spill.nta [rpSA1] = f126
  3957. stf.spill.nta [rpSA2] = f127
  3958. //
  3959. // Set DFH bit so the high floating point set may not be used by the kernel
  3960. // Must clear mfh after fp registers saved
  3961. //
  3962. Kshfpv20:
  3963. ssm 1 << PSR_DFH
  3964. ;;
  3965. rum 1 << PSR_MFH
  3966. (pt3) br.ret.sptk brp
  3967. LOWER_IRQL(loc2)
  3968. NESTED_RETURN
  3969. ;;
  3970. LEAF_EXIT(KiSaveHigherFPVolatile)
  3971. //++
  3972. //--------------------------------------------------------------------
  3973. // Routine:
  3974. //
  3975. // KiRestoreHigherFPVolatile()
  3976. //
  3977. // Description:
  3978. //
  3979. // Restore higher FP volatile context from higher FP save area
  3980. //
  3981. // N.B. This function is carefully constructed to use only scratch
  3982. // registers rHpT1, rHpT3, and rTH2. This function may be
  3983. // called by C code and the disabled fp vector when user
  3984. // and kernel bank is used respectively.
  3985. // N.B. Caller must ensure higher fp enabled (psr.dfh=0)
  3986. // N.B. Caller must ensure no interrupt during restore
  3987. //
  3988. // Input:
  3989. //
  3990. // None.
  3991. //
  3992. // Output:
  3993. //
  3994. // None
  3995. //
  3996. // Return value:
  3997. //
  3998. // None
  3999. //
  4000. //--------------------------------------------------------------------
  4001. LEAF_ENTRY(KiRestoreHigherFPVolatile)
  4002. movl rHpT1 = KiPcr+PcCurrentThread
  4003. ;;
  4004. ld8 rHpT3 = [rHpT1], PcHighFpOwner-PcCurrentThread
  4005. ;;
  4006. st8 [rHpT1] = rHpT3, PcNumber-PcHighFpOwner
  4007. add rHpT3 = ThNumber, rHpT3
  4008. ;;
  4009. ld1 rHpT1 = [rHpT1] // load processor #
  4010. ;;
  4011. st1 [rHpT3] = rHpT1 // save it in Thread->Number
  4012. add rHpT3 = ThStackBase-ThNumber, rHpT3
  4013. ;;
  4014. ld8 rHpT3 = [rHpT3] // load kernel stack base
  4015. ;;
  4016. add rHpT1 = -ThreadStateSaveAreaLength+TsHigherFPVolatile+HiFltF32, rHpT3
  4017. add rHpT3 = -ThreadStateSaveAreaLength+TsHigherFPVolatile+HiFltF33, rHpT3
  4018. ;;
  4019. ldf.fill.nta f32 = [rHpT1], HiFltF34-HiFltF32
  4020. ldf.fill.nta f33 = [rHpT3], HiFltF35-HiFltF33
  4021. ;;
  4022. ldf.fill.nta f34 = [rHpT1], HiFltF36-HiFltF34
  4023. ldf.fill.nta f35 = [rHpT3], HiFltF37-HiFltF35
  4024. ;;
  4025. ldf.fill.nta f36 = [rHpT1], HiFltF38-HiFltF36
  4026. ldf.fill.nta f37 = [rHpT3], HiFltF39-HiFltF37
  4027. ;;
  4028. ldf.fill.nta f38 = [rHpT1], HiFltF40-HiFltF38
  4029. ldf.fill.nta f39 = [rHpT3], HiFltF41-HiFltF39
  4030. ;;
  4031. ldf.fill.nta f40 = [rHpT1], HiFltF42-HiFltF40
  4032. ldf.fill.nta f41 = [rHpT3], HiFltF43-HiFltF41
  4033. ;;
  4034. ldf.fill.nta f42 = [rHpT1], HiFltF44-HiFltF42
  4035. ldf.fill.nta f43 = [rHpT3], HiFltF45-HiFltF43
  4036. ;;
  4037. ldf.fill.nta f44 = [rHpT1], HiFltF46-HiFltF44
  4038. ldf.fill.nta f45 = [rHpT3], HiFltF47-HiFltF45
  4039. ;;
  4040. ldf.fill.nta f46 = [rHpT1], HiFltF48-HiFltF46
  4041. ldf.fill.nta f47 = [rHpT3], HiFltF49-HiFltF47
  4042. ;;
  4043. ldf.fill.nta f48 = [rHpT1], HiFltF50-HiFltF48
  4044. ldf.fill.nta f49 = [rHpT3], HiFltF51-HiFltF49
  4045. ;;
  4046. ldf.fill.nta f50 = [rHpT1], HiFltF52-HiFltF50
  4047. ldf.fill.nta f51 = [rHpT3], HiFltF53-HiFltF51
  4048. ;;
  4049. ldf.fill.nta f52 = [rHpT1], HiFltF54-HiFltF52
  4050. ldf.fill.nta f53 = [rHpT3], HiFltF55-HiFltF53
  4051. ;;
  4052. ldf.fill.nta f54 = [rHpT1], HiFltF56-HiFltF54
  4053. ldf.fill.nta f55 = [rHpT3], HiFltF57-HiFltF55
  4054. ;;
  4055. ldf.fill.nta f56 = [rHpT1], HiFltF58-HiFltF56
  4056. ldf.fill.nta f57 = [rHpT3], HiFltF59-HiFltF57
  4057. ;;
  4058. ldf.fill.nta f58 = [rHpT1], HiFltF60-HiFltF58
  4059. ldf.fill.nta f59 = [rHpT3], HiFltF61-HiFltF59
  4060. ;;
  4061. ldf.fill.nta f60 = [rHpT1], HiFltF62-HiFltF60
  4062. ldf.fill.nta f61 = [rHpT3], HiFltF63-HiFltF61
  4063. ;;
  4064. ldf.fill.nta f62 = [rHpT1], HiFltF64-HiFltF62
  4065. ldf.fill.nta f63 = [rHpT3], HiFltF65-HiFltF63
  4066. ;;
  4067. ldf.fill.nta f64 = [rHpT1], HiFltF66-HiFltF64
  4068. ldf.fill.nta f65 = [rHpT3], HiFltF67-HiFltF65
  4069. ;;
  4070. ldf.fill.nta f66 = [rHpT1], HiFltF68-HiFltF66
  4071. ldf.fill.nta f67 = [rHpT3], HiFltF69-HiFltF67
  4072. ;;
  4073. ldf.fill.nta f68 = [rHpT1], HiFltF70-HiFltF68
  4074. ldf.fill.nta f69 = [rHpT3], HiFltF71-HiFltF69
  4075. ;;
  4076. ldf.fill.nta f70 = [rHpT1], HiFltF72-HiFltF70
  4077. ldf.fill.nta f71 = [rHpT3], HiFltF73-HiFltF71
  4078. ;;
  4079. ldf.fill.nta f72 = [rHpT1], HiFltF74-HiFltF72
  4080. ldf.fill.nta f73 = [rHpT3], HiFltF75-HiFltF73
  4081. ;;
  4082. ldf.fill.nta f74 = [rHpT1], HiFltF76-HiFltF74
  4083. ldf.fill.nta f75 = [rHpT3], HiFltF77-HiFltF75
  4084. ;;
  4085. ldf.fill.nta f76 = [rHpT1], HiFltF78-HiFltF76
  4086. ldf.fill.nta f77 = [rHpT3], HiFltF79-HiFltF77
  4087. ;;
  4088. ldf.fill.nta f78 = [rHpT1], HiFltF80-HiFltF78
  4089. ldf.fill.nta f79 = [rHpT3], HiFltF81-HiFltF79
  4090. ;;
  4091. ldf.fill.nta f80 = [rHpT1], HiFltF82-HiFltF80
  4092. ldf.fill.nta f81 = [rHpT3], HiFltF83-HiFltF81
  4093. ;;
  4094. ldf.fill.nta f82 = [rHpT1], HiFltF84-HiFltF82
  4095. ldf.fill.nta f83 = [rHpT3], HiFltF85-HiFltF83
  4096. ;;
  4097. ldf.fill.nta f84 = [rHpT1], HiFltF86-HiFltF84
  4098. ldf.fill.nta f85 = [rHpT3], HiFltF87-HiFltF85
  4099. ;;
  4100. ldf.fill.nta f86 = [rHpT1], HiFltF88-HiFltF86
  4101. ldf.fill.nta f87 = [rHpT3], HiFltF89-HiFltF87
  4102. ;;
  4103. ldf.fill.nta f88 = [rHpT1], HiFltF90-HiFltF88
  4104. ldf.fill.nta f89 = [rHpT3], HiFltF91-HiFltF89
  4105. ;;
  4106. ldf.fill.nta f90 = [rHpT1], HiFltF92-HiFltF90
  4107. ldf.fill.nta f91 = [rHpT3], HiFltF93-HiFltF91
  4108. ;;
  4109. ldf.fill.nta f92 = [rHpT1], HiFltF94-HiFltF92
  4110. ldf.fill.nta f93 = [rHpT3], HiFltF95-HiFltF93
  4111. ;;
  4112. ldf.fill.nta f94 = [rHpT1], HiFltF96-HiFltF94
  4113. ldf.fill.nta f95 = [rHpT3], HiFltF97-HiFltF95
  4114. ;;
  4115. ldf.fill.nta f96 = [rHpT1], HiFltF98-HiFltF96
  4116. ldf.fill.nta f97 = [rHpT3], HiFltF99-HiFltF97
  4117. ;;
  4118. ldf.fill.nta f98 = [rHpT1], HiFltF100-HiFltF98
  4119. ldf.fill.nta f99 = [rHpT3], HiFltF101-HiFltF99
  4120. ;;
  4121. ldf.fill.nta f100 = [rHpT1], HiFltF102-HiFltF100
  4122. ldf.fill.nta f101 = [rHpT3], HiFltF103-HiFltF101
  4123. ;;
  4124. ldf.fill.nta f102 = [rHpT1], HiFltF104-HiFltF102
  4125. ldf.fill.nta f103 = [rHpT3], HiFltF105-HiFltF103
  4126. ;;
  4127. ldf.fill.nta f104 = [rHpT1], HiFltF106-HiFltF104
  4128. ldf.fill.nta f105 = [rHpT3], HiFltF107-HiFltF105
  4129. ;;
  4130. ldf.fill.nta f106 = [rHpT1], HiFltF108-HiFltF106
  4131. ldf.fill.nta f107 = [rHpT3], HiFltF109-HiFltF107
  4132. ;;
  4133. ldf.fill.nta f108 = [rHpT1], HiFltF110-HiFltF108
  4134. ldf.fill.nta f109 = [rHpT3], HiFltF111-HiFltF109
  4135. ;;
  4136. ldf.fill.nta f110 = [rHpT1], HiFltF112-HiFltF110
  4137. ldf.fill.nta f111 = [rHpT3], HiFltF113-HiFltF111
  4138. ;;
  4139. ldf.fill.nta f112 = [rHpT1], HiFltF114-HiFltF112
  4140. ldf.fill.nta f113 = [rHpT3], HiFltF115-HiFltF113
  4141. ;;
  4142. ldf.fill.nta f114 = [rHpT1], HiFltF116-HiFltF114
  4143. ldf.fill.nta f115 = [rHpT3], HiFltF117-HiFltF115
  4144. ;;
  4145. ldf.fill.nta f116 = [rHpT1], HiFltF118-HiFltF116
  4146. ldf.fill.nta f117 = [rHpT3], HiFltF119-HiFltF117
  4147. ;;
  4148. ldf.fill.nta f118 = [rHpT1], HiFltF120-HiFltF118
  4149. ldf.fill.nta f119 = [rHpT3], HiFltF121-HiFltF119
  4150. ;;
  4151. ldf.fill.nta f120 = [rHpT1], HiFltF122-HiFltF120
  4152. ldf.fill.nta f121 = [rHpT3], HiFltF123-HiFltF121
  4153. ;;
  4154. ldf.fill.nta f122 = [rHpT1], HiFltF124-HiFltF122
  4155. ldf.fill.nta f123 = [rHpT3], HiFltF125-HiFltF123
  4156. ;;
  4157. ldf.fill.nta f124 = [rHpT1], HiFltF126-HiFltF124
  4158. ldf.fill.nta f125 = [rHpT3], HiFltF127-HiFltF125
  4159. ;;
  4160. ldf.fill.nta f126 = [rHpT1]
  4161. ldf.fill.nta f127 = [rHpT3]
  4162. ;;
  4163. rsm 1 << PSR_MFH // clear psr.mfh bit
  4164. br.ret.sptk brp
  4165. ;;
  4166. LEAF_EXIT(KiRestoreHigherFPVolatile)
  4167. //
  4168. // ++
  4169. //
  4170. // Routine:
  4171. //
  4172. // KiPageTableFault
  4173. //
  4174. // Description:
  4175. //
  4176. // Branched from Inst/DataTlbVector
  4177. // Inserts a missing PDE translation for VHPT mapping
  4178. // If PageNotPresent-bit of PDE is not set,
  4179. // branchs out to KiPdeNotPresentFault
  4180. //
  4181. // On entry:
  4182. //
  4183. // rva (h24) : offending virtual address
  4184. // riha (h25) : a offending PTE address
  4185. // rpr: (h26) : saved predicate
  4186. //
  4187. // Handle:
  4188. //
  4189. // Extracts the PDE index from riha (PTE address in VHPT) and
  4190. // generates a PDE address by adding to VHPT_DIRBASE. When accesses
  4191. // a page directory entry (PDE), there might be a TLB miss on the
  4192. // page directory table and returns a NaT on ld8.s. If so, branches
  4193. // to KiPageDirectoryTableFault. If the page-not-present bit of the
  4194. // PDE is not set, branches to KiPageNotPresentFault. Otherwise,
  4195. // inserts the PDE entry into the data TC (translation cache).
  4196. //
  4197. // Notes:
  4198. //
  4199. //
  4200. // --
  4201. HANDLER_ENTRY(KiPageTableFault)
  4202. rva = h24
  4203. riha = h25
  4204. rpr = h26
  4205. rpPde = h27
  4206. rPde = h28
  4207. rPde2 = h29
  4208. rps = h30
  4209. thash rpPde = riha // M
  4210. cmp.ne pt1 = r0, r0
  4211. mov rps = PAGE_SHIFT << PS_SHIFT // I
  4212. ;;
  4213. mov cr.itir = rps // M
  4214. ld8.s rPde = [rpPde] // M, load PDE
  4215. ;;
  4216. tnat.nz pt0, p0 = rPde // I
  4217. tbit.z.or pt1, p0 = rPde, PTE_ACCESS
  4218. tbit.z.or pt1, p0 = rPde, PTE_VALID // I, if non-present page fault
  4219. (pt0) br.cond.spnt KiPageDirectoryFault // B, tb miss on PDE access
  4220. (pt1) br.cond.spnt KiPdeNotPresentFault // B, page fault
  4221. ;;
  4222. mov cr.ifa = riha // M
  4223. ;;
  4224. itc.d rPde // M
  4225. ;;
  4226. #if !defined(NT_UP)
  4227. ld8.s rPde2 = [rpPde] // M
  4228. cmp.ne pt0 = zero, zero // I
  4229. ;;
  4230. cmp.ne.or pt0, p0 = rPde2, rPde // I, if PTEs are different
  4231. tnat.nz.or pt0, p0 = rPde2 // I
  4232. ;;
  4233. (pt0) ptc.l riha, rps // M, purge it
  4234. #endif
  4235. mov pr = rpr, -1 // I
  4236. rfi;; // B
  4237. HANDLER_EXIT(KiPageTableFault)
  4238. //++
  4239. //
  4240. // KiPageDirectoryFault
  4241. //
  4242. // Cause:
  4243. //
  4244. // Parameters:
  4245. // rpPde (h28) : pointer to PDE entry
  4246. // rpr (h26) : saved predicate
  4247. //
  4248. //
  4249. // Handle:
  4250. //
  4251. //--
  4252. HANDLER_ENTRY(KiPageDirectoryFault)
  4253. rva = h24
  4254. rpPpe = h25
  4255. rpr = h26
  4256. rpPde = h27
  4257. rPpe = h28
  4258. rPpe2 = h29
  4259. rps = h30
  4260. thash rpPpe = rpPde // M
  4261. cmp.ne pt1 = r0, r0
  4262. ;;
  4263. ld8.s rPpe = [rpPpe] // M
  4264. ;;
  4265. tnat.nz pt0, p0 = rPpe // I
  4266. tbit.z.or pt1, p0 = rPpe, PTE_ACCESS
  4267. tbit.z.or pt1, p0 = rPpe, PTE_VALID // I, if non-present page fault
  4268. (pt0) br.cond.spnt KiPageFault // B
  4269. (pt1) br.cond.spnt KiPdeNotPresentFault // B
  4270. ;;
  4271. mov cr.ifa = rpPde // M, set tva for vhpt translation
  4272. ;;
  4273. itc.d rPpe // M
  4274. ;;
  4275. #if !defined(NT_UP)
  4276. ld8.s rPpe2 = [rpPpe] // M
  4277. mov rps = PAGE_SHIFT << PS_SHIFT // I
  4278. cmp.ne pt0 = zero, zero // I
  4279. ;;
  4280. cmp.ne.or pt0, p0 = rPpe2, rPpe // I, if PTEs are different
  4281. tnat.nz.or pt0, p0 = rPpe2 // I
  4282. ;;
  4283. (pt0) ptc.l rpPde, rps // M, purge it
  4284. #endif
  4285. mov pr = rpr, -1 // I
  4286. rfi;; // B
  4287. HANDLER_EXIT(KiPageDirectoryFault)
  4288. //
  4289. // ++
  4290. //
  4291. // Routine:
  4292. //
  4293. // KiPteNotPresentFault
  4294. //
  4295. // Description:
  4296. //
  4297. // Branched from KiVhptTransVector and KiPageTableFault.
  4298. // Inserts a missing PDE translation for VHPT mapping
  4299. // If no PDE for it, branchs out to KiPageFault
  4300. //
  4301. // On entry:
  4302. //
  4303. // rva (h24) : offending virtual address
  4304. // rpr (h26) : saved predicate
  4305. // rPde (h28) : PDE entry
  4306. //
  4307. // Handle:
  4308. //
  4309. // Check to see if PDE is marked as LARGE_PAGE. If so,
  4310. // make it valid and install the large page size PTE.
  4311. // If not, branch to KiPageFault.
  4312. //
  4313. //
  4314. // Notes:
  4315. //
  4316. // PCR page mapped with TR
  4317. // --
  4318. HANDLER_ENTRY(KiPteNotPresentFault)
  4319. rva = h24 // passed
  4320. riha = h25 // passed
  4321. rpr = h26 // passed
  4322. rps = h27
  4323. rPfn = h28
  4324. rpAte = h28
  4325. rAte = h29
  4326. rAteEnd = h30
  4327. rAteBase = h31
  4328. rAteMask = h22
  4329. rK0Base = h31
  4330. rK2Base = h30
  4331. pIndr = pt1
  4332. mov rps = PS_4K << PS_SHIFT // M
  4333. movl rK0Base = KSEG0_BASE // L
  4334. ;;
  4335. cmp.geu pt3, p0 = rva, rK0Base // M
  4336. movl rK2Base = KSEG2_BASE // L
  4337. ;;
  4338. (pt3) cmp.ltu pt3, p0 = rva, rK2Base // M
  4339. movl rAteBase = ALT4KB_BASE // L
  4340. ;;
  4341. shr.u rPfn = rva, PAGE4K_SHIFT // I
  4342. (pt3) br.cond.spnt KiKseg0Fault // B
  4343. ;;
  4344. mov rAteMask = ATE_MASK0 // I
  4345. shladd rpAte = rPfn, PTE_SHIFT, rAteBase // M
  4346. movl rAteEnd = ALT4KB_END // L
  4347. ;;
  4348. ld8.s rAte = [rpAte] // M
  4349. andcm rAteMask = -1, rAteMask // I
  4350. cmp.ltu pIndr = rpAte, rAteEnd // I
  4351. ;;
  4352. tnat.z.and pIndr = rAte // I
  4353. tbit.nz.and pIndr = rAte, PTE_VALID // I
  4354. or rAteMask = rAte, rAteMask // M
  4355. tbit.nz.and pIndr = rAte, PTE_ACCESS // I
  4356. tbit.nz.and pIndr = rAte, ATE_INDIRECT // I
  4357. (pIndr) br.cond.spnt KiPteIndirectFault
  4358. ;;
  4359. ptc.l rva, rps // M
  4360. br.sptk KiPageFault // B
  4361. HANDLER_EXIT(KiPteNotPresentFault)
  4362. //
  4363. // ++
  4364. //
  4365. // Routine:
  4366. //
  4367. // KiPdeNotPresentFault
  4368. //
  4369. // Description:
  4370. //
  4371. // Branched from KiVhptTransVector and KiPageTableFault.
  4372. // Inserts a missing PDE translation for VHPT mapping
  4373. // If no PDE for it, branchs out to KiPageFault
  4374. //
  4375. // On entry:
  4376. //
  4377. // rva (h24) : offending virtual address
  4378. // rpr (h26) : saved predicate
  4379. // rPde (h28) : PDE entry
  4380. //
  4381. // Handle:
  4382. //
  4383. // Check to see if PDE is marked as LARGE_PAGE. If so,
  4384. // make it valid and install the large page size PTE.
  4385. // If not, branch to KiPageFault.
  4386. //
  4387. //
  4388. // Notes:
  4389. //
  4390. // PCR page mapped with TR
  4391. // --
  4392. HANDLER_ENTRY(KiPdeNotPresentFault)
  4393. br.sptk KiPageFault
  4394. #if 0
  4395. rva = h24
  4396. rK0Base = h25
  4397. rpr = h26
  4398. rK2Base = h27
  4399. rPde = h28
  4400. ridtr = h29
  4401. rps = h30
  4402. rPte = h25
  4403. movl rK0Base = KSEG0_BASE
  4404. ;;
  4405. cmp.ltu pt3, pt4 = rva, rK0Base
  4406. movl rK2Base = KSEG2_BASE
  4407. ;;
  4408. (pt4) cmp.geu pt3, p0 = rva, rK2Base
  4409. (pt3) br.cond.spnt KiPageFault
  4410. mov ridtr = cr.itir
  4411. shr.u rPde = rva, PAGE_SHIFT
  4412. mov rps = 24
  4413. ;;
  4414. movl rPte = VALID_KERNEL_PTE
  4415. dep.z rPde = rPde, PAGE_SHIFT, 28 - PAGE_SHIFT
  4416. dep ridtr = rps, ridtr, PS_SHIFT, PS_LEN
  4417. ;;
  4418. mov cr.itir = ridtr
  4419. or rPde = rPte, rPde
  4420. ;;
  4421. itc.d rPde
  4422. ;;
  4423. mov pr = rpr, -1
  4424. rfi;;
  4425. #endif
  4426. HANDLER_EXIT(KiPdeNotPresentFault)
  4427. //
  4428. // ++
  4429. //
  4430. // Routine:
  4431. //
  4432. // KiKseg0Fault
  4433. //
  4434. // Description:
  4435. //
  4436. // TLB miss on KSEG0 space
  4437. //
  4438. //
  4439. // On entry:
  4440. //
  4441. // rva (h24) : faulting virtual address
  4442. // riha (h25) : IHA address
  4443. // rpr (h26) : saved predicate
  4444. //
  4445. // Process:
  4446. //
  4447. //
  4448. // Notes:
  4449. //
  4450. // PCR page mapped with TR
  4451. // --
  4452. HANDLER_ENTRY(KiKseg0Fault)
  4453. rISR = h30
  4454. rva = h24 // passed
  4455. riha = h25 // passed
  4456. rpr = h26 // passed
  4457. rps = h27
  4458. rPte = h29
  4459. rITIR = h28
  4460. rPs = h30
  4461. rPte0 = h31
  4462. mov rISR = cr.isr // M
  4463. ld8.s rPte = [riha] // M
  4464. cmp.ne pt1 = r0, r0 // I, pt1 = 0
  4465. ;;
  4466. or rPte0 = PTE_VALID_MASK, rPte // M
  4467. tbit.z pt2, pt3 = rISR, ISR_SP // I
  4468. tbit.z.or pt1 = rPte, PTE_LARGE_PAGE // I
  4469. tbit.nz.or pt1 = rPte, PTE_VALID // I
  4470. tnat.nz pt4 = rPte // I
  4471. (pt4) br.cond.spnt KiPageTableFault // B, tb miss on PTE access
  4472. ;;
  4473. rIPSR = h25
  4474. mov rIPSR = cr.ipsr // M
  4475. extr rPs = rPte, PTE_PS, PS_LEN // I
  4476. (pt1) br.cond.spnt KiPageFault // B, invalid access
  4477. ;;
  4478. dep.z rITIR = rPs, PS_SHIFT, PS_LEN // I
  4479. ;;
  4480. (pt2) mov cr.itir = rITIR // M
  4481. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  4482. ;;
  4483. (pt2) itc.d rPte0 // M
  4484. ;;
  4485. (pt3) mov cr.ipsr = rIPSR // M
  4486. ;;
  4487. mov pr = rpr, -1 // I
  4488. rfi // B
  4489. ;;
  4490. HANDLER_EXIT(KiKseg0Fault)
  4491. //
  4492. // ++
  4493. //
  4494. // Routine:
  4495. //
  4496. // KiKseg4Fault
  4497. //
  4498. // Description:
  4499. //
  4500. // TLB miss on KSEG4 space
  4501. //
  4502. //
  4503. // On entry:
  4504. //
  4505. // rva (h24) : faulting virtual address
  4506. // riha (h25) : IHA address
  4507. // rpr (h26) : saved predicate
  4508. //
  4509. // Process:
  4510. //
  4511. //
  4512. // Notes:
  4513. //
  4514. // PCR page mapped with TR
  4515. // --
  4516. HANDLER_ENTRY(KiKseg4Fault)
  4517. rIPSR = h22
  4518. rISR = h23
  4519. rva = h24 // passed
  4520. riha = h25
  4521. rpr = h26 // passed
  4522. rPte = h27
  4523. mov rISR = cr.isr // M
  4524. movl rPte = VALID_KERNEL_PTE | PTE_NOCACHE // L
  4525. mov rIPSR = cr.ipsr // M
  4526. shr.u rva = rva, PAGE_SHIFT // I
  4527. ;;
  4528. tbit.z pt2, pt3 = rISR, ISR_SP // I
  4529. dep.z rva = rva, PAGE_SHIFT, 32 // I
  4530. ;;
  4531. or rPte = rPte, rva // I
  4532. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  4533. ;;
  4534. (pt2) itc.d rPte // M
  4535. ;;
  4536. (pt3) mov cr.ipsr = rIPSR // M
  4537. ;;
  4538. mov pr = rpr, -1 // I
  4539. rfi // B
  4540. ;;
  4541. HANDLER_EXIT(KiKseg4Fault)
  4542. //
  4543. // ++
  4544. //
  4545. // Routine:
  4546. //
  4547. // KiPageFault
  4548. //
  4549. // Description:
  4550. //
  4551. // This must be a genuine page fault. Call KiMemoryFault().
  4552. //
  4553. //
  4554. // On entry:
  4555. //
  4556. // rva (h24) : offending virtual address
  4557. // rpr (h26) : PDE contents
  4558. //
  4559. // Process:
  4560. //
  4561. // Restores the save predicate (pr), and branches to
  4562. // KiGenericExceptionHandler with the argument KiMemoryFault with
  4563. // macro VECTOR_CALL_HANDLER().
  4564. //
  4565. // Notes:
  4566. //
  4567. // PCR page mapped with TR
  4568. // --
  4569. HANDLER_ENTRY(KiPageFault)
  4570. rva = h24
  4571. rpr = h26
  4572. rIPSR = h27
  4573. rISR = h31
  4574. //
  4575. // check to see if non-present fault occurred on a speculative load.
  4576. // if so, set IPSR.ed bit. This forces to generate a NaT on ld.s after
  4577. // rfi
  4578. //
  4579. mov rISR = cr.isr // M
  4580. mov rIPSR = cr.ipsr // M
  4581. ;;
  4582. tbit.z pt0, p0 = rISR, ISR_SP // I
  4583. dep rIPSR = 1, rIPSR, PSR_ED, 1 // I
  4584. (pt0) br.cond.spnt KiCallMemoryFault // B
  4585. ;;
  4586. mov cr.ipsr = rIPSR // M
  4587. ;;
  4588. mov pr = rpr, -1 // I
  4589. rfi // B
  4590. ;;
  4591. KiCallMemoryFault:
  4592. mov pr = rpr, -1 // I
  4593. VECTOR_CALL_HANDLER(KiGenericExceptionHandler, KiMemoryFault)
  4594. HANDLER_EXIT(KiPageFault)
  4595. //
  4596. // ++
  4597. //
  4598. // Routine:
  4599. //
  4600. // KiPteIndirectFault
  4601. //
  4602. // Description:
  4603. //
  4604. // The PTE itself indicates a PteIndirect fault. The target PTE address
  4605. // should be generated by extracting PteOffset from PTE and adding it to
  4606. // PTE_UBASE. The owner field of the target PTE must be 1. Otherwise,
  4607. // Call MmX86Fault().
  4608. //
  4609. // On entry:
  4610. //
  4611. // rva (h24) : offending virtual address
  4612. // rpr (h26) : PDE contents
  4613. //
  4614. // Process:
  4615. //
  4616. // Restores the save predicate (pr), and branches to
  4617. // KiGenericExceptionHandler with the argument KiMemoryFault with
  4618. // macro VECTOR_CALL_HANDLER().
  4619. //
  4620. // Notes:
  4621. //
  4622. // PCR page mapped with TR
  4623. // --
  4624. HANDLER_ENTRY(KiPteIndirectFault)
  4625. rpr = h26 // passed
  4626. rps = h27 // passed
  4627. rpAte = h28 // passed
  4628. rAte = h29 // passed
  4629. rPte = h30
  4630. rPte0 = h31
  4631. rAteMask = h22 // passed
  4632. rVa12 = h23
  4633. rPteOffset = h23
  4634. rpNewPte = h21
  4635. rOldIIP = h17 // preserved
  4636. rIA32IIP = h18
  4637. rpVa = h19 // preserved
  4638. rIndex = h20 // preserved
  4639. rpBuffer= h16
  4640. rpPte = h22
  4641. pBr = pt0
  4642. pPrg = pt3
  4643. pLoop = pt4
  4644. pClear = pt5
  4645. mov cr.itir = rps // M
  4646. thash rpNewPte = r0 // M
  4647. mov rIA32IIP = cr.iip // M
  4648. extr.u rPteOffset = rAte, PAGE4K_SHIFT, 32 // I
  4649. ;;
  4650. add rpNewPte = rPteOffset, rpNewPte // M/I
  4651. cmp.eq pLoop, pClear = rIA32IIP, rOldIIP // I
  4652. ;;
  4653. ld8.s rPte = [rpNewPte] // M
  4654. shr rVa12 = rpAte, PTE_SHIFT // I
  4655. ;;
  4656. tnat.nz.or pBr = rPte // I
  4657. tbit.z.or pBr = rPte, PTE_VALID // I
  4658. tbit.z.or pBr = rPte, PTE_ACCESS // I
  4659. (pBr) br.cond.spnt KiPageFault
  4660. ;;
  4661. (pClear)mov rIndex = 0 // M
  4662. and rPte0 = rPte, rAteMask // I
  4663. ;;
  4664. //
  4665. // deposit extra PFN bits for 4k page
  4666. //
  4667. dep rPte0 = rVa12, rPte0, PAGE4K_SHIFT, PAGE_SHIFT-PAGE4K_SHIFT // I
  4668. ;;
  4669. (pClear)itc.d rPte0 // M
  4670. ;;
  4671. and rIndex = 7, rIndex // A
  4672. movl rpBuffer = KiPcr + PcForwardProgressBuffer // L
  4673. ;;
  4674. shladd rpVa = rIndex, 4, rpBuffer // M
  4675. add rIndex = 1, rIndex // I
  4676. ;;
  4677. st8 [rpVa] = rva // M
  4678. add rpPte = 8, rpVa // I
  4679. ;;
  4680. st8 [rpPte] = rPte0 // M
  4681. mf // M
  4682. mov rOldIIP = rIA32IIP // I
  4683. #if !defined(NT_UP)
  4684. rAte2 = h28
  4685. rPte2 = h31
  4686. ld8.s rPte2 = [rpNewPte] // M
  4687. ld8.s rAte2 = [rpAte] // M
  4688. cmp.ne pPrg = zero, zero // I
  4689. ;;
  4690. cmp.ne.or pPrg = rPte, rPte2 // I
  4691. tnat.nz.or pPrg = rPte2 // I
  4692. cmp.ne.or pPrg = rAte, rAte2 // I
  4693. tnat.nz.or pPrg = rAte2 // I
  4694. ;;
  4695. (pPrg) ptc.l rva, rps // M
  4696. (pPrg) st8 [rpPte] = r0 // M
  4697. #endif
  4698. (pLoop) br.cond.spnt KiFillForwardProgressTb // B
  4699. mov pr = rpr, -1 // I
  4700. rfi;; // B
  4701. HANDLER_EXIT(KiPteIndirectFault)
  4702. //
  4703. // ++
  4704. //
  4705. // Routine:
  4706. //
  4707. // Ki4KDataTlbFault
  4708. //
  4709. // Description:
  4710. //
  4711. // Branched from KiDataTlbVector if PTE.Cache indicates the reserved
  4712. // encoding. Reads the corresponding ATE and creates a 4kb TB on the
  4713. // fly inserts it to the TLB. If a looping condition at IIP is
  4714. // detected, it branches to KiFillForwardProgressTb and insert the TBs
  4715. // from the forward progress TB queue.
  4716. //
  4717. // On entry:
  4718. //
  4719. // rva (h24) : offending virtual address
  4720. // riha(h25) : IHA address
  4721. // rpr (h26) : PDE contents
  4722. //
  4723. // Notes:
  4724. //
  4725. // --
  4726. HANDLER_ENTRY(Ki4KDataTlbFault)
  4727. rva = h24 // passed
  4728. riha = h25 // passed
  4729. rpr = h26 // passed
  4730. rps = h27
  4731. rPfn = h28
  4732. rpAte = h28
  4733. rAte = h29
  4734. rPte = h30
  4735. rAltBase = h31
  4736. rPte0 = h31
  4737. rAteMask = h22
  4738. rVa12 = h23
  4739. rOldIIP = h17 // preserved
  4740. rIA32IIP = h18
  4741. rpVa = h19
  4742. rIndex = h20 // preserved
  4743. rpBuffer= h16
  4744. rpPte = h21
  4745. pBr = pt0
  4746. pIndr = pt1
  4747. pMiss = pt2
  4748. pPrg = pt3
  4749. pLoop = pt4
  4750. pClear = pt5
  4751. pMiss2 = pt6
  4752. mov rIA32IIP = cr.iip // M
  4753. mov rps = PS_4K << PS_SHIFT // I
  4754. shr.u rPfn = rva, PAGE4K_SHIFT // I
  4755. cmp.ne pBr = zero, zero // M/I, initialize to 0
  4756. movl rAltBase = ALT4KB_BASE // L
  4757. ;;
  4758. ld8.s rPte = [riha] // M
  4759. shladd rpAte = rPfn, PTE_SHIFT, rAltBase // I
  4760. ;;
  4761. ld8.s rAte = [rpAte] // M
  4762. movl rAteMask = ATE_MASK // L
  4763. ;;
  4764. cmp.eq pLoop, pClear = rIA32IIP, rOldIIP// M
  4765. tnat.nz pMiss = rPte // I
  4766. (pMiss) br.cond.spnt KiPageTableFault // B
  4767. tnat.nz pMiss2 = rAte // I
  4768. (pMiss2)br.cond.spnt KiAltTableFault // B
  4769. tbit.z.or pBr = rPte, PTE_VALID // I
  4770. tbit.z.or pBr = rAte, PTE_VALID // I
  4771. tbit.z.or pBr = rAte, PTE_ACCESS // I
  4772. or rAteMask = rAte, rAteMask // M
  4773. tbit.nz pIndr, p0 = rAte, ATE_INDIRECT // I
  4774. (pBr) br.cond.spnt KiPageFault // B
  4775. dep rPte0 = 0, rPte, 2, 3 // I, make it WB
  4776. shr rVa12 = rpAte, PTE_SHIFT // I
  4777. (pIndr) br.cond.spnt KiPteIndirectFault // B
  4778. ;;
  4779. (pClear)mov rIndex = 0 // M
  4780. mov cr.itir = rps // M
  4781. and rPte0 = rPte0, rAteMask // I
  4782. ;;
  4783. //
  4784. // deposit extra PFN bits for 4k page
  4785. //
  4786. dep rPte0 = rVa12, rPte0, PAGE4K_SHIFT, PAGE_SHIFT-PAGE4K_SHIFT // I
  4787. ;;
  4788. (pClear)itc.d rPte0 // M, install PTE
  4789. ;;
  4790. and rIndex = 7, rIndex // A
  4791. movl rpBuffer = KiPcr + PcForwardProgressBuffer // L
  4792. ;;
  4793. shladd rpVa = rIndex, 4, rpBuffer // M
  4794. add rIndex = 1, rIndex // I
  4795. ;;
  4796. st8 [rpVa] = rva // M
  4797. add rpPte = 8, rpVa // I
  4798. ;;
  4799. st8 [rpPte] = rPte0 // M
  4800. mf // M
  4801. mov rOldIIP = rIA32IIP // I
  4802. #if !defined(NT_UP)
  4803. rps = h27
  4804. rAte2 = h28
  4805. rPte2 = h31
  4806. ld8.s rPte2 = [riha] // M
  4807. ld8.s rAte2 = [rpAte] // M
  4808. cmp.ne pPrg = zero, zero // I
  4809. ;;
  4810. cmp.ne.or pPrg = rPte, rPte2 // M
  4811. tnat.nz.or pPrg = rPte2 // I
  4812. cmp.ne.or pPrg = rAte, rAte2 // M
  4813. tnat.nz.or pPrg = rAte2 // I
  4814. ;;
  4815. (pPrg) ptc.l rva, rps // M
  4816. (pPrg) st8 [rpPte] = r0 // M
  4817. #endif
  4818. (pLoop) br.cond.spnt KiFillForwardProgressTb // B
  4819. mov pr = rpr, -1 // I
  4820. rfi;; // B
  4821. HANDLER_EXIT(Ki4KDataTlbFault)
  4822. //
  4823. // ++
  4824. //
  4825. // Routine:
  4826. //
  4827. // Ki4KInstTlbFault
  4828. //
  4829. // Description:
  4830. //
  4831. // Branched from KiInstTlbVector if PTE.Cache indicates the reserved
  4832. // encoding. Reads the corresponding ATE and creates a 4kb TB on the
  4833. // fly inserts it to the TLB.
  4834. //
  4835. // On entry:
  4836. //
  4837. // rva (h24) : offending virtual address
  4838. // riha(h25) : IHA address
  4839. // rpr (h26) : PDE contents
  4840. //
  4841. // Notes:
  4842. //
  4843. // --
  4844. HANDLER_ENTRY(Ki4KInstTlbFault)
  4845. rva = h24 // passed
  4846. riha = h25 // passed
  4847. rpr = h26 // passed
  4848. rps = h27
  4849. rPfn = h28
  4850. rpAte = h28
  4851. rAte = h29
  4852. rPte = h30
  4853. rAltBase = h31
  4854. rPte0 = h31
  4855. rAteMask = h22
  4856. rVa12 = h23
  4857. pBr = pt0
  4858. pIndr = pt1
  4859. pMiss = pt2
  4860. pPrg = pt3
  4861. pMiss2 = pt6
  4862. mov rps = PS_4K << PS_SHIFT // M
  4863. movl rAltBase = ALT4KB_BASE // L
  4864. shr.u rPfn = rva, PAGE4K_SHIFT // I
  4865. ;;
  4866. ld8.s rPte = [riha] // M
  4867. cmp.ne pBr = zero, zero // M/I, initialize to 0
  4868. shladd rpAte = rPfn, PTE_SHIFT, rAltBase // I
  4869. ;;
  4870. ld8.s rAte = [rpAte] // M
  4871. movl rAteMask = ATE_MASK // L
  4872. ;;
  4873. tnat.nz pMiss = rPte // I
  4874. (pMiss) br.cond.spnt KiPageTableFault // B
  4875. tnat.nz pMiss2 = rAte // I
  4876. (pMiss2)br.cond.spnt KiAltTableFault // B
  4877. tbit.z.or pBr = rPte, PTE_VALID // I
  4878. tbit.z.or pBr = rAte, PTE_VALID // I
  4879. tbit.z.or pBr = rAte, PTE_ACCESS // I
  4880. or rAteMask = rAte, rAteMask // M
  4881. tbit.nz pIndr, p0 = rAte, ATE_INDIRECT // I
  4882. (pBr) br.cond.spnt KiPageFault // B
  4883. dep rPte0 = 0, rPte, 2, 3 // I, make it WB
  4884. shr rVa12 = rpAte, PTE_SHIFT // I
  4885. (pIndr) br.cond.spnt KiPteIndirectFault // B
  4886. ;;
  4887. mov cr.itir = rps // M
  4888. and rPte0 = rPte0, rAteMask // I
  4889. ;;
  4890. //
  4891. // deposit extra PFN bits for 4k page
  4892. //
  4893. dep rPte0 = rVa12, rPte0, PAGE4K_SHIFT, PAGE_SHIFT-PAGE4K_SHIFT // I
  4894. ;;
  4895. itc.i rPte0 // M, install PTE
  4896. ;;
  4897. #if !defined(NT_UP)
  4898. rps = h27
  4899. rAte2 = h28
  4900. rPte2 = h31
  4901. ld8.s rPte2 = [riha] // M
  4902. ld8.s rAte2 = [rpAte] // M
  4903. cmp.ne pPrg = zero, zero // I
  4904. ;;
  4905. cmp.ne.or pPrg = rPte, rPte2 // M
  4906. tnat.nz.or pPrg = rPte2 // I
  4907. cmp.ne.or pPrg = rAte, rAte2 // M
  4908. tnat.nz.or pPrg = rAte2 // I
  4909. ;;
  4910. (pPrg) ptc.l rva, rps // M
  4911. #endif
  4912. mov pr = rpr, -1 // I
  4913. rfi;; // B
  4914. HANDLER_EXIT(Ki4KInstTlbFault)
  4915. //
  4916. // ++
  4917. //
  4918. // Routine:
  4919. //
  4920. // KiAltTableFault
  4921. //
  4922. // Description:
  4923. //
  4924. // Branched from Inst/DataAccessBitVector
  4925. // Inserts a missing PTE translation for the alt table.
  4926. //
  4927. // On entry:
  4928. //
  4929. // rva (h24) : offending virtual address
  4930. // riha (h25) : a offending PTE address
  4931. // rpr: (h26) : saved predicate
  4932. //
  4933. // Handle:
  4934. //
  4935. // --
  4936. HANDLER_ENTRY(KiAltTableFault)
  4937. rpAte = h28 // passed
  4938. rva = h24
  4939. riha = h25
  4940. rpr = h26 // passed
  4941. rPte = h27
  4942. rPte2 = h28
  4943. rps = h29
  4944. thash riha = rpAte // M
  4945. cmp.ne pt1 = r0, r0
  4946. mov rva = rpAte // I
  4947. ;;
  4948. ld8.s rPte = [riha] // M
  4949. ;;
  4950. tnat.nz pt0, p0 = rPte // I
  4951. tbit.z.or pt1, p0 = rPte, PTE_ACCESS
  4952. tbit.z.or pt1, p0 = rPte, PTE_VALID // I, if non-present page fault
  4953. (pt0) br.cond.spnt KiPageTableFault // B
  4954. (pt1) br.cond.spnt KiPteNotPresentFault // B
  4955. ;;
  4956. mov cr.ifa = rva
  4957. ;;
  4958. itc.d rPte // M
  4959. ;;
  4960. #if !defined(NT_UP)
  4961. ld8.s rPte2 = [riha] // M
  4962. mov rps = PAGE_SHIFT << PS_SHIFT // I
  4963. cmp.ne pt0 = zero, zero // I
  4964. ;;
  4965. cmp.ne.or pt0 = rPte2, rPte // M
  4966. tnat.nz.or pt0 = rPte2 // I
  4967. ;;
  4968. (pt0) ptc.l rva, rps // M
  4969. #endif
  4970. mov pr = rpr, -1 // I
  4971. rfi;; // B
  4972. HANDLER_EXIT(KiAltTableFault)
  4973. //
  4974. // ++
  4975. //
  4976. // Routine:
  4977. //
  4978. // KiFillForwardProgressTb
  4979. //
  4980. // Description:
  4981. //
  4982. // Fill TB from TLB forward progress buffer.
  4983. //
  4984. // On entry:
  4985. //
  4986. // rpBuffer (h16) : forward progress buffer address
  4987. // rpr: (h26) : saved predicate
  4988. //
  4989. // Handle:
  4990. //
  4991. // --
  4992. HANDLER_ENTRY(KiFillForwardProgressTb)
  4993. rLc = h29
  4994. rT0 = h28
  4995. rps = h27
  4996. rpr = h26
  4997. rVa = h22
  4998. rPte = h21
  4999. rpVa = h19
  5000. rpPte = h17
  5001. rpBuffer= h16
  5002. mov rpVa = rpBuffer // A
  5003. mov.i rLc = ar.lc // I
  5004. mov rT0 = NUMBER_OF_FWP_ENTRIES - 1 //
  5005. ;;
  5006. add rpPte = 8, rpBuffer // A
  5007. mov.i ar.lc = rT0 // I
  5008. ;;
  5009. fpb_loop:
  5010. //
  5011. // use ALAT to see if somebody modify the PTE entry
  5012. //
  5013. ld8 rVa = [rpVa], 16 // M
  5014. ld8.a rPte = [rpPte] // M
  5015. ;;
  5016. mov cr.ifa = rVa // M
  5017. cmp.ne pt0, pt1 = rPte, r0 // I
  5018. ;;
  5019. (pt0) itc.d rPte // M
  5020. ;;
  5021. (pt0) ld8.c.clr rPte = [rpPte] // M
  5022. add rpPte = 16, rpPte // I
  5023. ;;
  5024. (pt1) invala.e rPte // M, invalidate ALAT entry
  5025. (pt0) cmp.eq.and pt0 = rPte, r0 // I
  5026. ;;
  5027. (pt0) ptc.l rVa, rps // M
  5028. br.cloop.dptk.many fpb_loop;; // B
  5029. mov.i ar.lc = rLc
  5030. mov pr = rpr, -1 // I
  5031. rfi // B
  5032. ;;
  5033. HANDLER_EXIT(KiFillForwardProgressTb)
  5034. //++
  5035. //
  5036. // Routine Description:
  5037. //
  5038. // This routine begins the common code for raising an exception.
  5039. // The routine saves the non-volatile state and dispatches to the
  5040. // next level exception dispatcher.
  5041. //
  5042. // Arguments:
  5043. //
  5044. // a0 - pointer to trap frame
  5045. // a1 - previous mode
  5046. //
  5047. // Return Value:
  5048. //
  5049. // None.
  5050. //
  5051. //--
  5052. NESTED_ENTRY(KiExceptionDispatch)
  5053. //
  5054. // Build exception frame
  5055. //
  5056. .regstk 2, 3, 5, 0
  5057. .prologue 0xA, loc0
  5058. alloc t16 = ar.pfs, 2, 3, 5, 0
  5059. mov loc0 = sp
  5060. cmp4.eq pt0 = UserMode, a1 // previous mode is user?
  5061. mov loc1 = brp
  5062. .fframe ExceptionFrameLength
  5063. add sp = -ExceptionFrameLength, sp
  5064. ;;
  5065. .save ar.unat, loc2
  5066. mov loc2 = ar.unat
  5067. add t0 = ExFltS19+STACK_SCRATCH_AREA, sp
  5068. add t1 = ExFltS18+STACK_SCRATCH_AREA, sp
  5069. ;;
  5070. .save.gf 0x0, 0xC0000
  5071. stf.spill [t0] = fs19, ExFltS17-ExFltS19
  5072. stf.spill [t1] = fs18, ExFltS16-ExFltS18
  5073. ;;
  5074. .save.gf 0x0, 0x30000
  5075. stf.spill [t0] = fs17, ExFltS15-ExFltS17
  5076. stf.spill [t1] = fs16, ExFltS14-ExFltS16
  5077. mov t10 = bs4
  5078. ;;
  5079. .save.gf 0x0, 0xC000
  5080. stf.spill [t0] = fs15, ExFltS13-ExFltS15
  5081. stf.spill [t1] = fs14, ExFltS12-ExFltS14
  5082. mov t11 = bs3
  5083. ;;
  5084. .save.gf 0x0, 0x3000
  5085. stf.spill [t0] = fs13, ExFltS11-ExFltS13
  5086. stf.spill [t1] = fs12, ExFltS10-ExFltS12
  5087. mov t12 = bs2
  5088. ;;
  5089. .save.gf 0x0, 0xC00
  5090. stf.spill [t0] = fs11, ExFltS9-ExFltS11
  5091. stf.spill [t1] = fs10, ExFltS8-ExFltS10
  5092. mov t13 = bs1
  5093. ;;
  5094. .save.gf 0x0, 0x300
  5095. stf.spill [t0] = fs9, ExFltS7-ExFltS9
  5096. stf.spill [t1] = fs8, ExFltS6-ExFltS8
  5097. mov t14 = bs0
  5098. ;;
  5099. .save.gf 0x0, 0xC0
  5100. stf.spill [t0] = fs7, ExFltS5-ExFltS7
  5101. stf.spill [t1] = fs6, ExFltS4-ExFltS6
  5102. mov t15 = ar.lc
  5103. ;;
  5104. .save.gf 0x0, 0x30
  5105. stf.spill [t0] = fs5, ExFltS3-ExFltS5
  5106. stf.spill [t1] = fs4, ExFltS2-ExFltS4
  5107. ;;
  5108. .save.f 0xC
  5109. stf.spill [t0] = fs3, ExFltS1-ExFltS3 // save fs3
  5110. stf.spill [t1] = fs2, ExFltS0-ExFltS2 // save fs2
  5111. ;;
  5112. .save.f 0x3
  5113. stf.spill [t0] = fs1, ExBrS4-ExFltS1 // save fs1
  5114. stf.spill [t1] = fs0, ExBrS3-ExFltS0 // save fs0
  5115. ;;
  5116. .save.b 0x18
  5117. st8 [t0] = t10, ExBrS2-ExBrS4 // save bs4
  5118. st8 [t1] = t11, ExBrS1-ExBrS3 // save bs3
  5119. ;;
  5120. .save.b 0x6
  5121. st8 [t0] = t12, ExBrS0-ExBrS2 // save bs2
  5122. st8 [t1] = t13, ExIntS2-ExBrS1 // save bs1
  5123. ;;
  5124. .save.b 0x1
  5125. st8 [t0] = t14, ExIntS3-ExBrS0 // save bs0
  5126. movl out0 = KiPcr+PcCurrentThread
  5127. ;;
  5128. .save.gf 0xC, 0x0
  5129. .mem.offset 0,0
  5130. st8.spill [t0] = s3, ExIntS1-ExIntS3 // save s3
  5131. .mem.offset 8,0
  5132. st8.spill [t1] = s2, ExIntS0-ExIntS2 // save s2
  5133. ;;
  5134. .save.gf 0x3, 0x0
  5135. .mem.offset 0,0
  5136. st8.spill [t0] = s1, ExApLC-ExIntS1 // save s1
  5137. .mem.offset 8,0
  5138. st8.spill [t1] = s0, ExApEC-ExIntS0 // save s0
  5139. ;;
  5140. .savepsp ar.pfs, ExceptionFrameLength-ExApEC-STACK_SCRATCH_AREA
  5141. st8 [t1] = t16, ExIntNats-ExApEC
  5142. mov t4 = ar.unat // captured Nats of s0-s3
  5143. ;;
  5144. (pt0) ld8 out0 = [out0]
  5145. ;;
  5146. (pt0) add out0 = ThStackBase, out0
  5147. .savepsp ar.lc, ExceptionFrameLength-ExApLC-STACK_SCRATCH_AREA
  5148. st8 [t0] = t15
  5149. .savepsp @priunat, ExceptionFrameLength-ExIntNats-STACK_SCRATCH_AREA
  5150. st8 [t1] = t4 // save Nats of s0-s3
  5151. ;;
  5152. PROLOGUE_END
  5153. (pt0) ld8 out0 = [out0]
  5154. ;;
  5155. (pt0) add out0 = -ThreadStateSaveAreaLength+TsHigherFPVolatile, out0
  5156. (pt0) br.call.sptk brp = KiSaveHigherFPVolatile
  5157. ;;
  5158. add out0 = TrExceptionRecord, a0 // -> exception record
  5159. add out1 = STACK_SCRATCH_AREA, sp // -> exception frame
  5160. mov out2 = a0 // -> trap frame
  5161. mov out3 = a1 // previous mode
  5162. mov out4 = 1 // first chance
  5163. br.call.sptk.many brp = KiDispatchException
  5164. ;;
  5165. add t1 = ExApEC+STACK_SCRATCH_AREA, sp
  5166. movl t0 = KiExceptionExit
  5167. ;;
  5168. //
  5169. // Interrupts must be disabled before calling KiExceptionExit
  5170. // because the unwind code cannot unwind from that point.
  5171. //
  5172. FAST_DISABLE_INTERRUPTS
  5173. ld8 t1 = [t1]
  5174. mov brp = t0
  5175. ;;
  5176. mov ar.unat = loc2
  5177. mov ar.pfs = t1
  5178. add s1 = STACK_SCRATCH_AREA, sp // s1 -> exception frame
  5179. mov s0 = a0 // s0 -> trap frame
  5180. br.ret.sptk brp
  5181. ;;
  5182. NESTED_EXIT(KiExceptionDispatch)
  5183. //++
  5184. //
  5185. // BOOLEAN
  5186. // KeInvalidAccessAllowed (
  5187. // IN PVOID TrapInformation
  5188. // )
  5189. //
  5190. // Routine Description:
  5191. //
  5192. // Mm will pass a pointer to a trap frame prior to issuing a bug check on
  5193. // a pagefault. This routine lets Mm know if it is ok to bugcheck. The
  5194. // specific case we must protect are the interlocked pop sequences which can
  5195. // blindly access memory that may have been freed and/or reused prior to the
  5196. // access. We don't want to bugcheck the system in these cases, so we check
  5197. // the instruction pointer here.
  5198. //
  5199. // Arguments:
  5200. //
  5201. // TrapFrame (a0) - Supplies a trap frame pointer. NULL means return False.
  5202. //
  5203. // Return Value:
  5204. //
  5205. // True if the invalid access should be ignored.
  5206. // False which will usually trigger a bugcheck.
  5207. //
  5208. //--
  5209. LEAF_ENTRY(KeInvalidAccessAllowed)
  5210. .regstk 1, 0, 0, 0
  5211. cmp.eq pt0 = 0, a0
  5212. movl t1 = ExpInterlockedPopEntrySListFault
  5213. add t0 = TrStIIP, a0
  5214. mov v0 = zero // assume access not allowed
  5215. (pt0) br.ret.spnt brp
  5216. ;;
  5217. ld8 t0 = [t0]
  5218. ;;
  5219. cmp.eq pt2 = t0, t1
  5220. ;;
  5221. nop.m 0
  5222. (pt2) mov v0 = 1
  5223. br.ret.sptk brp
  5224. LEAF_EXIT(KeInvalidAccessAllowed)