Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2894 lines
101 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. // 1. Optimizations for more than 2-way parallelism when
  21. // regsiters available.
  22. //--
  23. #include "ksia64.h"
  24. .file "trap.s"
  25. //
  26. // Globals imported:
  27. //
  28. .global BdPcr
  29. PublicFunction(BdSetMovlImmediate)
  30. PublicFunction(BdInstallVectors)
  31. PublicFunction(BdTrap)
  32. PublicFunction(BdOtherBreakException)
  33. PublicFunction(BdSingleStep)
  34. PublicFunction(BdIvtStart)
  35. PublicFunction(BdIvtEnd)
  36. PublicFunction(memcpy)
  37. //
  38. // Register aliases used throughout the entire module
  39. //
  40. //
  41. // Banked general registers
  42. //
  43. //
  44. // Register aliases used throughout the entire module
  45. //
  46. //
  47. // Banked general registers
  48. //
  49. //
  50. // Register aliases used throughout the entire module
  51. //
  52. //
  53. // Banked general registers
  54. //
  55. // h16-h23 can only be used when psr.ic=1.
  56. //
  57. // h24-h31 can only be used when psr.ic=0 (these are reserved for tlb
  58. // and pal/machine check handlers when psr.ic=1).
  59. //
  60. //
  61. // Shown below are aliases of bank 0 registers used in the low level handlers
  62. // by macros ALLOCATE_TRAP_FRAME, SAVE_INTERRUPTION_RESOURCES, and
  63. // NORMAL_KERNEL_EXIT. When the code in the macros are changes, these
  64. // register aliases must be reviewed.
  65. //
  66. rHIPSR = h16
  67. rHpT2 = h16
  68. rHIIPA = h17
  69. rHRSC = h17
  70. rHDfhPFS = h17 // used to preserve pfs in BdDisabledFpRegisterVector
  71. rHIIP = h18
  72. rHFPSR = h18
  73. rHOldPreds = h19
  74. rHBrp = h19
  75. rHCSD = h19
  76. rHIFS = h20
  77. rHPFS = h20
  78. rHBSP = h20
  79. rHISR = h21
  80. rHUNAT = h21
  81. rHpT3 = h21
  82. rHSp = h22
  83. rHDfhBrp = h22 // used to preserve brp in BdDisabledFpRegisterVector
  84. rHpT4 = h22
  85. rHpT1 = h23
  86. rHIFA = h24
  87. rTH3 = h24
  88. rHHandler = h25
  89. rTH1 = h26
  90. rTH2 = h27
  91. rHIIM = h28
  92. rHEPCVa = h29
  93. rHEPCVa2 = h30
  94. rPanicCode = h30
  95. //
  96. // General registers used through out module
  97. //
  98. pApc = ps0 // User Apc Pending
  99. pUser = ps1 // mode on entry was user
  100. pKrnl = ps2 // mode on entry was kernel
  101. pUstk = ps3
  102. pKstk = ps4
  103. pEM = ps5 // EM ISA on kernel entry
  104. pIA = ps6 // X86 ISA on kernel entry
  105. //
  106. // Kernel registers used through out module
  107. //
  108. rkHandler = k6 // specific exception handler
  109. //
  110. // Macro definitions for this module only
  111. //
  112. //
  113. // Define vector/exception entry/exit macros.
  114. // N.B. All HANDLER_ENTRY functions go into .nsc section with
  115. // BdNormalSystemCall being the first.
  116. //
  117. #define HANDLER_ENTRY(Name) \
  118. .##global Name; \
  119. .##proc Name; \
  120. Name::
  121. #define HANDLER_ENTRY_EX(Name, Handler) \
  122. .##global Name; \
  123. .##proc Name; \
  124. .##type Handler, @function; \
  125. .##personality Handler; \
  126. Name::
  127. #define VECTOR_ENTRY(Offset, Name, Extra0) \
  128. .##org Offset; \
  129. .##global Name; \
  130. .##proc Name; \
  131. Name::
  132. #define VECTOR_EXIT(Name) \
  133. .##endp Name
  134. #define HANDLER_EXIT(Name) \
  135. .##endp Name
  136. //++
  137. // Routine:
  138. //
  139. // IO_END_OF_INTERRUPT(rVector,rT1,rT2,pEOI)
  140. //
  141. // Routine Description:
  142. //
  143. // HalEOITable Entry corresponding to the vectorNo is tested.
  144. // If the entry is nonzero, then vectorNo is stored to the location
  145. // specified in the entry. If the entry is zero, return.
  146. //
  147. // Arguements:
  148. //
  149. //
  150. // Notes:
  151. //
  152. // MS preprocessor requires /* */ style comments
  153. //
  154. //--
  155. #define IO_END_OF_INTERRUPT(rVector,rT1,rT2,pEOI) ;\
  156. add rT1 = @gprel(__imp_HalEOITable),gp ;\
  157. ;; ;\
  158. ld8 rT1 = [rT1] ;\
  159. ;; ;\
  160. shladd rT2 = rVector,3,rT1 ;\
  161. ;; ;\
  162. ld8 rT1 = [rT2] ;\
  163. ;; ;\
  164. cmp.ne pEOI = zero, rT1 ;\
  165. ;; ;\
  166. (pEOI) st4.rel [rT1] = rVector
  167. //++
  168. // Routine:
  169. //
  170. // VECTOR_CALL_HANDLER(Handler, SpecificHandler)
  171. //
  172. // Routine Description:
  173. //
  174. // Common code for transfer to heavyweight handlers from
  175. // interruption vectors. Put RSE in store intensive mode,
  176. // cover current frame and call handler.
  177. //
  178. // Arguments:
  179. //
  180. // Handler: First level handler for this vector
  181. // SpecificHandler: Specific handler to be called by the generic
  182. // exception handler.
  183. //
  184. // Return Value:
  185. //
  186. // None
  187. //
  188. // Notes:
  189. // Uses just the kernel banked registers (h16-h31)
  190. //
  191. // MS preprocessor requires /* */ style comments
  192. //--
  193. #define VECTOR_CALL_HANDLER(Handler,SpecificHandler) ;\
  194. mov rHIFA = cr##.##ifa ;\
  195. movl rTH1 = BdPcr+PcSavedIFA ;\
  196. ;; ;\
  197. ;\
  198. st8 [rTH1] = rHIFA ;\
  199. movl rHHandler = SpecificHandler ;\
  200. br##.##sptk Handler ;\
  201. ;;
  202. //++
  203. // Routine:
  204. //
  205. // ALLOCATE_TRAP_FRAME
  206. //
  207. // Routine Description:
  208. //
  209. // Common code for allocating trap frame on kernel entry for heavyweight
  210. // handler.
  211. //
  212. // On entry:
  213. //
  214. // On exit: sp -> trap frame; any instruction that depends on sp must be
  215. // placed in the new instruction group. Interruption resources
  216. // ipsr, iipa, iip, predicates, isr, sp, ifs are captured in
  217. // seven of the banked registers h16-23. The last one is used
  218. // by SAVE_INTERRUPTION_STATE as a pointer to save these resources
  219. // in the trap frame.
  220. //
  221. // Return Value:
  222. //
  223. // None
  224. //
  225. // Notes:
  226. // Uses just the kernel banked registers (h16-h31)
  227. //
  228. // MS preprocessor requires /* */ style comments below
  229. //--
  230. #define ALLOCATE_TRAP_FRAME ;\
  231. ;\
  232. pOverflow = pt2 ;\
  233. ;\
  234. mov rHIPSR = cr##.##ipsr ;\
  235. mov rHIIP = cr##.##iip ;\
  236. cover /* cover and save IFS */;\
  237. ;; ;\
  238. ;\
  239. mov rHIIPA = cr##.##iipa ;\
  240. movl rTH2 = MM_EPC_VA ;\
  241. ;\
  242. mov rTH3 = ar##.##bsp ;\
  243. mov rHOldPreds = pr ;\
  244. ;; ;\
  245. ;\
  246. mov rHIFS = cr##.##ifs ;\
  247. add rHEPCVa = 0x30, rTH2 ;\
  248. ;\
  249. mov rHISR = cr##.##isr ;\
  250. movl rTH2 = BdPcr+PcInitialStack ;\
  251. ;\
  252. tbit##.##z pEM, pIA = rHIPSR, PSR_IS /* set instr set */;\
  253. extr##.##u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN /* get mode */;\
  254. mov rHSp = sp ;\
  255. ;; ;\
  256. ;\
  257. ssm (1 << PSR_IC) | (1 << PSR_DFH) | (1 << PSR_AC) ;\
  258. cmp4##.##eq pKrnl, pUser = PL_KERNEL, rTH1 /* set mode pred */;\
  259. cmp4##.##eq pKstk, pUstk = PL_KERNEL, rTH1 /* set stack pred */;\
  260. ;; ;\
  261. ;\
  262. .pred.rel "mutex",pUstk,pKstk ;\
  263. add sp = -TrapFrameLength, sp /* allocate TF */;\
  264. ;; ;\
  265. add rHpT1 = TrStIPSR, sp ;\
  266. ;;
  267. //++
  268. // Routine:
  269. //
  270. // SAVE_INTERRUPTION_STATE(Label)
  271. //
  272. // Routine Description:
  273. //
  274. // Common code for saving interruption state on entry to a heavyweight
  275. // handler.
  276. //
  277. // Arguments:
  278. //
  279. // Label: label for branching around BSP switch
  280. //
  281. // On entry:
  282. //
  283. // sp -> trap frame
  284. //
  285. // On exit:
  286. //
  287. // Static registers gp, teb, sp, fpsr spilled into the trap frame.
  288. // Registers gp, teb, fpsr are set up for kernel mode execution.
  289. //
  290. // Return Value:
  291. //
  292. // None
  293. //
  294. // Notes:
  295. //
  296. // Interruption resources already captured in bank 0 registers h16-h23.
  297. // It's safe to take data TLB fault when saving them into the trap
  298. // frame because kernel stack is always resident in memory. This macro
  299. // is carefully constructed to save the bank registers' contents in
  300. // the trap frame and reuse them to capture other register states as
  301. // soon as they are available. Until we have a virtual register
  302. // allocation scheme in place, the bank 0 register aliases defined at
  303. // the beginning of the file must be updated when this macro is modified.
  304. //
  305. // MS preprocessor requires /* */ style comments below
  306. //--
  307. #define SAVE_INTERRUPTION_STATE(Label) ;\
  308. ;\
  309. /* Save interruption resources in trap frame */ ;\
  310. ;\
  311. ;\
  312. srlz##.##i /* I serialize required */;\
  313. st8 [rHpT1] = rHIPSR, TrStISR-TrStIPSR /* save IPSR */;\
  314. add rHpT2 = TrPreds, sp /* -> Preds */;\
  315. ;; ;\
  316. ;\
  317. st8 [rHpT1] = rHISR, TrStIIP-TrStISR /* save ISR */;\
  318. st8 [rHpT2] = rHOldPreds, TrBrRp-TrPreds ;\
  319. ;; ;\
  320. ;\
  321. mov rHUNAT = ar##.##unat ;\
  322. st8 [rHpT1] = rHIIP, TrStIFS-TrStIIP /* save IIP */;\
  323. mov rHBrp = brp ;\
  324. ;; ;\
  325. ;\
  326. mov rHFPSR = ar##.##fpsr ;\
  327. st8 [rHpT1] = rHIFS, TrStIIPA-TrStIFS /* save IFS */;\
  328. mov rHPFS = ar##.##pfs ;\
  329. ;; ;\
  330. ;\
  331. st8 [rHpT1] = rHIIPA, TrStFPSR-TrStIIPA /* save IIPA */;\
  332. st8 [rHpT2] = rHBrp, TrRsPFS-TrBrRp ;\
  333. ;; ;\
  334. ;\
  335. mov rHRSC = ar##.##rsc ;\
  336. st8 [rHpT2] = rHPFS /* save PFS */;\
  337. add rHpT2 = TrApUNAT, sp ;\
  338. ;\
  339. mov rHBSP = ar##.##bsp ;\
  340. mov rHCSD = ar##.##csd ;\
  341. ;; ;\
  342. ;\
  343. st8 [rHpT1] = rHFPSR, TrRsRSC-TrStFPSR /* save FPSR */;\
  344. st8 [rHpT2] = rHUNAT, TrIntGp-TrApUNAT /* save UNAT */;\
  345. ;; ;\
  346. ;\
  347. st8 [rHpT1] = rHRSC, TrRsBSP-TrRsRSC /* save RSC */;\
  348. st8##.##spill [rHpT2] = gp, TrIntTeb-TrIntGp /* spill GP */;\
  349. ;; ;\
  350. ;\
  351. st8##.##spill [rHpT2] = teb, TrIntSp-TrIntTeb /* spill TEB (r13) */;\
  352. mov teb = kteb /* sanitize teb */;\
  353. ;; ;\
  354. ;\
  355. st8 [rHpT1] = rHBSP /* save BSP */;\
  356. movl rHpT1 = BdPcr + PcKernelGP ;\
  357. ;\
  358. (pUstk) mov ar##.##rsc = RSC_KERNEL_DISABLED /* turn off RSE */;\
  359. st8##.##spill [rHpT2] = rHSp, TrSegCSD-TrIntSp /* spill SP */;\
  360. ;; ;\
  361. ;\
  362. st8 [rHpT2] = rHCSD /* save CSD */;\
  363. (pKstk) br##.##dpnt Label /* br if on kernel stack */;\
  364. ;\
  365. ;\
  366. /* */;\
  367. /* Local register aliases for back store switch */;\
  368. /* N.B. These must be below h24 since PSR.ic = 1 at this point */;\
  369. /* h16-h23 are available */;\
  370. /* */;\
  371. ;\
  372. rpRNAT = h16 ;\
  373. rpBSPStore= h17 ;\
  374. rBSPStore = h18 ;\
  375. rKBSPStore= h19 ;\
  376. rRNAT = h20 ;\
  377. rKrnlFPSR = h21 ;\
  378. rEFLAG = h22 ;\
  379. ;\
  380. /* */;\
  381. /* If previous mode is user, switch to kernel backing store */;\
  382. /* -- uses the "loadrs" approach. Note that we do not save the */;\
  383. /* BSP/BSPSTORE in the trap frame if prvious mode was kernel */;\
  384. /* */;\
  385. ;\
  386. ;\
  387. mov rBSPStore = ar##.##bspstore /* get user bsp store point */;\
  388. mov rRNAT = ar##.##rnat /* get RNAT */;\
  389. add rpRNAT = TrRsRNAT, sp /* -> RNAT */;\
  390. ;; ;\
  391. ;\
  392. ld8 rKBSPStore = [rHpT1] /* load kernel bstore */;\
  393. movl rKrnlFPSR = FPSR_FOR_KERNEL /* initial fpsr value */;\
  394. ;; ;\
  395. ;\
  396. mov ar##.##fpsr = rKrnlFPSR /* set fpsr */;\
  397. add rpBSPStore = TrRsBSPSTORE, sp /* -> User BSPStore */;\
  398. ;; ;\
  399. ;\
  400. st8 [rpRNAT] = rRNAT /* save user RNAT */;\
  401. st8 [rpBSPStore] = rBSPStore /* save user BSP Store */;\
  402. ;; ;\
  403. dep rKBSPStore = rBSPStore, rKBSPStore, 0, 9 ;\
  404. /* adjust kernel BSPSTORE */;\
  405. /* for NAT collection */;\
  406. ;\
  407. ;; ;\
  408. ;\
  409. /* */;\
  410. /* Now running on kernel backing store */;\
  411. /* */;\
  412. ;\
  413. Label: ;\
  414. (pUstk) mov ar##.##bspstore = rKBSPStore /* switch to kernel BSP */;\
  415. (pUstk) mov ar##.##rsc = RSC_KERNEL /* turn rse on, kernel mode */;\
  416. bsw##.##1 /* switch back to user bank */;\
  417. ;; /* stop bit required */
  418. //++
  419. // Routine:
  420. //
  421. // RETURN_FROM_INTERRUPTION
  422. //
  423. // Routine Description:
  424. //
  425. // Common handler code to restore trap frame and resume execution
  426. // at the interruption address.
  427. //
  428. // Arguments:
  429. //
  430. // Label
  431. //
  432. // Return Value:
  433. //
  434. // None
  435. //
  436. // Note:
  437. //
  438. // On entry: interrrupts disabled, sp -> trap frame
  439. // On exit:
  440. // MS preprocessor requires /* */ style comments below
  441. //--
  442. #define RETURN_FROM_INTERRUPTION(Label) ;\
  443. ;\
  444. .##regstk 0,3,2,0 /* must match the alloc instruction below */ ;\
  445. ;\
  446. rBSP = loc0 ;\
  447. rBSPStore = loc1 ;\
  448. rRnat = loc2 ;\
  449. ;\
  450. rpT1 = t1 ;\
  451. rpT2 = t2 ;\
  452. rpT3 = t3 ;\
  453. rpT4 = t4 ;\
  454. rThread = t6 ;\
  455. rApcFlag = t7 ;\
  456. rT1 = t8 ;\
  457. rT2 = t9 ;\
  458. ;\
  459. alloc rT1 = 0,4,2,0 ;\
  460. movl rpT1 = BdPcr + PcCurrentThread /* ->PcCurrentThread */;\
  461. ;; ;\
  462. ;\
  463. (pUstk) ld8 rThread = [rpT1] /* load thread ptr */;\
  464. add rBSP = TrRsBSP, sp /* -> user BSP */;\
  465. (pKstk) br##.##call##.##spnt brp = BdRestoreTrapFrame ;\
  466. ;; ;\
  467. ;\
  468. add rBSPStore = TrRsBSPSTORE, sp /* -> user BSP Store */;\
  469. add rRnat = TrRsRNAT, sp /* -> user RNAT */;\
  470. (pKstk) br##.##spnt Label##ReturnToKernel ;\
  471. ;; ;\
  472. ;\
  473. add rpT1 = ThApcState+AsUserApcPending, rThread ;\
  474. ;; ;\
  475. ld1 rApcFlag = [rpT1], ThAlerted-ThApcState-AsUserApcPending ;\
  476. ;; ;\
  477. st1.nta [rpT1] = zero ;\
  478. cmp##.##ne pApc = zero, rApcFlag ;\
  479. ;; ;\
  480. ;\
  481. PSET_IRQL (pApc, APC_LEVEL) ;\
  482. (pApc) mov out1 = sp ;\
  483. ;; ;\
  484. ;\
  485. (pApc) FAST_DISABLE_INTERRUPTS ;\
  486. PSET_IRQL (pApc, zero) ;\
  487. ;\
  488. ld8 rBSP = [rBSP] /* user BSP */;\
  489. ld8 rBSPStore = [rBSPStore] /* user BSP Store */;\
  490. ld8 rRnat = [rRnat] /* user RNAT */;\
  491. br##.##call##.##sptk brp = BdRestoreDebugRegisters ;\
  492. ;; ;\
  493. ;\
  494. invala ;\
  495. br##.##call##.##sptk brp = BdRestoreTrapFrame ;\
  496. ;; ;\
  497. ;\
  498. ;\
  499. Label##CriticalExitCode: ;\
  500. ;\
  501. rHRscE = h17 ;\
  502. rHRnat = h18 ;\
  503. rHBSPStore = h19 ;\
  504. rHRscD = h20 ;\
  505. rHRscDelta = h24 ;\
  506. ;\
  507. bsw##.##0 ;\
  508. ;; ;\
  509. ;\
  510. mov rHRscE = ar##.##rsc /* save user RSC */;\
  511. mov rHBSPStore = rBSPStore ;\
  512. mov rHRscD = RSC_KERNEL_DISABLED ;\
  513. ;\
  514. sub rHRscDelta = rBSP, rBSPStore /* delta = BSP - BSP Store */;\
  515. ;; ;\
  516. mov rHRnat = rRnat ;\
  517. dep rHRscD = rHRscDelta, rHRscD, 16, 14 /* set RSC.loadrs */;\
  518. ;; ;\
  519. ;\
  520. alloc rTH1 = 0,0,0,0 ;\
  521. mov ar##.##rsc = rHRscD /* RSE off */ ;\
  522. ;; ;\
  523. loadrs /* pull in user regs */;\
  524. /* up to tear point */ ;\
  525. ;; ;\
  526. ;\
  527. mov ar##.##bspstore = rHBSPStore /* restore user BSP */ ;\
  528. ;; ;\
  529. mov ar##.##rnat = rHRnat /* restore user RNAT */;\
  530. ;\
  531. Label##ReturnToKernel: ;\
  532. ;\
  533. (pUstk) mov ar.rsc = rHRscE /* restore user RSC */;\
  534. bsw##.##0 ;\
  535. ;; ;\
  536. ;\
  537. add rHpT2 = TrApUNAT, sp /* -> previous UNAT */;\
  538. add rHpT1 = TrStFPSR, sp /* -> previous Preds */;\
  539. ;; ;\
  540. ;\
  541. ld8 rHUNAT = [rHpT2],TrPreds-TrApUNAT ;\
  542. ld8 rHFPSR = [rHpT1],TrRsPFS-TrStFPSR ;\
  543. ;; ;\
  544. ;\
  545. ld8 rHOldPreds = [rHpT2], TrIntSp-TrPreds ;\
  546. ld8 rHPFS = [rHpT1],TrStIIPA-TrRsPFS ;\
  547. ;; ;\
  548. ;\
  549. ld8##.##fill rHSp = [rHpT2], TrBrRp-TrIntSp ;\
  550. ld8 rHIIPA = [rHpT1], TrStIIP-TrStIIPA ;\
  551. ;; ;\
  552. ;\
  553. mov ar##.##fpsr = rHFPSR /* restore FPSR */;\
  554. ld8 rHIIP = [rHpT1], TrStIPSR-TrStIIP /* load IIP */;\
  555. mov pr = rHOldPreds, -1 /* restore preds */;\
  556. ;\
  557. mov ar##.##unat = rHUNAT /* restore UNAT */;\
  558. ld8 rHBrp = [rHpT2], TrStIFS-TrBrRp ;\
  559. mov ar##.##pfs = rHPFS /* restore PFS */;\
  560. ;; ;\
  561. ;\
  562. ld8 rHIFS = [rHpT2] /* load IFS */;\
  563. ld8 rHIPSR = [rHpT1] /* load IPSR */;\
  564. ;\
  565. rsm 1 << PSR_IC /* reset ic bit */;\
  566. ;; ;\
  567. srlz##.##d /* must serialize */;\
  568. mov brp = rHBrp /* restore brp */;\
  569. ;\
  570. /* */;\
  571. /* Restore status registers */;\
  572. /* */;\
  573. ;\
  574. mov cr##.##ipsr = rHIPSR /* restore previous IPSR */;\
  575. mov cr##.##iip = rHIIP /* restore previous IIP */;\
  576. ;\
  577. mov cr##.##ifs = rHIFS /* restore previous IFS */;\
  578. mov cr##.##iipa = rHIIPA /* restore previous IIPA */;\
  579. ;; ;\
  580. ;\
  581. /* */;\
  582. /* Resume at point of interruption (rfi must be at end of instruction group)*/;\
  583. /* */;\
  584. mov sp = rHSp /* restore sp */;\
  585. mov h17 = r0 /* clear TB loop count */;\
  586. rfi ;\
  587. ;;
  588. //++
  589. // Routine:
  590. //
  591. // USER_APC_CHECK
  592. //
  593. // Routine Description:
  594. //
  595. // Common handler code for requesting
  596. // pending APC if returning to user mode.
  597. //
  598. // Arguments:
  599. //
  600. // Return Value:
  601. //
  602. // None
  603. //
  604. // Note:
  605. //
  606. // On entry: interrrupts disabled, sp -> trap frame
  607. // On exit:
  608. // MS preprocessor requires /* */ style comments below
  609. //--
  610. #define USER_APC_CHECK ;\
  611. ;\
  612. /* */;\
  613. /* Check for pending APC's */;\
  614. /* */;\
  615. ;\
  616. movl t22=BdPcr + PcCurrentThread /* ->PcCurrentThread */;\
  617. ;; ;\
  618. ;\
  619. LDPTR (t22,t22) ;\
  620. ;; ;\
  621. add t22=ThApcState+AsUserApcPending, t22 /* -> pending flag */;\
  622. ;; ;\
  623. ;\
  624. ld1 t8 = [t22], ThAlerted-ThApcState-AsUserApcPending ;\
  625. ;; ;\
  626. st1 [t22] = zero ;\
  627. cmp##.##ne pApc = zero, t8 /* pApc = 1 if pending */;\
  628. ;; ;\
  629. ;\
  630. PSET_IRQL (pApc, APC_LEVEL) ;\
  631. (pApc) mov out1 = sp ;\
  632. ;; ;\
  633. (pApc) FAST_DISABLE_INTERRUPTS ;\
  634. PSET_IRQL (pApc, zero)
  635. //++
  636. // Routine:
  637. //
  638. // BSTORE_SWITCH
  639. //
  640. // Routine Description:
  641. //
  642. // Common handler code for switching to user backing store, if
  643. // returning to user mode.
  644. //
  645. // On entry:
  646. //
  647. // sp: pointer to trap frame
  648. //
  649. // On exit:
  650. //
  651. // on user backing store, can't afford another alloc of any frame size
  652. // other than zero. otherwise, the kernel may panic.
  653. //
  654. // Return Value:
  655. //
  656. // None
  657. //
  658. // Note:
  659. //
  660. // MS preprocessor requires /* */ style comments below
  661. //--
  662. #define BSTORE_SWITCH ;\
  663. /* */;\
  664. /* Set sp to trap frame and switch to kernel banked registers */;\
  665. /* */;\
  666. rRscD = t11 ;\
  667. rpT2 = t12 ;\
  668. rRNAT = t13 ;\
  669. rBSPStore = t14 ;\
  670. rRscDelta = t15 ;\
  671. rpT1 = t16 ;\
  672. ;\
  673. ;\
  674. add rpT1 = TrRsRNAT, sp /* -> user RNAT */;\
  675. add rpT2 = TrRsBSPSTORE, sp /* -> user BSP Store */;\
  676. mov rRscD = RSC_KERNEL_DISABLED ;\
  677. ;; ;\
  678. ;\
  679. /* */;\
  680. /* Switch to user BSP -- put in load intensive mode to overlap RS restore */;\
  681. /* with volatile state restore. */;\
  682. /* */;\
  683. ;\
  684. ld8 rRNAT = [rpT1], TrRsBSP-TrRsRNAT /* user RNAT */ ;\
  685. ld8 rBSPStore = [rpT2] /* user BSP Store*/ ;\
  686. ;; ;\
  687. ;\
  688. alloc t22 = 0,0,0,0 ;\
  689. ld8 rRscDelta = [rpT1] /* user BSP */ ;\
  690. ;; ;\
  691. sub rRscDelta = rRscDelta, rBSPStore /* delta = BSP - BSP Store */;\
  692. ;; ;\
  693. ;\
  694. invala ;\
  695. dep rRscD = rRscDelta, rRscD, 16, 14 /* set RSC.loadrs */;\
  696. ;; ;\
  697. ;\
  698. mov ar##.##rsc = rRscD /* RSE off */ ;\
  699. ;; ;\
  700. loadrs /* pull in user regs */;\
  701. /* up to tear point */ ;\
  702. ;; ;\
  703. ;\
  704. mov ar##.##bspstore = rBSPStore /* restore user BSP */ ;\
  705. ;; ;\
  706. mov ar##.##rnat = rRNAT /* restore user RNAT */
  707. //++
  708. // Routine:
  709. //
  710. // NORMAL_KERNEL_EXIT
  711. //
  712. // Routine Description:
  713. //
  714. // Common handler code for restoring previous state and rfi.
  715. //
  716. // On entry:
  717. //
  718. // sp: pointer to trap frame
  719. // ar.unat: contains Nat for previous sp (restored by ld8.fill)
  720. //
  721. // Return Value:
  722. //
  723. // None
  724. //
  725. // Note:
  726. //
  727. // Uses just the kernel banked registers (h16-h31)
  728. //
  729. // MS preprocessor requires /* */ style comments below
  730. //--
  731. #define NORMAL_KERNEL_EXIT ;\
  732. ;\
  733. add rHpT2 = TrApUNAT, sp /* -> previous UNAT */;\
  734. add rHpT1 = TrStFPSR, sp /* -> previous Preds */;\
  735. ;; ;\
  736. ;\
  737. ld8 rHUNAT = [rHpT2],TrPreds-TrApUNAT ;\
  738. ld8 rHFPSR = [rHpT1],TrRsPFS-TrStFPSR ;\
  739. ;; ;\
  740. ;\
  741. ld8 rHOldPreds = [rHpT2], TrIntSp-TrPreds ;\
  742. ld8 rHPFS = [rHpT1],TrStIIPA-TrRsPFS ;\
  743. ;; ;\
  744. ;\
  745. ld8##.##fill rHSp = [rHpT2], TrBrRp-TrIntSp ;\
  746. ld8 rHIIPA = [rHpT1], TrStIIP-TrStIIPA ;\
  747. ;; ;\
  748. ;\
  749. mov ar##.##fpsr = rHFPSR /* restore FPSR */;\
  750. ld8 rHIIP = [rHpT1], TrStIPSR-TrStIIP /* load IIP */;\
  751. mov pr = rHOldPreds, -1 /* restore preds */;\
  752. ;\
  753. mov ar##.##unat = rHUNAT /* restore UNAT */;\
  754. ld8 rHBrp = [rHpT2], TrStIFS-TrBrRp ;\
  755. mov ar##.##pfs = rHPFS /* restore PFS */;\
  756. ;; ;\
  757. ;\
  758. ld8 rHIFS = [rHpT2] /* load IFS */;\
  759. ld8 rHIPSR = [rHpT1] /* load IPSR */;\
  760. ;\
  761. rsm 1 << PSR_IC /* reset ic bit */;\
  762. ;; ;\
  763. srlz##.##d /* must serialize */;\
  764. mov brp = rHBrp /* restore brp */;\
  765. ;\
  766. /* */;\
  767. /* Restore status registers */;\
  768. /* */;\
  769. ;\
  770. mov cr##.##ipsr = rHIPSR /* restore previous IPSR */;\
  771. mov cr##.##iip = rHIIP /* restore previous IIP */;\
  772. ;\
  773. mov cr##.##ifs = rHIFS /* restore previous IFS */;\
  774. mov cr##.##iipa = rHIIPA /* restore previous IIPA */;\
  775. ;; ;\
  776. ;\
  777. /* */;\
  778. /* Resume at point of interruption (rfi must be at end of instruction group)*/;\
  779. /* */;\
  780. mov sp = rHSp /* restore sp */;\
  781. mov h17 = r0 /* clear TB loop count */;\
  782. rfi ;\
  783. ;;
  784. //++
  785. // Routine:
  786. //
  787. // GET_INTERRUPT_VECTOR(pGet, rVector)
  788. //
  789. // Routine Description:
  790. //
  791. // Hook to get the vector for an interrupt. Currently just
  792. // reads the Interrupt Vector Control Register.
  793. //
  794. // Agruments:
  795. //
  796. // pGet: Predicate: if true then get, else skip.
  797. // rVector: Register for the vector number.
  798. //
  799. // Return Value:
  800. //
  801. // The vector number of the highest priority pending interrupt.
  802. // Vectors number is an 8-bit value. All other bits 0.
  803. //
  804. //--
  805. #define GET_INTERRUPT_VECTOR(pGet,rVector) \
  806. srlz##.##d ;\
  807. (pGet) mov rVector = cr##.##ivr
  808. //--------------------------------------------------------------------
  809. // Routine:
  810. //
  811. // BdBreakVector
  812. //
  813. // Description:
  814. //
  815. // Interruption vector for break instruction.
  816. //
  817. // On entry:
  818. //
  819. // IIM contains break immediate value:
  820. // -- BREAK_SYSCALL -> standard system call
  821. // interrupts disabled
  822. // r16-r31 switched to kernel bank
  823. // r16-r31 all available since no TLB faults at this point
  824. //
  825. // Return value:
  826. //
  827. // if system call, sys call return value in v0.
  828. //
  829. // Process:
  830. //--------------------------------------------------------------------
  831. VECTOR_ENTRY(0x2C00, BdBreakVector, cr.iim)
  832. mov b7 = h30 // restore the original value of b7
  833. mov rHIIM = cr.iim // get break value
  834. movl rTH1 = BdPcr+PcSavedIIM
  835. ;;
  836. st8 [rTH1] = rHIIM
  837. VECTOR_CALL_HANDLER(BdGenericExceptionHandler, BdOtherBreakException)
  838. //
  839. // Do not return from handler
  840. //
  841. VECTOR_EXIT(BdBreakVector)
  842. //++
  843. //
  844. // BdTakenBranchVector
  845. //
  846. // Cause: A taken branch was successfully execcuted and the PSR.tb
  847. // bit is 1. This trap is higher priority than single step trap.
  848. //
  849. // Parameters: cr.iip - address of bundle containing the instruction to
  850. // be executed next.
  851. //
  852. // cr.ipsr - copy of PSR at the time of interruption.
  853. //
  854. // cr.iipa - address of bundle containing the last
  855. // successfully executed instruction
  856. //
  857. // cr.isr - faulting status information. The ISR.code
  858. // contains a bit vector for all traps which
  859. // occurred in the trapping bundle.
  860. //
  861. //--
  862. VECTOR_ENTRY(0x5f00, BdTakenBranchVector, cr.iipa)
  863. mov rHIIP = cr.iip
  864. movl rHEPCVa = MM_EPC_VA+0x20 // user system call entry point
  865. mov rHIPSR = cr.ipsr
  866. movl rHpT1 = BdPcr+PcInitialStack
  867. ;;
  868. ld8 rHpT1 = [rHpT1]
  869. mov rHOldPreds = pr
  870. mov rPanicCode = UNEXPECTED_KERNEL_MODE_TRAP
  871. ;;
  872. cmp.eq pt0 = rHEPCVa, rHIIP
  873. extr.u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN
  874. ;;
  875. cmp4.eq pKrnl, pUser = PL_KERNEL, rTH1
  876. (pKrnl) br.spnt.few BdPanicHandler
  877. ;;
  878. (pt0) ssm 1 << PSR_IC
  879. (pt0) movl rTH1 = 1 << PSR_LP
  880. ;;
  881. (pt0) or rHpT3 = rHIPSR, rTH1
  882. movl rHHandler = BdSingleStep
  883. (pt0) srlz.d
  884. add rHpT1=-ThreadStateSaveAreaLength-TrapFrameLength+TrStIPSR,rHpT1
  885. (pt0) br.spnt.few Ktbv10
  886. mov pr = rHOldPreds, -2
  887. br.sptk BdGenericExceptionHandler
  888. ;;
  889. Ktbv10:
  890. st8 [rHpT1] = rHpT3
  891. movl rTH1 = 1 << PSR_SS | 1 << PSR_TB | 1 << PSR_DB
  892. ;;
  893. rsm 1 << PSR_IC
  894. mov pr = rHOldPreds, -2
  895. andcm rHIPSR = rHIPSR, rTH1 // clear ss, tb, db bits
  896. ;;
  897. srlz.d
  898. mov cr.ipsr = rHIPSR
  899. ;;
  900. rfi
  901. ;;
  902. VECTOR_EXIT(BdTakenBranchVector)
  903. //++
  904. //
  905. // BdSingleStepVector
  906. //
  907. // Cause: An instruction was successfully execcuted and the PSR.ss
  908. // bit is 1.
  909. //
  910. // Parameters: cr.iip - address of bundle containing the instruction to
  911. // be executed next.
  912. //
  913. // cr.ipsr - copy of PSR at the time of interruption.
  914. //
  915. // cr.iipa - address of bundle containing the last
  916. // successfully executed instruction
  917. //
  918. // cr.isr - faulting status information. The ISR.code
  919. // contains a bit vector for all traps which
  920. // occurred in the trapping bundle.
  921. //
  922. //--
  923. VECTOR_ENTRY(0x6000, BdSingleStepVector, cr.iipa)
  924. mov rHIIP = cr.iip
  925. movl rHEPCVa = MM_EPC_VA+0x20 // user system call entry point
  926. mov rHIPSR = cr.ipsr
  927. movl rHpT1 = BdPcr+PcInitialStack
  928. ;;
  929. ld8 rHpT1 = [rHpT1]
  930. mov rHOldPreds = pr
  931. mov rPanicCode = UNEXPECTED_KERNEL_MODE_TRAP
  932. ;;
  933. cmp.eq pt0 = rHEPCVa, rHIIP
  934. extr.u rTH1 = rHIPSR, PSR_CPL, PSR_CPL_LEN
  935. ;;
  936. cmp4.eq pKrnl, pUser = PL_KERNEL, rTH1
  937. (pKrnl) br.spnt.few BdPanicHandler
  938. ;;
  939. (pt0) ssm 1 << PSR_IC
  940. (pt0) movl rTH1 = 1 << PSR_LP
  941. ;;
  942. (pt0) or rHpT3 = rHIPSR, rTH1
  943. movl rHHandler = BdSingleStep
  944. (pt0) srlz.d
  945. add rHpT1=-ThreadStateSaveAreaLength-TrapFrameLength+TrStIPSR,rHpT1
  946. (pt0) br.spnt.few Kssv10
  947. mov pr = rHOldPreds, -2
  948. br.sptk BdGenericExceptionHandler
  949. ;;
  950. Kssv10:
  951. st8 [rHpT1] = rHpT3
  952. movl rTH1 = 1 << PSR_SS | 1 << PSR_DB
  953. ;;
  954. rsm 1 << PSR_IC
  955. mov pr = rHOldPreds, -2
  956. andcm rHIPSR = rHIPSR, rTH1 // clear ss, db bits
  957. ;;
  958. srlz.d
  959. mov cr.ipsr = rHIPSR
  960. ;;
  961. rfi
  962. ;;
  963. VECTOR_EXIT(BdSingleStepVector)
  964. .text
  965. //++
  966. //--------------------------------------------------------------------
  967. // Routine:
  968. //
  969. // BdGenericExceptionHandler
  970. //
  971. // Description:
  972. //
  973. // First level handler for heavyweight exceptions.
  974. //
  975. // On entry:
  976. //
  977. // ic off
  978. // interrupts disabled
  979. // current frame covered
  980. //
  981. // Process:
  982. //
  983. // Notes:
  984. //
  985. // PCR page mapped with TR
  986. //--------------------------------------------------------------------
  987. HANDLER_ENTRY(BdGenericExceptionHandler)
  988. .prologue
  989. .unwabi @nt, EXCEPTION_FRAME
  990. ALLOCATE_TRAP_FRAME
  991. //
  992. // sp points to trap frame
  993. //
  994. // Save exception handler routine in kernel register
  995. //
  996. mov rkHandler = rHHandler
  997. ;;
  998. //
  999. // Save interruption state in trap frame and switch to user bank registers
  1000. // and switch to kernel backing store.
  1001. //
  1002. SAVE_INTERRUPTION_STATE(Kgeh_SaveTrapFrame)
  1003. //
  1004. // Now running with user banked registers and on kernel stack.
  1005. //
  1006. // Can now take TLB faults
  1007. //
  1008. // sp -> trap frame
  1009. //
  1010. br.call.sptk brp = BdSaveTrapFrame
  1011. ;;
  1012. //
  1013. // setup debug registers if previous mode is user
  1014. //
  1015. (pUser) br.call.spnt brp = BdSetupDebugRegisters
  1016. //
  1017. // Register aliases
  1018. //
  1019. rpT1 = t0
  1020. rpT2 = t1
  1021. rpT3 = t2
  1022. rT1 = t3
  1023. rT2 = t4
  1024. rT3 = t5
  1025. rPreviousMode = t6 // previous mode
  1026. rT4 = t7
  1027. movl gp = _gp // make sure we are using loader's GP
  1028. mov rT1 = rkHandler // restore address of interruption routine
  1029. movl rpT1 = BdPcr+PcSavedIIM
  1030. ;;
  1031. ld8 rT2 = [rpT1], PcSavedIFA-PcSavedIIM // load saved IIM
  1032. add rpT2 = TrEOFMarker, sp
  1033. add rpT3 = TrStIIM, sp
  1034. ;;
  1035. ld8 rT4 = [rpT1] // load saved IFA
  1036. movl rT3 = KTRAP_FRAME_EOF | EXCEPTION_FRAME
  1037. ;;
  1038. st8 [rpT2] = rT3, TrNewBSP-TrEOFMarker
  1039. st8 [rpT3] = rT2, TrStIFA-TrStIIM // save IIM in trap frame
  1040. mov bt0 = rT1 // set destination address
  1041. ;;
  1042. st8 [rpT3] = rT4 // save IFA in trap frame
  1043. #if DBG
  1044. st8 [rpT2] = rT1 // save debug info in TrFrame
  1045. #endif // DBG
  1046. ;;
  1047. PROLOGUE_END
  1048. .regstk 0, 1, 2, 0 // must be in sync with BdExceptionExit
  1049. alloc out1 = 0,1,2,0 // alloc 0 in, 1 locals, 2 outs
  1050. //
  1051. // Dispatch the exception via call to address in rkHandler
  1052. //
  1053. .pred.rel "mutex",pUser,pKrnl
  1054. add rpT1 = TrPreviousMode, sp // -> previous mode
  1055. (pUser) mov rPreviousMode = UserMode // set previous mode
  1056. (pKrnl) mov rPreviousMode = KernelMode
  1057. ;;
  1058. st4 [rpT1] = rPreviousMode // **** TBD 1 byte -- save in trap frame
  1059. mov out0 = sp // trap frame pointer
  1060. br.call.sptk brp = bt0 // call handler(tf) (C code)
  1061. ;;
  1062. .pred.rel "mutex",pUser,pKrnl
  1063. cmp.ne pt0, pt1 = v0, zero
  1064. (pUser) mov out1 = UserMode
  1065. (pKrnl) mov out1 = KernelMode
  1066. //
  1067. // does not return
  1068. //
  1069. mov out0 = sp
  1070. (pt1) br.cond.sptk BdAlternateExit
  1071. (pt0) br.call.spnt brp = BdExceptionDispatch
  1072. nop.m 0
  1073. nop.m 0
  1074. nop.i 0
  1075. ;;
  1076. HANDLER_EXIT(BdGenericExceptionHandler)
  1077. //--------------------------------------------------------------------
  1078. // Routine:
  1079. //
  1080. // BdPanicHandler
  1081. //
  1082. // Description:
  1083. //
  1084. // Handler for panic. Call the bug check routine. A place
  1085. // holder for now.
  1086. //
  1087. // On entry:
  1088. //
  1089. // running on kernel memory stack and kernel backing store
  1090. // sp: top of stack -- points to trap frame
  1091. // interrupts enabled
  1092. //
  1093. // IIP: address of bundle causing fault
  1094. //
  1095. // IPSR: copy of PSR at time of interruption
  1096. //
  1097. // Output:
  1098. //
  1099. // sp: top of stack -- points to trap frame
  1100. //
  1101. // Return value:
  1102. //
  1103. // none
  1104. //
  1105. // Notes:
  1106. //
  1107. // If ISR code out of bounds, this code will inovke the panic handler
  1108. //
  1109. //--------------------------------------------------------------------
  1110. HANDLER_ENTRY(BdPanicHandler)
  1111. movl rTH1 = BdPcr+PcPanicStack
  1112. ;;
  1113. ld8 sp = [rTH1]
  1114. movl rTH2 = BdPcr+PcSystemReserved
  1115. ;;
  1116. st4 [rTH2] = rPanicCode
  1117. add sp = -TrapFrameLength, sp
  1118. ;;
  1119. SAVE_INTERRUPTION_STATE(Kph_SaveTrapFrame)
  1120. rpRNAT = t16
  1121. rpBSPStore= t17
  1122. rBSPStore = t18
  1123. rKBSPStore= t19
  1124. rRNAT = t20
  1125. rKrnlFPSR = t21
  1126. mov ar.rsc = RSC_KERNEL_DISABLED
  1127. add rpRNAT = TrRsRNAT, sp
  1128. add rpBSPStore = TrRsBSPSTORE, sp
  1129. ;;
  1130. mov rBSPStore = ar.bspstore
  1131. mov rRNAT = ar.rnat
  1132. ;;
  1133. st8 [rpRNAT] = rRNAT
  1134. st8 [rpBSPStore] = rBSPStore
  1135. dep rKBSPStore = rBSPStore, sp, 0, 9
  1136. ;;
  1137. mov ar.bspstore = rKBSPStore
  1138. mov ar.rsc = RSC_KERNEL
  1139. ;;
  1140. alloc t22 = ar.pfs, 0, 0, 5, 0
  1141. movl out0 = BdPcr+PcSystemReserved
  1142. ;;
  1143. ld4 out0 = [out0] // 1st argument: panic code
  1144. mov out1 = sp // 2nd argument: trap frame
  1145. //br.call.sptk.many brp = KeBugCheckEx
  1146. ;;
  1147. HANDLER_EXIT(BdPanicHandler)
  1148. //++
  1149. //--------------------------------------------------------------------
  1150. // Routine:
  1151. //
  1152. // VOID
  1153. // BdSaveTrapFrame(PKTRAP_FRAME)
  1154. //
  1155. // Description:
  1156. //
  1157. // Save volatile application state in trap frame.
  1158. // Note: sp, brp, UNAT, RSC, predicates, BSP, BSP Store,
  1159. // PFS, CSD, and FPSR saved elsewhere.
  1160. //
  1161. // Input:
  1162. //
  1163. // sp: points to trap frame
  1164. // ar.unat: contains the Nats of sp, gp, teb, which have already
  1165. // been spilled into the trap frame.
  1166. //
  1167. // Output:
  1168. //
  1169. // None
  1170. //
  1171. // Return value:
  1172. //
  1173. // none
  1174. //
  1175. //--------------------------------------------------------------------
  1176. LEAF_ENTRY(BdSaveTrapFrame)
  1177. .regstk 0, 3, 0, 0
  1178. //
  1179. // Local register aliases
  1180. //
  1181. rpTF1 = loc0
  1182. rpTF2 = loc1
  1183. rL1 = t0
  1184. rL2 = t1
  1185. rL3 = t2
  1186. rL4 = t3
  1187. rL5 = t4
  1188. //
  1189. // (ar.unat unchanged from point of save)
  1190. // Spill temporary (volatile) integer registers
  1191. //
  1192. alloc loc2 = 0,3,0,0 // don't destroy static register
  1193. add rpTF1 = TrIntT0, sp // -> t0 save area
  1194. add rpTF2 = TrIntT1, sp // -> t1 save area
  1195. ;;
  1196. .mem.offset 0,0
  1197. st8.spill [rpTF1] = t0, TrIntT2-TrIntT0 // spill t0 - t22
  1198. .mem.offset 8,0
  1199. st8.spill [rpTF2] = t1, TrIntT3-TrIntT1
  1200. ;;
  1201. .mem.offset 0,0
  1202. st8.spill [rpTF1] = t2, TrIntT4-TrIntT2
  1203. .mem.offset 8,0
  1204. st8.spill [rpTF2] = t3, TrIntT5-TrIntT3
  1205. ;;
  1206. .mem.offset 0,0
  1207. st8.spill [rpTF1] = t4, TrIntT6-TrIntT4
  1208. .mem.offset 8,0
  1209. st8.spill [rpTF2] = t5, TrIntT7-TrIntT5
  1210. ;;
  1211. .mem.offset 0,0
  1212. st8.spill [rpTF1] = t6, TrIntT8-TrIntT6
  1213. .mem.offset 8,0
  1214. st8.spill [rpTF2] = t7, TrIntT9-TrIntT7
  1215. ;;
  1216. .mem.offset 0,0
  1217. st8.spill [rpTF1] = t8, TrIntT10-TrIntT8
  1218. .mem.offset 8,0
  1219. st8.spill [rpTF2] = t9, TrIntT11-TrIntT9
  1220. ;;
  1221. .mem.offset 0,0
  1222. st8.spill [rpTF1] = t10, TrIntT12-TrIntT10
  1223. .mem.offset 8,0
  1224. st8.spill [rpTF2] = t11, TrIntT13-TrIntT11
  1225. ;;
  1226. .mem.offset 0,0
  1227. st8.spill [rpTF1] = t12, TrIntT14-TrIntT12
  1228. .mem.offset 8,0
  1229. st8.spill [rpTF2] = t13, TrIntT15-TrIntT13
  1230. ;;
  1231. .mem.offset 0,0
  1232. st8.spill [rpTF1] = t14, TrIntT16-TrIntT14
  1233. .mem.offset 8,0
  1234. st8.spill [rpTF2] = t15, TrIntT17-TrIntT15
  1235. ;;
  1236. .mem.offset 0,0
  1237. st8.spill [rpTF1] = t16, TrIntT18-TrIntT16
  1238. .mem.offset 8,0
  1239. st8.spill [rpTF2] = t17, TrIntT19-TrIntT17
  1240. ;;
  1241. .mem.offset 0,0
  1242. st8.spill [rpTF1] = t18, TrIntT20-TrIntT18
  1243. .mem.offset 8,0
  1244. st8.spill [rpTF2] = t19, TrIntT21-TrIntT19
  1245. ;;
  1246. .mem.offset 0,0
  1247. st8.spill [rpTF1] = t20, TrIntT22-TrIntT20
  1248. .mem.offset 8,0
  1249. st8.spill [rpTF2] = t21, TrIntV0-TrIntT21
  1250. ;;
  1251. .mem.offset 0,0
  1252. st8.spill [rpTF1] = t22, TrBrT0-TrIntT22
  1253. .mem.offset 8,0
  1254. st8.spill [rpTF2] = v0, TrIntNats-TrIntV0 // spill old V0
  1255. ;;
  1256. //
  1257. // Now save the Nats interger regsisters saved so far (includes Nat for sp)
  1258. //
  1259. mov rL1 = ar.unat
  1260. mov rL2 = bt0
  1261. mov rL3 = bt1
  1262. ;;
  1263. st8 [rpTF2] = rL1, TrBrT1-TrIntNats // save Nats of volatile regs
  1264. mov rL4 = ar.ccv
  1265. ;;
  1266. //
  1267. // Save temporary (volatile) branch registers
  1268. //
  1269. st8 [rpTF1] = rL2, TrApCCV-TrBrT0 // save old bt0 - bt1
  1270. st8 [rpTF2] = rL3
  1271. ;;
  1272. st8 [rpTF1] = rL4 // save ar.ccv
  1273. add rpTF1 = TrFltT0, sp // point to FltT0
  1274. add rpTF2 = TrFltT1, sp // point to FltT1
  1275. ;;
  1276. //
  1277. // Spill temporary (volatile) floating point registers
  1278. //
  1279. stf.spill [rpTF1] = ft0, TrFltT2-TrFltT0 // spill float tmp 0 - 9
  1280. stf.spill [rpTF2] = ft1, TrFltT3-TrFltT1
  1281. ;;
  1282. stf.spill [rpTF1] = ft2, TrFltT4-TrFltT2
  1283. stf.spill [rpTF2] = ft3, TrFltT5-TrFltT3
  1284. ;;
  1285. stf.spill [rpTF1] = ft4, TrFltT6-TrFltT4
  1286. stf.spill [rpTF2] = ft5, TrFltT7-TrFltT5
  1287. ;;
  1288. stf.spill [rpTF1] = ft6, TrFltT8-TrFltT6
  1289. stf.spill [rpTF2] = ft7, TrFltT9-TrFltT7
  1290. ;;
  1291. stf.spill [rpTF1] = ft8
  1292. stf.spill [rpTF2] = ft9
  1293. ;;
  1294. rum 1 << PSR_MFL // clear mfl bit
  1295. //
  1296. // TBD **** Debug/performance regs ** ?
  1297. // **** Performance regs not needed (either user or system wide)
  1298. // No performance regs switched on kernel entry
  1299. // **** Debug regs saved if in use
  1300. //
  1301. LEAF_RETURN
  1302. ;;
  1303. LEAF_EXIT(BdSaveTrapFrame)
  1304. //++
  1305. //--------------------------------------------------------------------
  1306. // Routine:
  1307. //
  1308. // VOID
  1309. // BdRestoreTrapFrame(PKTRAP_FRAME)
  1310. //
  1311. // Description:
  1312. //
  1313. // Restore volatile application state from trap frame. Restore CSD
  1314. // Note: sp, brp, RSC, UNAT, predicates, BSP, BSP Store, PFS,
  1315. // CSD and FPSR not restored here.
  1316. //
  1317. // Input:
  1318. //
  1319. // sp: points to trap frame
  1320. // RSE frame size is zero
  1321. //
  1322. // Output:
  1323. //
  1324. // None
  1325. //
  1326. // Return value:
  1327. //
  1328. // none
  1329. //
  1330. //--------------------------------------------------------------------
  1331. LEAF_ENTRY(BdRestoreTrapFrame)
  1332. LEAF_SETUP(0,2,0,0)
  1333. rpTF1 = loc0
  1334. rpTF2 = loc1
  1335. //
  1336. // **** TBD **** Restore debug/performance registers??
  1337. // **** Performance regs not needed (either user or system wide)
  1338. // No performance regs switched on kernel entry
  1339. // **** Debug regs saved if in use
  1340. //
  1341. //
  1342. // Restore RSC, CCV, CSD, and volatile branch, floating point, integer register
  1343. //
  1344. mov t21 = psr
  1345. add rpTF1 = TrRsRSC, sp
  1346. add rpTF2 = TrApCCV, sp
  1347. ;;
  1348. ld8 t5 = [rpTF1], TrIntNats-TrRsRSC
  1349. ld8 t1 = [rpTF2], TrSegCSD-TrApCCV
  1350. ;;
  1351. ld8 t0 = [rpTF1], TrBrT0-TrIntNats
  1352. ld8 t3 = [rpTF2], TrBrT1-TrSegCSD
  1353. ;;
  1354. ld8 t2 = [rpTF1]
  1355. ld8 t4 = [rpTF2]
  1356. mov ar.rsc = t5
  1357. mov ar.ccv = t1
  1358. add rpTF1 = TrIntGp, sp
  1359. mov ar.unat = t0
  1360. mov ar.csd = t3
  1361. add rpTF2 = TrIntT0, sp
  1362. ;;
  1363. ld8.fill gp = [rpTF1], TrIntT1-TrIntGp
  1364. ld8.fill t0 = [rpTF2], TrIntT2-TrIntT0
  1365. mov bt0 = t2
  1366. ;;
  1367. ld8.fill t1 = [rpTF1], TrIntT3-TrIntT1
  1368. ld8.fill t2 = [rpTF2], TrIntT4-TrIntT2
  1369. mov bt1 = t4
  1370. ;;
  1371. ld8.fill t3 = [rpTF1], TrIntT5-TrIntT3
  1372. ld8.fill t4 = [rpTF2], TrIntT6-TrIntT4
  1373. tbit.z pt1 = t21, PSR_MFL
  1374. ;;
  1375. ld8.fill t5 = [rpTF1], TrIntT7-TrIntT5
  1376. ld8.fill t6 = [rpTF2], TrIntT8-TrIntT6
  1377. ;;
  1378. ld8.fill t7 = [rpTF1], TrIntT9-TrIntT7
  1379. ld8.fill t8 = [rpTF2], TrIntT10-TrIntT8
  1380. ;;
  1381. ld8.fill t9 = [rpTF1], TrIntT11-TrIntT9
  1382. ld8.fill t10 = [rpTF2], TrIntT12-TrIntT10
  1383. ;;
  1384. ld8.fill t11 = [rpTF1], TrIntT13-TrIntT11
  1385. ld8.fill t12 = [rpTF2], TrIntT14-TrIntT12
  1386. ;;
  1387. ld8.fill t13 = [rpTF1], TrIntT15-TrIntT13
  1388. ld8.fill t14 = [rpTF2], TrIntT16-TrIntT14
  1389. ;;
  1390. ld8.fill t15 = [rpTF1], TrIntT17-TrIntT15
  1391. ld8.fill t16 = [rpTF2], TrIntT18-TrIntT16
  1392. ;;
  1393. ld8.fill t17 = [rpTF1], TrIntT19-TrIntT17
  1394. ld8.fill t18 = [rpTF2], TrIntT20-TrIntT18
  1395. ;;
  1396. ld8.fill t19 = [rpTF1], TrIntT21-TrIntT19
  1397. ld8.fill t20 = [rpTF2], TrIntT22-TrIntT20
  1398. ;;
  1399. ld8.fill t21 = [rpTF1], TrIntTeb-TrIntT21
  1400. ld8.fill t22 = [rpTF2], TrIntV0-TrIntT22
  1401. ;;
  1402. ld8.fill teb = [rpTF1], TrFltT1-TrIntTeb
  1403. ld8.fill v0 = [rpTF2], TrFltT0-TrIntV0
  1404. ;;
  1405. ldf.fill ft0 = [rpTF2], TrFltT2-TrFltT0
  1406. ldf.fill ft1 = [rpTF1], TrFltT3-TrFltT1
  1407. ;;
  1408. ldf.fill ft2 = [rpTF2], TrFltT4-TrFltT2
  1409. ldf.fill ft3 = [rpTF1], TrFltT5-TrFltT3
  1410. ;;
  1411. ldf.fill ft4 = [rpTF2], TrFltT6-TrFltT4
  1412. ldf.fill ft5 = [rpTF1], TrFltT7-TrFltT5
  1413. ;;
  1414. ldf.fill ft6 = [rpTF2], TrFltT8-TrFltT6
  1415. ldf.fill ft7 = [rpTF1], TrFltT9-TrFltT7
  1416. ;;
  1417. ldf.fill ft8 = [rpTF2]
  1418. ldf.fill ft9 = [rpTF1]
  1419. br.ret.sptk.many brp
  1420. ;;
  1421. LEAF_EXIT(BdRestoreTrapFrame)
  1422. //++
  1423. //--------------------------------------------------------------------
  1424. // Routine:
  1425. //
  1426. // VOID
  1427. // BdSetupDebugRegisters
  1428. //
  1429. // Description:
  1430. //
  1431. // We maintain two debug register flags:
  1432. // 1. Thread DebugActive: Debug registers active for current thread
  1433. // 2. PCR KernelDebugActive: Debug registers active in kernel mode
  1434. // (setup by kernel debugger)
  1435. //
  1436. // On user -> kernel transitions there are four possibilities:
  1437. //
  1438. // Thread Kernel
  1439. // DebugActive DebugActive Action
  1440. //
  1441. // 1. 0 0 None
  1442. //
  1443. // 2. 1 0 None (kernel PSR.db = 0 by default)
  1444. //
  1445. // 3. 0 1 Set PSR.db = 1 for kernel
  1446. //
  1447. // 4. 1 1 Set PSR.db = 1 for kernel and
  1448. // load kernel debug registers
  1449. //
  1450. // Note we never save the user debug registers:
  1451. // the user cannot change the DRs so the values in the DR save area are
  1452. // always up-to-date (set by SetContext).
  1453. //
  1454. // Input:
  1455. //
  1456. // None (Previous mode is USER)
  1457. //
  1458. // Output:
  1459. //
  1460. // None
  1461. //
  1462. // Return value:
  1463. //
  1464. // none
  1465. //
  1466. //--------------------------------------------------------------------
  1467. LEAF_ENTRY(BdSetupDebugRegisters)
  1468. //
  1469. // *** TBD -- no support for kernel debug registers (KernelDebugActive = 0)
  1470. // All the calls to this function are removed and have to be reinstated
  1471. // when hardware debug support is implemented in the kernel debugger.
  1472. //
  1473. LEAF_RETURN
  1474. LEAF_EXIT(BdSetupDebugRegisters)
  1475. //++
  1476. //--------------------------------------------------------------------
  1477. // Routine:
  1478. //
  1479. // VOID
  1480. // BdRestoreDebugRegisters
  1481. //
  1482. // Description:
  1483. //
  1484. // If debug active, restore user debug registers from DR save area in
  1485. // kernel stack.
  1486. //
  1487. // Input:
  1488. //
  1489. // None
  1490. //
  1491. // Output:
  1492. //
  1493. // None
  1494. //
  1495. // Return value:
  1496. //
  1497. // none
  1498. //
  1499. // Note:
  1500. // We find the DR save are from the the StackBase not PCR->InitialStack,
  1501. // which can be changed in BdCallUserMode().
  1502. //
  1503. //--------------------------------------------------------------------
  1504. LEAF_ENTRY(BdRestoreDebugRegisters)
  1505. //
  1506. // Local register aliases
  1507. //
  1508. rpSA0 = t0
  1509. rpSA1 = t1
  1510. rDebugActive = t2
  1511. rpT1 = t3
  1512. rPrcb = t4
  1513. rDr0 = t5
  1514. rDr1 = t6
  1515. rDrIndex0 = t7
  1516. rDrIndex1 = t8
  1517. rSaveLC = t9
  1518. rpCurrentThread = t10
  1519. rStackBase = t11
  1520. pNoRestore = pt0
  1521. //
  1522. // Restore debug registers, if debug active
  1523. //
  1524. movl rpT1 = BdPcr+PcCurrentThread
  1525. ;;
  1526. mov rSaveLC = ar.lc // save
  1527. ld8 rpCurrentThread = [rpT1] // get Current thread pointer
  1528. ;;
  1529. add rpT1 = ThDebugActive, rpCurrentThread
  1530. add rStackBase = ThStackBase, rpCurrentThread
  1531. ;;
  1532. ld1 rDebugActive = [rpT1] // get thread debug active flag
  1533. ;;
  1534. cmp.eq pNoRestore = zero, rDebugActive
  1535. (pNoRestore) br.sptk Krdr_Exit // skip if not active
  1536. ;;
  1537. mov rDrIndex0 = 0
  1538. mov rDrIndex1 = 1
  1539. ;;
  1540. add rpSA0 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbI0,rStackBase
  1541. add rpSA1 = -ThreadStateSaveAreaLength+TsDebugRegisters+DrDbI1,rStackBase
  1542. mov ar.lc = 3 // 4 pair of ibr
  1543. ;;
  1544. Krdr_ILoop:
  1545. ld8 rDr0 = [rpSA0], 16 // get ibr pair
  1546. ld8 rDr1 = [rpSA1], 16 // step by 16 = 1 pair of DRs
  1547. ;;
  1548. .auto
  1549. mov ibr[rDrIndex0] = rDr0 // restore ibr pair
  1550. mov ibr[rDrIndex1] = rDr1
  1551. ;;
  1552. add rDrIndex0 = 1, rDrIndex0 // next pair
  1553. add rDrIndex1 = 1, rDrIndex1
  1554. br.cloop.sptk Krdr_ILoop
  1555. ;;
  1556. mov ar.lc = 3 // 4 pair of dbr
  1557. mov rDrIndex0 = 0
  1558. mov rDrIndex1 = 1
  1559. ;;
  1560. Krdr_DLoop:
  1561. ld8 rDr0 = [rpSA0], 16 // get dbr pair
  1562. ld8 rDr1 = [rpSA1], 16 // step by 16 = 1 pair of DRs
  1563. ;;
  1564. mov dbr[rDrIndex0] = rDr0 // restore dbr pair
  1565. mov dbr[rDrIndex1] = rDr1
  1566. ;;
  1567. .default
  1568. add rDrIndex0 = 1, rDrIndex0 // next pair
  1569. add rDrIndex1 = 1, rDrIndex1
  1570. br.cloop.sptk Krdr_DLoop
  1571. ;;
  1572. mov ar.lc = rSaveLC // restore
  1573. Krdr_Exit:
  1574. LEAF_RETURN
  1575. LEAF_EXIT(BdRestoreDebugRegisters)
  1576. //++
  1577. //--------------------------------------------------------------------
  1578. // Routine:
  1579. //
  1580. // VOID
  1581. // BdSaveExceptionFrame(PKEXCEPTION_FRAME)
  1582. //
  1583. // Description:
  1584. //
  1585. // Save preserved context in exception frame.
  1586. //
  1587. // Input:
  1588. //
  1589. // a0: points to exception frame
  1590. //
  1591. // Output:
  1592. //
  1593. // None
  1594. //
  1595. // Return value:
  1596. //
  1597. // none
  1598. //
  1599. // Note: t0 may contain the trap frame address; don't touch it.
  1600. //
  1601. //--------------------------------------------------------------------
  1602. LEAF_ENTRY(BdSaveExceptionFrame)
  1603. //
  1604. // Local register aliases
  1605. //
  1606. rpEF1 = t10
  1607. rpEF2 = t11
  1608. add rpEF1 = ExIntS0, a0 // -> ExIntS0
  1609. add rpEF2 = ExIntS1, a0 // -> ExIntS1
  1610. mov t3 = ar.ec
  1611. ;;
  1612. .mem.offset 0,0
  1613. st8.spill [rpEF1] = s0, ExIntS2-ExIntS0
  1614. .mem.offset 8,0
  1615. st8.spill [rpEF2] = s1, ExIntS3-ExIntS1
  1616. mov t4 = ar.lc
  1617. ;;
  1618. .mem.offset 0,0
  1619. st8.spill [rpEF1] = s2, ExApEC-ExIntS2
  1620. .mem.offset 8,0
  1621. st8.spill [rpEF2] = s3, ExApLC-ExIntS3
  1622. mov t5 = bs0
  1623. ;;
  1624. st8 [rpEF1] = t3, ExBrS0-ExApEC
  1625. st8 [rpEF2] = t4, ExBrS1-ExApLC
  1626. mov t6 = bs1
  1627. ;;
  1628. mov t2 = ar.unat // save user nat register for
  1629. mov t7 = bs2
  1630. mov t8 = bs3
  1631. st8 [rpEF1] = t5, ExBrS2-ExBrS0
  1632. st8 [rpEF2] = t6, ExBrS3-ExBrS1
  1633. mov t9 = bs4
  1634. ;;
  1635. st8 [rpEF1] = t7, ExBrS4-ExBrS2
  1636. st8 [rpEF2] = t8, ExIntNats-ExBrS3
  1637. ;;
  1638. st8 [rpEF1] = t9, ExFltS0-ExBrS4
  1639. st8 [rpEF2] = t2, ExFltS1-ExIntNats
  1640. ;;
  1641. stf.spill [rpEF1] = fs0, ExFltS2-ExFltS0
  1642. stf.spill [rpEF2] = fs1, ExFltS3-ExFltS1
  1643. ;;
  1644. stf.spill [rpEF1] = fs2, ExFltS4-ExFltS2
  1645. stf.spill [rpEF2] = fs3, ExFltS5-ExFltS3
  1646. ;;
  1647. stf.spill [rpEF1] = fs4, ExFltS6-ExFltS4
  1648. stf.spill [rpEF2] = fs5, ExFltS7-ExFltS5
  1649. ;;
  1650. stf.spill [rpEF1] = fs6, ExFltS8-ExFltS6
  1651. stf.spill [rpEF2] = fs7, ExFltS9-ExFltS7
  1652. ;;
  1653. stf.spill [rpEF1] = fs8, ExFltS10-ExFltS8
  1654. stf.spill [rpEF2] = fs9, ExFltS11-ExFltS9
  1655. ;;
  1656. stf.spill [rpEF1] = fs10, ExFltS12-ExFltS10
  1657. stf.spill [rpEF2] = fs11, ExFltS13-ExFltS11
  1658. ;;
  1659. stf.spill [rpEF1] = fs12, ExFltS14-ExFltS12
  1660. stf.spill [rpEF2] = fs13, ExFltS15-ExFltS13
  1661. ;;
  1662. stf.spill [rpEF1] = fs14, ExFltS16-ExFltS14
  1663. stf.spill [rpEF2] = fs15, ExFltS17-ExFltS15
  1664. ;;
  1665. stf.spill [rpEF1] = fs16, ExFltS18-ExFltS16
  1666. stf.spill [rpEF2] = fs17, ExFltS19-ExFltS17
  1667. ;;
  1668. stf.spill [rpEF1] = fs18
  1669. stf.spill [rpEF2] = fs19
  1670. LEAF_RETURN
  1671. ;;
  1672. LEAF_EXIT(BdSaveExceptionFrame)
  1673. //--------------------------------------------------------------------
  1674. // Routine:
  1675. //
  1676. // VOID
  1677. // BdRestoreExceptionFrame(PKEXCEPTION_FRAME)
  1678. //
  1679. // Description:
  1680. //
  1681. // Restores preserved context from the exception frame. Also
  1682. // restore volatile part of floating point context not restored with
  1683. // rest of volatile context.
  1684. //
  1685. // Input:
  1686. //
  1687. // a0: points to exception frame
  1688. //
  1689. // Output:
  1690. //
  1691. // None
  1692. //
  1693. // Return value:
  1694. //
  1695. // none
  1696. //
  1697. //--------------------------------------------------------------------
  1698. LEAF_ENTRY(BdRestoreExceptionFrame)
  1699. //
  1700. // Local register aliases
  1701. //
  1702. rpEF1 = t10
  1703. rpEF2 = t11
  1704. add rpEF1 = ExIntNats, a0
  1705. add rpEF2 = ExApEC, a0
  1706. ;;
  1707. ld8 t2 = [rpEF1], ExBrS0-ExIntNats
  1708. ld8 t3 = [rpEF2], ExApLC-ExApEC
  1709. ;;
  1710. ld8 t5 = [rpEF1], ExBrS1-ExBrS0
  1711. ld8 t4 = [rpEF2], ExBrS2-ExApLC
  1712. ;;
  1713. mov ar.unat = t2
  1714. mov ar.ec = t3
  1715. ;;
  1716. ld8 t6 = [rpEF1], ExBrS3-ExBrS1
  1717. ld8 t7 = [rpEF2], ExBrS4-ExBrS2
  1718. mov ar.lc = t4
  1719. ;;
  1720. ld8 t8 = [rpEF1], ExIntS0-ExBrS3
  1721. ld8 t9 = [rpEF2], ExIntS1-ExBrS4
  1722. mov bs0 = t5
  1723. ;;
  1724. ld8.fill s0 = [rpEF1], ExIntS2-ExIntS0
  1725. ld8.fill s1 = [rpEF2], ExIntS3-ExIntS1
  1726. mov bs1 = t6
  1727. ;;
  1728. ld8.fill s2 = [rpEF1], ExFltS0-ExIntS2
  1729. ld8.fill s3 = [rpEF2], ExFltS1-ExIntS3
  1730. mov bs2 = t7
  1731. ;;
  1732. ldf.fill fs0 = [rpEF1], ExFltS2-ExFltS0
  1733. ldf.fill fs1 = [rpEF2], ExFltS3-ExFltS1
  1734. mov bs3 = t8
  1735. ;;
  1736. ldf.fill fs2 = [rpEF1], ExFltS4-ExFltS2
  1737. ldf.fill fs3 = [rpEF2], ExFltS5-ExFltS3
  1738. mov bs4 = t9
  1739. ;;
  1740. ldf.fill fs4 = [rpEF1], ExFltS6-ExFltS4
  1741. ldf.fill fs5 = [rpEF2], ExFltS7-ExFltS5
  1742. ;;
  1743. ldf.fill fs6 = [rpEF1], ExFltS8-ExFltS6
  1744. ldf.fill fs7 = [rpEF2], ExFltS9-ExFltS7
  1745. ;;
  1746. ldf.fill fs8 = [rpEF1], ExFltS10-ExFltS8
  1747. ldf.fill fs9 = [rpEF2], ExFltS11-ExFltS9
  1748. ;;
  1749. ldf.fill fs10 = [rpEF1], ExFltS12-ExFltS10
  1750. ldf.fill fs11 = [rpEF2], ExFltS13-ExFltS11
  1751. ;;
  1752. ldf.fill fs12 = [rpEF1], ExFltS14-ExFltS12
  1753. ldf.fill fs13 = [rpEF2], ExFltS15-ExFltS13
  1754. ;;
  1755. ldf.fill fs14 = [rpEF1], ExFltS16-ExFltS14
  1756. ldf.fill fs15 = [rpEF2], ExFltS17-ExFltS15
  1757. ;;
  1758. ldf.fill fs16 = [rpEF1], ExFltS18-ExFltS16
  1759. ldf.fill fs17 = [rpEF2], ExFltS19-ExFltS17
  1760. ;;
  1761. ldf.fill fs18 = [rpEF1]
  1762. ldf.fill fs19 = [rpEF2]
  1763. LEAF_RETURN
  1764. ;;
  1765. LEAF_EXIT(BdRestoreExceptionFrame)
  1766. //++
  1767. //--------------------------------------------------------------------
  1768. // Routine:
  1769. //
  1770. // BdSaveHigherFPVolatile(PKHIGHER_FP_SAVEAREA)
  1771. //
  1772. // Description:
  1773. //
  1774. // Save higher FP volatile context in higher FP save area
  1775. //
  1776. // Input:
  1777. //
  1778. // a0: pointer to higher FP save area
  1779. // brp: return address
  1780. //
  1781. // Output:
  1782. //
  1783. // None
  1784. //
  1785. // Return value:
  1786. //
  1787. // None
  1788. //
  1789. //--------------------------------------------------------------------
  1790. LEAF_ENTRY(BdSaveHigherFPVolatile)
  1791. //
  1792. // Local register aliases
  1793. //
  1794. rpSA1 = t0
  1795. rpSA2 = t1
  1796. //
  1797. // Spill higher floating point volatile registers f32-f127.
  1798. // Must add length of preserved area within FP save area to
  1799. // point to volatile save area.
  1800. //
  1801. //
  1802. // Clear DFH bit so the high floating point set may be saved by the kernel
  1803. // Disable interrupts so that save is atomic
  1804. //
  1805. rsm 1 << PSR_DFH
  1806. add rpSA1 = HiFltF32, a0 // -> HiFltF32
  1807. add rpSA2 = HiFltF33, a0 // -> HiFltF33
  1808. ;;
  1809. srlz.d
  1810. stf.spill [rpSA1] = f32, HiFltF34-HiFltF32
  1811. stf.spill [rpSA2] = f33, HiFltF35-HiFltF33
  1812. ;;
  1813. stf.spill [rpSA1] = f34, HiFltF36-HiFltF34
  1814. stf.spill [rpSA2] = f35, HiFltF37-HiFltF35
  1815. ;;
  1816. stf.spill [rpSA1] = f36, HiFltF38-HiFltF36
  1817. stf.spill [rpSA2] = f37, HiFltF39-HiFltF37
  1818. ;;
  1819. stf.spill [rpSA1] = f38, HiFltF40-HiFltF38
  1820. stf.spill [rpSA2] = f39, HiFltF41-HiFltF39
  1821. ;;
  1822. stf.spill [rpSA1] = f40, HiFltF42-HiFltF40
  1823. stf.spill [rpSA2] = f41, HiFltF43-HiFltF41
  1824. ;;
  1825. stf.spill [rpSA1] = f42, HiFltF44-HiFltF42
  1826. stf.spill [rpSA2] = f43, HiFltF45-HiFltF43
  1827. ;;
  1828. stf.spill [rpSA1] = f44, HiFltF46-HiFltF44
  1829. stf.spill [rpSA2] = f45, HiFltF47-HiFltF45
  1830. ;;
  1831. stf.spill [rpSA1] = f46, HiFltF48-HiFltF46
  1832. stf.spill [rpSA2] = f47, HiFltF49-HiFltF47
  1833. ;;
  1834. stf.spill [rpSA1] = f48, HiFltF50-HiFltF48
  1835. stf.spill [rpSA2] = f49, HiFltF51-HiFltF49
  1836. ;;
  1837. stf.spill [rpSA1] = f50, HiFltF52-HiFltF50
  1838. stf.spill [rpSA2] = f51, HiFltF53-HiFltF51
  1839. ;;
  1840. stf.spill [rpSA1] = f52, HiFltF54-HiFltF52
  1841. stf.spill [rpSA2] = f53, HiFltF55-HiFltF53
  1842. ;;
  1843. stf.spill [rpSA1] = f54, HiFltF56-HiFltF54
  1844. stf.spill [rpSA2] = f55, HiFltF57-HiFltF55
  1845. ;;
  1846. stf.spill [rpSA1] = f56, HiFltF58-HiFltF56
  1847. stf.spill [rpSA2] = f57, HiFltF59-HiFltF57
  1848. ;;
  1849. stf.spill [rpSA1] = f58, HiFltF60-HiFltF58
  1850. stf.spill [rpSA2] = f59, HiFltF61-HiFltF59
  1851. ;;
  1852. stf.spill [rpSA1] = f60, HiFltF62-HiFltF60
  1853. stf.spill [rpSA2] = f61, HiFltF63-HiFltF61
  1854. ;;
  1855. stf.spill [rpSA1] = f62, HiFltF64-HiFltF62
  1856. stf.spill [rpSA2] = f63, HiFltF65-HiFltF63
  1857. ;;
  1858. stf.spill [rpSA1] = f64, HiFltF66-HiFltF64
  1859. stf.spill [rpSA2] = f65, HiFltF67-HiFltF65
  1860. ;;
  1861. stf.spill [rpSA1] = f66, HiFltF68-HiFltF66
  1862. stf.spill [rpSA2] = f67, HiFltF69-HiFltF67
  1863. ;;
  1864. stf.spill [rpSA1] = f68, HiFltF70-HiFltF68
  1865. stf.spill [rpSA2] = f69, HiFltF71-HiFltF69
  1866. ;;
  1867. stf.spill [rpSA1] = f70, HiFltF72-HiFltF70
  1868. stf.spill [rpSA2] = f71, HiFltF73-HiFltF71
  1869. ;;
  1870. stf.spill [rpSA1] = f72, HiFltF74-HiFltF72
  1871. stf.spill [rpSA2] = f73, HiFltF75-HiFltF73
  1872. ;;
  1873. stf.spill [rpSA1] = f74, HiFltF76-HiFltF74
  1874. stf.spill [rpSA2] = f75, HiFltF77-HiFltF75
  1875. ;;
  1876. stf.spill [rpSA1] = f76, HiFltF78-HiFltF76
  1877. stf.spill [rpSA2] = f77, HiFltF79-HiFltF77
  1878. ;;
  1879. stf.spill [rpSA1] = f78, HiFltF80-HiFltF78
  1880. stf.spill [rpSA2] = f79, HiFltF81-HiFltF79
  1881. ;;
  1882. stf.spill [rpSA1] = f80, HiFltF82-HiFltF80
  1883. stf.spill [rpSA2] = f81, HiFltF83-HiFltF81
  1884. ;;
  1885. stf.spill [rpSA1] = f82, HiFltF84-HiFltF82
  1886. stf.spill [rpSA2] = f83, HiFltF85-HiFltF83
  1887. ;;
  1888. stf.spill [rpSA1] = f84, HiFltF86-HiFltF84
  1889. stf.spill [rpSA2] = f85, HiFltF87-HiFltF85
  1890. ;;
  1891. stf.spill [rpSA1] = f86, HiFltF88-HiFltF86
  1892. stf.spill [rpSA2] = f87, HiFltF89-HiFltF87
  1893. ;;
  1894. stf.spill [rpSA1] = f88, HiFltF90-HiFltF88
  1895. stf.spill [rpSA2] = f89, HiFltF91-HiFltF89
  1896. ;;
  1897. stf.spill [rpSA1] = f90, HiFltF92-HiFltF90
  1898. stf.spill [rpSA2] = f91, HiFltF93-HiFltF91
  1899. ;;
  1900. stf.spill [rpSA1] = f92, HiFltF94-HiFltF92
  1901. stf.spill [rpSA2] = f93, HiFltF95-HiFltF93
  1902. ;;
  1903. stf.spill [rpSA1] = f94, HiFltF96-HiFltF94
  1904. stf.spill [rpSA2] = f95, HiFltF97-HiFltF95
  1905. ;;
  1906. stf.spill [rpSA1] = f96, HiFltF98-HiFltF96
  1907. stf.spill [rpSA2] = f97, HiFltF99-HiFltF97
  1908. ;;
  1909. stf.spill [rpSA1] = f98, HiFltF100-HiFltF98
  1910. stf.spill [rpSA2] = f99, HiFltF101-HiFltF99
  1911. ;;
  1912. stf.spill [rpSA1] = f100, HiFltF102-HiFltF100
  1913. stf.spill [rpSA2] = f101, HiFltF103-HiFltF101
  1914. ;;
  1915. stf.spill [rpSA1] = f102, HiFltF104-HiFltF102
  1916. stf.spill [rpSA2] = f103, HiFltF105-HiFltF103
  1917. ;;
  1918. stf.spill [rpSA1] = f104, HiFltF106-HiFltF104
  1919. stf.spill [rpSA2] = f105, HiFltF107-HiFltF105
  1920. ;;
  1921. stf.spill [rpSA1] = f106, HiFltF108-HiFltF106
  1922. stf.spill [rpSA2] = f107, HiFltF109-HiFltF107
  1923. ;;
  1924. stf.spill [rpSA1] = f108, HiFltF110-HiFltF108
  1925. stf.spill [rpSA2] = f109, HiFltF111-HiFltF109
  1926. ;;
  1927. stf.spill [rpSA1] = f110, HiFltF112-HiFltF110
  1928. stf.spill [rpSA2] = f111, HiFltF113-HiFltF111
  1929. ;;
  1930. stf.spill [rpSA1] = f112, HiFltF114-HiFltF112
  1931. stf.spill [rpSA2] = f113, HiFltF115-HiFltF113
  1932. ;;
  1933. stf.spill [rpSA1] = f114, HiFltF116-HiFltF114
  1934. stf.spill [rpSA2] = f115, HiFltF117-HiFltF115
  1935. ;;
  1936. stf.spill [rpSA1] = f116, HiFltF118-HiFltF116
  1937. stf.spill [rpSA2] = f117, HiFltF119-HiFltF117
  1938. ;;
  1939. stf.spill [rpSA1] = f118, HiFltF120-HiFltF118
  1940. stf.spill [rpSA2] = f119, HiFltF121-HiFltF119
  1941. ;;
  1942. stf.spill [rpSA1] = f120, HiFltF122-HiFltF120
  1943. stf.spill [rpSA2] = f121, HiFltF123-HiFltF121
  1944. ;;
  1945. stf.spill [rpSA1] = f122, HiFltF124-HiFltF122
  1946. stf.spill [rpSA2] = f123, HiFltF125-HiFltF123
  1947. ;;
  1948. stf.spill [rpSA1] = f124, HiFltF126-HiFltF124
  1949. stf.spill [rpSA2] = f125, HiFltF127-HiFltF125
  1950. ;;
  1951. stf.spill [rpSA1] = f126
  1952. stf.spill [rpSA2] = f127
  1953. //
  1954. // Set DFH bit so the high floating point set may not be used by the kernel
  1955. // Must clear mfh after fp registers saved
  1956. //
  1957. rsm 1 << PSR_MFH
  1958. ssm 1 << PSR_DFH
  1959. ;;
  1960. srlz.d
  1961. LEAF_RETURN
  1962. LEAF_EXIT(BdSaveHigherFPVolatile)
  1963. //++
  1964. //--------------------------------------------------------------------
  1965. // Routine:
  1966. //
  1967. // BdRestoreHigherFPVolatile()
  1968. //
  1969. // Description:
  1970. //
  1971. // Restore higher FP volatile context from higher FP save area
  1972. //
  1973. // N.B. This function is carefully constructed to use only scratch
  1974. // registers rHpT1, rHpT3, and rTH2. This function may be
  1975. // called by C code and the disabled fp vector when user
  1976. // and kernel bank is used respectively.
  1977. // N.B. Caller must ensure higher fp enabled (psr.dfh=0)
  1978. // N.B. Caller must ensure no interrupt during restore
  1979. //
  1980. // Input:
  1981. //
  1982. // None.
  1983. //
  1984. // Output:
  1985. //
  1986. // None
  1987. //
  1988. // Return value:
  1989. //
  1990. // None
  1991. //
  1992. //--------------------------------------------------------------------
  1993. LEAF_ENTRY(BdRestoreHigherFPVolatile)
  1994. //
  1995. // rHpT1 & rHpT3 are 2 registers that are available as
  1996. // scratch registers in this function.
  1997. //
  1998. srlz.d
  1999. movl rHpT1 = BdPcr+PcInitialStack
  2000. ;;
  2001. ld8 rTH2 = [rHpT1]
  2002. ;;
  2003. add rHpT1 = -ThreadStateSaveAreaLength+TsHigherFPVolatile+HiFltF32, rTH2
  2004. add rHpT3 = -ThreadStateSaveAreaLength+TsHigherFPVolatile+HiFltF33, rTH2
  2005. ;;
  2006. ldf.fill f32 = [rHpT1], HiFltF34-HiFltF32
  2007. ldf.fill f33 = [rHpT3], HiFltF35-HiFltF33
  2008. ;;
  2009. ldf.fill f34 = [rHpT1], HiFltF36-HiFltF34
  2010. ldf.fill f35 = [rHpT3], HiFltF37-HiFltF35
  2011. ;;
  2012. ldf.fill f36 = [rHpT1], HiFltF38-HiFltF36
  2013. ldf.fill f37 = [rHpT3], HiFltF39-HiFltF37
  2014. ;;
  2015. ldf.fill f38 = [rHpT1], HiFltF40-HiFltF38
  2016. ldf.fill f39 = [rHpT3], HiFltF41-HiFltF39
  2017. ;;
  2018. ldf.fill f40 = [rHpT1], HiFltF42-HiFltF40
  2019. ldf.fill f41 = [rHpT3], HiFltF43-HiFltF41
  2020. ;;
  2021. ldf.fill f42 = [rHpT1], HiFltF44-HiFltF42
  2022. ldf.fill f43 = [rHpT3], HiFltF45-HiFltF43
  2023. ;;
  2024. ldf.fill f44 = [rHpT1], HiFltF46-HiFltF44
  2025. ldf.fill f45 = [rHpT3], HiFltF47-HiFltF45
  2026. ;;
  2027. ldf.fill f46 = [rHpT1], HiFltF48-HiFltF46
  2028. ldf.fill f47 = [rHpT3], HiFltF49-HiFltF47
  2029. ;;
  2030. ldf.fill f48 = [rHpT1], HiFltF50-HiFltF48
  2031. ldf.fill f49 = [rHpT3], HiFltF51-HiFltF49
  2032. ;;
  2033. ldf.fill f50 = [rHpT1], HiFltF52-HiFltF50
  2034. ldf.fill f51 = [rHpT3], HiFltF53-HiFltF51
  2035. ;;
  2036. ldf.fill f52 = [rHpT1], HiFltF54-HiFltF52
  2037. ldf.fill f53 = [rHpT3], HiFltF55-HiFltF53
  2038. ;;
  2039. ldf.fill f54 = [rHpT1], HiFltF56-HiFltF54
  2040. ldf.fill f55 = [rHpT3], HiFltF57-HiFltF55
  2041. ;;
  2042. ldf.fill f56 = [rHpT1], HiFltF58-HiFltF56
  2043. ldf.fill f57 = [rHpT3], HiFltF59-HiFltF57
  2044. ;;
  2045. ldf.fill f58 = [rHpT1], HiFltF60-HiFltF58
  2046. ldf.fill f59 = [rHpT3], HiFltF61-HiFltF59
  2047. ;;
  2048. ldf.fill f60 = [rHpT1], HiFltF62-HiFltF60
  2049. ldf.fill f61 = [rHpT3], HiFltF63-HiFltF61
  2050. ;;
  2051. ldf.fill f62 = [rHpT1], HiFltF64-HiFltF62
  2052. ldf.fill f63 = [rHpT3], HiFltF65-HiFltF63
  2053. ;;
  2054. ldf.fill f64 = [rHpT1], HiFltF66-HiFltF64
  2055. ldf.fill f65 = [rHpT3], HiFltF67-HiFltF65
  2056. ;;
  2057. ldf.fill f66 = [rHpT1], HiFltF68-HiFltF66
  2058. ldf.fill f67 = [rHpT3], HiFltF69-HiFltF67
  2059. ;;
  2060. ldf.fill f68 = [rHpT1], HiFltF70-HiFltF68
  2061. ldf.fill f69 = [rHpT3], HiFltF71-HiFltF69
  2062. ;;
  2063. ldf.fill f70 = [rHpT1], HiFltF72-HiFltF70
  2064. ldf.fill f71 = [rHpT3], HiFltF73-HiFltF71
  2065. ;;
  2066. ldf.fill f72 = [rHpT1], HiFltF74-HiFltF72
  2067. ldf.fill f73 = [rHpT3], HiFltF75-HiFltF73
  2068. ;;
  2069. ldf.fill f74 = [rHpT1], HiFltF76-HiFltF74
  2070. ldf.fill f75 = [rHpT3], HiFltF77-HiFltF75
  2071. ;;
  2072. ldf.fill f76 = [rHpT1], HiFltF78-HiFltF76
  2073. ldf.fill f77 = [rHpT3], HiFltF79-HiFltF77
  2074. ;;
  2075. ldf.fill f78 = [rHpT1], HiFltF80-HiFltF78
  2076. ldf.fill f79 = [rHpT3], HiFltF81-HiFltF79
  2077. ;;
  2078. ldf.fill f80 = [rHpT1], HiFltF82-HiFltF80
  2079. ldf.fill f81 = [rHpT3], HiFltF83-HiFltF81
  2080. ;;
  2081. ldf.fill f82 = [rHpT1], HiFltF84-HiFltF82
  2082. ldf.fill f83 = [rHpT3], HiFltF85-HiFltF83
  2083. ;;
  2084. ldf.fill f84 = [rHpT1], HiFltF86-HiFltF84
  2085. ldf.fill f85 = [rHpT3], HiFltF87-HiFltF85
  2086. ;;
  2087. ldf.fill f86 = [rHpT1], HiFltF88-HiFltF86
  2088. ldf.fill f87 = [rHpT3], HiFltF89-HiFltF87
  2089. ;;
  2090. ldf.fill f88 = [rHpT1], HiFltF90-HiFltF88
  2091. ldf.fill f89 = [rHpT3], HiFltF91-HiFltF89
  2092. ;;
  2093. ldf.fill f90 = [rHpT1], HiFltF92-HiFltF90
  2094. ldf.fill f91 = [rHpT3], HiFltF93-HiFltF91
  2095. ;;
  2096. ldf.fill f92 = [rHpT1], HiFltF94-HiFltF92
  2097. ldf.fill f93 = [rHpT3], HiFltF95-HiFltF93
  2098. ;;
  2099. ldf.fill f94 = [rHpT1], HiFltF96-HiFltF94
  2100. ldf.fill f95 = [rHpT3], HiFltF97-HiFltF95
  2101. ;;
  2102. ldf.fill f96 = [rHpT1], HiFltF98-HiFltF96
  2103. ldf.fill f97 = [rHpT3], HiFltF99-HiFltF97
  2104. ;;
  2105. ldf.fill f98 = [rHpT1], HiFltF100-HiFltF98
  2106. ldf.fill f99 = [rHpT3], HiFltF101-HiFltF99
  2107. ;;
  2108. ldf.fill f100 = [rHpT1], HiFltF102-HiFltF100
  2109. ldf.fill f101 = [rHpT3], HiFltF103-HiFltF101
  2110. ;;
  2111. ldf.fill f102 = [rHpT1], HiFltF104-HiFltF102
  2112. ldf.fill f103 = [rHpT3], HiFltF105-HiFltF103
  2113. ;;
  2114. ldf.fill f104 = [rHpT1], HiFltF106-HiFltF104
  2115. ldf.fill f105 = [rHpT3], HiFltF107-HiFltF105
  2116. ;;
  2117. ldf.fill f106 = [rHpT1], HiFltF108-HiFltF106
  2118. ldf.fill f107 = [rHpT3], HiFltF109-HiFltF107
  2119. ;;
  2120. ldf.fill f108 = [rHpT1], HiFltF110-HiFltF108
  2121. ldf.fill f109 = [rHpT3], HiFltF111-HiFltF109
  2122. ;;
  2123. ldf.fill f110 = [rHpT1], HiFltF112-HiFltF110
  2124. ldf.fill f111 = [rHpT3], HiFltF113-HiFltF111
  2125. ;;
  2126. ldf.fill f112 = [rHpT1], HiFltF114-HiFltF112
  2127. ldf.fill f113 = [rHpT3], HiFltF115-HiFltF113
  2128. ;;
  2129. ldf.fill f114 = [rHpT1], HiFltF116-HiFltF114
  2130. ldf.fill f115 = [rHpT3], HiFltF117-HiFltF115
  2131. ;;
  2132. ldf.fill f116 = [rHpT1], HiFltF118-HiFltF116
  2133. ldf.fill f117 = [rHpT3], HiFltF119-HiFltF117
  2134. ;;
  2135. ldf.fill f118 = [rHpT1], HiFltF120-HiFltF118
  2136. ldf.fill f119 = [rHpT3], HiFltF121-HiFltF119
  2137. ;;
  2138. ldf.fill f120 = [rHpT1], HiFltF122-HiFltF120
  2139. ldf.fill f121 = [rHpT3], HiFltF123-HiFltF121
  2140. ;;
  2141. ldf.fill f122 = [rHpT1], HiFltF124-HiFltF122
  2142. ldf.fill f123 = [rHpT3], HiFltF125-HiFltF123
  2143. ;;
  2144. ldf.fill f124 = [rHpT1], HiFltF126-HiFltF124
  2145. ldf.fill f125 = [rHpT3], HiFltF127-HiFltF125
  2146. ;;
  2147. ldf.fill f126 = [rHpT1]
  2148. ldf.fill f127 = [rHpT3]
  2149. ;;
  2150. rsm 1 << PSR_MFH // clear psr.mfh bit
  2151. br.ret.sptk brp
  2152. ;;
  2153. LEAF_EXIT(BdRestoreHigherFPVolatile)
  2154. //++
  2155. //
  2156. // Routine Description:
  2157. //
  2158. // This routine begins the common code for raising an exception.
  2159. // The routine saves the non-volatile state and dispatches to the
  2160. // next level exception dispatcher.
  2161. //
  2162. // Arguments:
  2163. //
  2164. // a0 - pointer to trap frame
  2165. // a1 - previous mode
  2166. //
  2167. // Return Value:
  2168. //
  2169. // None.
  2170. //
  2171. //--
  2172. NESTED_ENTRY(BdExceptionDispatch)
  2173. //
  2174. // Build exception frame
  2175. //
  2176. .regstk 2, 3, 5, 0
  2177. .prologue 0xA, loc0
  2178. alloc t16 = ar.pfs, 2, 3, 5, 0
  2179. mov loc0 = sp
  2180. cmp4.eq pt0 = UserMode, a1 // previous mode is user?
  2181. mov loc1 = brp
  2182. add sp = -ExceptionFrameLength, sp
  2183. ;;
  2184. .save ar.unat, loc2
  2185. mov loc2 = ar.unat
  2186. add t0 = ExFltS19+STACK_SCRATCH_AREA, sp
  2187. add t1 = ExFltS18+STACK_SCRATCH_AREA, sp
  2188. ;;
  2189. .save.gf 0x0, 0xC0000
  2190. stf.spill [t0] = fs19, ExFltS17-ExFltS19
  2191. stf.spill [t1] = fs18, ExFltS16-ExFltS18
  2192. ;;
  2193. .save.gf 0x0, 0x30000
  2194. stf.spill [t0] = fs17, ExFltS15-ExFltS17
  2195. stf.spill [t1] = fs16, ExFltS14-ExFltS16
  2196. mov t10 = bs4
  2197. ;;
  2198. .save.gf 0x0, 0xC000
  2199. stf.spill [t0] = fs15, ExFltS13-ExFltS15
  2200. stf.spill [t1] = fs14, ExFltS12-ExFltS14
  2201. mov t11 = bs3
  2202. ;;
  2203. .save.gf 0x0, 0x3000
  2204. stf.spill [t0] = fs13, ExFltS11-ExFltS13
  2205. stf.spill [t1] = fs12, ExFltS10-ExFltS12
  2206. mov t12 = bs2
  2207. ;;
  2208. .save.gf 0x0, 0xC00
  2209. stf.spill [t0] = fs11, ExFltS9-ExFltS11
  2210. stf.spill [t1] = fs10, ExFltS8-ExFltS10
  2211. mov t13 = bs1
  2212. ;;
  2213. .save.gf 0x0, 0x300
  2214. stf.spill [t0] = fs9, ExFltS7-ExFltS9
  2215. stf.spill [t1] = fs8, ExFltS6-ExFltS8
  2216. mov t14 = bs0
  2217. ;;
  2218. .save.gf 0x0, 0xC0
  2219. stf.spill [t0] = fs7, ExFltS5-ExFltS7
  2220. stf.spill [t1] = fs6, ExFltS4-ExFltS6
  2221. mov t15 = ar.lc
  2222. ;;
  2223. .save.gf 0x0, 0x30
  2224. stf.spill [t0] = fs5, ExFltS3-ExFltS5
  2225. stf.spill [t1] = fs4, ExFltS2-ExFltS4
  2226. ;;
  2227. .save.f 0xC
  2228. stf.spill [t0] = fs3, ExFltS1-ExFltS3 // save fs3
  2229. stf.spill [t1] = fs2, ExFltS0-ExFltS2 // save fs2
  2230. ;;
  2231. .save.f 0x3
  2232. stf.spill [t0] = fs1, ExBrS4-ExFltS1 // save fs1
  2233. stf.spill [t1] = fs0, ExBrS3-ExFltS0 // save fs0
  2234. ;;
  2235. .save.b 0x18
  2236. st8 [t0] = t10, ExBrS2-ExBrS4 // save bs4
  2237. st8 [t1] = t11, ExBrS1-ExBrS3 // save bs3
  2238. ;;
  2239. .save.b 0x6
  2240. st8 [t0] = t12, ExBrS0-ExBrS2 // save bs2
  2241. st8 [t1] = t13, ExIntS2-ExBrS1 // save bs1
  2242. ;;
  2243. .save.b 0x1
  2244. st8 [t0] = t14, ExIntS3-ExBrS0 // save bs0
  2245. (pt0) add out0 = TrapFrameLength+TsHigherFPVolatile, a0
  2246. ;;
  2247. .save.gf 0xC, 0x0
  2248. .mem.offset 0,0
  2249. st8.spill [t0] = s3, ExIntS1-ExIntS3 // save s3
  2250. .mem.offset 8,0
  2251. st8.spill [t1] = s2, ExIntS0-ExIntS2 // save s2
  2252. ;;
  2253. .save.gf 0x3, 0x0
  2254. .mem.offset 0,0
  2255. st8.spill [t0] = s1, ExApLC-ExIntS1 // save s1
  2256. .mem.offset 8,0
  2257. st8.spill [t1] = s0, ExApEC-ExIntS0 // save s0
  2258. ;;
  2259. .savepsp ar.pfs, ExceptionFrameLength-ExApEC-STACK_SCRATCH_AREA
  2260. st8 [t1] = t16, ExIntNats-ExApEC
  2261. mov t4 = ar.unat // captured Nats of s0-s3
  2262. ;;
  2263. .savepsp ar.lc, ExceptionFrameLength-ExApLC-STACK_SCRATCH_AREA
  2264. st8 [t0] = t15
  2265. .savepsp @priunat, ExceptionFrameLength-ExIntNats-STACK_SCRATCH_AREA
  2266. st8 [t1] = t4 // save Nats of s0-s3
  2267. (pt0) br.call.sptk brp = BdSaveHigherFPVolatile
  2268. ;;
  2269. PROLOGUE_END
  2270. add out0 = TrExceptionRecord, a0 // -> exception record
  2271. add out1 = STACK_SCRATCH_AREA, sp // -> exception frame
  2272. mov out2 = a0 // -> trap frame
  2273. br.call.sptk.many brp = BdTrap
  2274. add t1 = ExApEC+STACK_SCRATCH_AREA, sp
  2275. movl t0 = BdExceptionExit
  2276. ;;
  2277. ld8 t1 = [t1]
  2278. mov brp = t0
  2279. ;;
  2280. mov ar.unat = loc2
  2281. mov ar.pfs = t1
  2282. add s1 = STACK_SCRATCH_AREA, sp // s1 -> exception frame
  2283. mov s0 = a0 // s0 -> trap frame
  2284. br.ret.sptk brp
  2285. ;;
  2286. ALTERNATE_ENTRY(BdExceptionExit)
  2287. //++
  2288. //
  2289. // Routine Description:
  2290. //
  2291. // This routine is called to exit from an exception.
  2292. //
  2293. // N.B. This transfer of control occurs from:
  2294. //
  2295. // 1. fall-through from above
  2296. // 2. exit from continue system service
  2297. // 3. exit from raise exception system service
  2298. // 4. exit into user mode from thread startup
  2299. //
  2300. // Arguments:
  2301. //
  2302. // loc0 - pointer to trap frame
  2303. // sp - pointer to high preserved float save area + STACK_SCRATCH_AREA
  2304. //
  2305. // Return Value:
  2306. //
  2307. // Does not return.
  2308. //
  2309. //--
  2310. //
  2311. // upon entry of this block, s0 and s1 must be set to the address of
  2312. // the trap and the exception frames respectively.
  2313. //
  2314. // preserved state is restored here because they may have been modified
  2315. // by SetContext
  2316. //
  2317. LEAF_SETUP(0, 1, 2, 0) // must be in sync with
  2318. // BdGenericExceptionHandler
  2319. mov loc0 = s0 // -> trap frame
  2320. mov out0 = s1 // -> exception frame
  2321. ;;
  2322. br.call.sptk brp = BdRestoreExceptionFrame
  2323. ;;
  2324. mov sp = loc0 // deallocate exception
  2325. // frame by restoring sp
  2326. ALTERNATE_ENTRY(BdAlternateExit)
  2327. //
  2328. // sp -> trap frame addres
  2329. //
  2330. // Interrupts disabled from here to rfi
  2331. //
  2332. FAST_DISABLE_INTERRUPTS
  2333. ;;
  2334. RETURN_FROM_INTERRUPTION(Ked)
  2335. NESTED_EXIT(BdExceptionDispatch)
  2336. NESTED_ENTRY(BdInstallVectors)
  2337. NESTED_SETUP (3,17,8,0)
  2338. IpValue:
  2339. mov loc4 = ip
  2340. movl loc5 = IpValue
  2341. ;;
  2342. sub loc6 = loc4, loc5 // relocation = runtime add - link addr
  2343. mov loc8 = cr.iva
  2344. ;;
  2345. //
  2346. // Set Break Instrution Vector
  2347. //
  2348. movl loc7 = 0x2C00
  2349. ;;
  2350. add out0 = loc7, loc8 // out0 = address of IVT vector
  2351. movl out1 = BdBreakVector // out2 = address of exception handler
  2352. // (static value) to be plugged into IVT
  2353. mov out2 = loc6 // adjustment to go from static to runtime
  2354. br.call.dpnt.few brp = BdUpdateIvt // Fill in the address of routine into IVT
  2355. //
  2356. // Set Taken Branch Vector
  2357. //
  2358. movl loc7 = 0x5F00
  2359. ;;
  2360. add out0 = loc7, loc8 // out0 = address of IVT vector
  2361. movl out1 = BdTakenBranchVector // out2 = address of exception handler
  2362. // (static value) to be plugged into IVT
  2363. mov out2 = loc6 // adjustment to go from static to runtime
  2364. br.call.dpnt.few brp = BdUpdateIvt // Fill in the address of routine into IVT
  2365. //
  2366. // Set Single Step Vector
  2367. //
  2368. movl loc7 = 0x6000
  2369. ;;
  2370. add out0 = loc7, loc8 // out0 = address of IVT vector
  2371. movl out1 = BdSingleStepVector // out2 = address of exception handler
  2372. // (static value) to be plugged into IVT
  2373. mov out2 = loc6 // adjustment to go from static to runtime
  2374. br.call.dpnt.few brp = BdUpdateIvt // Fill in the address of routine into IVT
  2375. NESTED_RETURN
  2376. NESTED_EXIT(BdInstallVectors) // Return to caller using B0
  2377. //-------------------------------------------------
  2378. //
  2379. // BdUpdateIvt : Routine to fill in an entry into the IVT.
  2380. // This is a leaf routine.
  2381. //
  2382. // in0 = address of IVT vector
  2383. // in1 = address of exception handler (static value) to be plugged into IVT
  2384. // in2 = adjustment to go from static to runtime
  2385. //
  2386. //-------------------------------------------------
  2387. NESTED_ENTRY(BdUpdateIvt)
  2388. NESTED_SETUP (8,16,4,0)
  2389. mov out0 = in0
  2390. movl out1 = BdIvtStart
  2391. movl out2 = BdIvtEnd - BdIvtStart
  2392. ;;
  2393. br.call.sptk brp = memcpy
  2394. ;;
  2395. mov out0 = in0
  2396. mov out1 = in1
  2397. ;;
  2398. br.call.sptk brp = BdSetMovlImmediate
  2399. NESTED_RETURN
  2400. NESTED_EXIT(BdUpdateIvt) // Return to caller using B0
  2401. BdIvtStart:
  2402. {
  2403. .mlx
  2404. nop.m 0
  2405. movl h31 = BdIvtStart
  2406. ;;
  2407. }
  2408. {
  2409. .mii
  2410. nop.m 0
  2411. nop.i 0
  2412. mov h30 = b7
  2413. ;;
  2414. }
  2415. {
  2416. .mii
  2417. nop.m 0
  2418. nop.i 0
  2419. mov b7 = h31
  2420. ;;
  2421. }
  2422. {
  2423. .mib
  2424. nop.m 0
  2425. nop.i 0
  2426. (p0) br.sptk.few b7
  2427. ;;
  2428. }
  2429. BdIvtEnd:
  2430. //
  2431. // All non-VECTOR_ENTRY functions must follow KiNormalSystemCall.
  2432. //
  2433. // N.B. KiNormalSystemCall must be the first function body in the .nsc
  2434. // section.
  2435. //
  2436. //--------------------------------------------------------------------
  2437. // Routine:
  2438. //
  2439. // KiNormalSystemCall
  2440. //
  2441. // Description:
  2442. //
  2443. // Handler for normal (not fast) system calls
  2444. //
  2445. // On entry:
  2446. //
  2447. // ic off
  2448. // interrupts disabled
  2449. // v0: contains sys call #
  2450. // cover done by call
  2451. // r32-r39: sys call arguments
  2452. // CFM: sof = # args, ins = 0, outs = # args
  2453. //
  2454. // Return value:
  2455. //
  2456. // v0: system call return value
  2457. //
  2458. // Process:
  2459. //
  2460. //--------------------------------------------------------------------
  2461. #if 0
  2462. .section .drectve, "MI", "progbits"
  2463. string " -section:.nsc,,align=0x4000"
  2464. .section .nsc = "ax", "progbits"
  2465. #endif
  2466. HANDLER_ENTRY_EX(KiNormalSystemCall, BdRestoreTrapFrame)
  2467. .prologue
  2468. .unwabi @nt, SYSCALL_FRAME
  2469. rThread = t1 // current thread
  2470. rIFS = t1
  2471. rIIP = t2
  2472. rPreds = t3
  2473. rIPSR = t4
  2474. rUNAT = t5
  2475. rSp = t6
  2476. rpT1 = t7
  2477. rpT2 = t8
  2478. rpT3 = t9
  2479. rpT4 = t10
  2480. rT0 = t11
  2481. rT1 = t12
  2482. rT2 = t13
  2483. rT3 = t14
  2484. rT4 = t15
  2485. rIntNats = t17
  2486. rpSd = t16 /* -> service descriptor entry */
  2487. rSdOffset = t17 /* service descriptor offset */
  2488. rArgTable = t18 /* pointer to argument table */
  2489. rArgNum = t20 /* number of arguments */
  2490. rArgBytes = t21
  2491. rpBSPStore = t16
  2492. rRscD = t16
  2493. rRNAT = t17
  2494. rRscE = t18
  2495. rKBSPStore = t18
  2496. rBSPStore = t19
  2497. rpBSP = t20
  2498. rRscDelta = t20
  2499. rBSP = t21
  2500. rPreviousMode = t22
  2501. pInvl = pt0 /* pInvl = not GUI service */
  2502. pVal = pt1
  2503. pGui = pt2 /* true if GUI call */
  2504. pNoGui = pt3 /* true if no GUI call */
  2505. pNatedArg = pt4 /* true if any input argument */
  2506. /* register is Nat'ed */
  2507. pNoCopy = pt5 /* no in-memory arguments to copy */
  2508. pCopy = pt6
  2509. mov rUNAT = ar.unat
  2510. tnat.nz pt0 = sp
  2511. mov rPreviousMode = KernelMode
  2512. mov rIPSR = psr
  2513. rsm 1 << PSR_I | 1 << PSR_MFH
  2514. br.sptk BdRestoreTrapFrame
  2515. HANDLER_EXIT(KiNormalSystemCall)