mca_asm.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:20k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. //
  2. // assembly portion of the IA64 MCA handling
  3. //
  4. // Mods by cfleck to integrate into kernel build
  5. // 00/03/15 davidm Added various stop bits to get a clean compile
  6. //
  7. // 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp
  8. //    kstack, switch modes, jump to C INIT handler
  9. //
  10. #include <linux/config.h>
  11. #include <asm/asmmacro.h>
  12. #include <asm/pgtable.h>
  13. #include <asm/processor.h>
  14. #include <asm/mca_asm.h>
  15. #include <asm/mca.h>
  16. /*
  17.  * When we get an machine check, the kernel stack pointer is no longer
  18.  * valid, so we need to set a new stack pointer.
  19.  */
  20. #define MINSTATE_PHYS /* Make sure stack access is physical for MINSTATE */
  21. #include "minstate.h"
  22. /*
  23.  *  SAL_TO_OS_MCA_HANDOFF_STATE (SAL 3.0 spec)
  24.  * 1. GR1 = OS GP
  25.  * 2. GR8 = PAL_PROC physical address
  26.  * 3. GR9 = SAL_PROC physical address
  27.  * 4. GR10 = SAL GP (physical)
  28.  * 5. GR11 = Rendez state
  29.  * 6. GR12 = Return address to location within SAL_CHECK
  30.  */
  31. #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)
  32. movl _tmp=ia64_sal_to_os_handoff_state;;
  33. DATA_VA_TO_PA(_tmp);;
  34. st8 [_tmp]=r1,0x08;;
  35. st8 [_tmp]=r8,0x08;;
  36. st8 [_tmp]=r9,0x08;;
  37. st8 [_tmp]=r10,0x08;;
  38. st8 [_tmp]=r11,0x08;;
  39. st8 [_tmp]=r12,0x08;;
  40. /*
  41.  *  OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
  42.  *      1. GR8 = OS_MCA return status
  43.  * 2. GR9 = SAL GP (physical)
  44.  *      3. GR10 = 0/1 returning same/new context
  45.  *      4. GR22 = New min state save area pointer
  46.  *      returns ptr to SAL rtn save loc in _tmp
  47.  */
  48. #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)
  49. movl _tmp=ia64_os_to_sal_handoff_state;;
  50. DATA_VA_TO_PA(_tmp);;
  51. ld8 r8=[_tmp],0x08;;
  52. ld8 r9=[_tmp],0x08;;
  53. ld8     r10=[_tmp],0x08;;
  54. ld8     r22=[_tmp],0x08;;
  55. movl    _tmp=ia64_sal_to_os_handoff_state;;
  56. DATA_VA_TO_PA(_tmp);;
  57. add     _tmp=0x28,_tmp;;            // point to SAL rtn save location
  58. .global ia64_os_mca_dispatch
  59. .global ia64_os_mca_dispatch_end
  60. .global ia64_sal_to_os_handoff_state
  61. .global ia64_os_to_sal_handoff_state
  62. .global ia64_mca_proc_state_dump
  63. .global ia64_mca_stack
  64. .global ia64_mca_stackframe
  65. .global ia64_mca_bspstore
  66. .global ia64_init_stack
  67. .text
  68. .align 16
  69. ia64_os_mca_dispatch:
  70. #if defined(MCA_TEST)
  71. // Pretend that we are in interrupt context
  72. mov r2=psr
  73. dep r2=0, r2, PSR_IC, 2;
  74. mov psr.l = r2
  75. #endif /* #if defined(MCA_TEST) */
  76. // Save the SAL to OS MCA handoff state as defined
  77. // by SAL SPEC 3.0
  78. // NOTE : The order in which the state gets saved
  79. //   is dependent on the way the C-structure
  80. //   for ia64_mca_sal_to_os_state_t has been
  81. //   defined in include/asm/mca.h
  82. SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
  83. // LOG PROCESSOR STATE INFO FROM HERE ON..
  84. ;;
  85. begin_os_mca_dump:
  86. br ia64_os_mca_proc_state_dump;;
  87. ia64_os_mca_done_dump:
  88. // Setup new stack frame for OS_MCA handling
  89. movl    r2=ia64_mca_bspstore;;      // local bspstore area location in r2
  90. DATA_VA_TO_PA(r2);;
  91. movl    r3=ia64_mca_stackframe;;    // save stack frame to memory in r3
  92. DATA_VA_TO_PA(r3);;
  93. rse_switch_context(r6,r3,r2);;                  // RSC management in this new context
  94. movl        r12=ia64_mca_stack;;
  95. mov     r2=8*1024;;                 // stack size must be same as c array
  96. add     r12=r2,r12;;                // stack base @ bottom of array
  97. DATA_VA_TO_PA(r12);;
  98. // Enter virtual mode from physical mode
  99. VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
  100. ia64_os_mca_virtual_begin:
  101. // call our handler
  102. movl r2=ia64_mca_ucmc_handler;;
  103. mov b6=r2;;
  104. br.call.sptk.many    b0=b6;;
  105. .ret0:
  106. // Revert back to physical mode before going back to SAL
  107. PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
  108. ia64_os_mca_virtual_end:
  109. #if defined(MCA_TEST)
  110. // Pretend that we are in interrupt context
  111. mov r2=psr;;
  112. dep r2=0, r2, PSR_IC, 2;;
  113. mov psr.l = r2;;
  114. #endif /* #if defined(MCA_TEST) */
  115. // restore the original stack frame here
  116. movl    r2=ia64_mca_stackframe               // restore stack frame from memory at r2
  117. ;;
  118. DATA_VA_TO_PA(r2)
  119. movl    r4=IA64_PSR_MC
  120. ;;
  121. rse_return_context(r4,r3,r2)                 // switch from interrupt context for RSE
  122. // let us restore all the registers from our PSI structure
  123. mov r8=gp
  124. ;;
  125. begin_os_mca_restore:
  126. br ia64_os_mca_proc_state_restore;;
  127. ia64_os_mca_done_restore:
  128. ;;
  129. // branch back to SALE_CHECK
  130. OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2)
  131. ld8 r3=[r2];;
  132. mov b0=r3;;       // SAL_CHECK return address
  133. br b0
  134. ;;
  135. ia64_os_mca_dispatch_end:
  136. //EndMain//////////////////////////////////////////////////////////////////////
  137. //++
  138. // Name:
  139. //      ia64_os_mca_proc_state_dump()
  140. //
  141. // Stub Description:
  142. //
  143. //       This stub dumps the processor state during MCHK to a data area
  144. //
  145. //--
  146. ia64_os_mca_proc_state_dump:
  147. // Save bank 1 GRs 16-31 which will be used by c-language code when we switch
  148. //  to virtual addressing mode.
  149. movl r2=ia64_mca_proc_state_dump;;           // Os state dump area
  150.         DATA_VA_TO_PA(r2)                   // convert to to physical address
  151. // save ar.NaT
  152. mov r5=ar.unat                  // ar.unat
  153. // save banked GRs 16-31 along with NaT bits
  154. bsw.1;;
  155. st8.spill [r2]=r16,8;;
  156. st8.spill [r2]=r17,8;;
  157. st8.spill [r2]=r18,8;;
  158. st8.spill [r2]=r19,8;;
  159. st8.spill [r2]=r20,8;;
  160. st8.spill [r2]=r21,8;;
  161. st8.spill [r2]=r22,8;;
  162. st8.spill [r2]=r23,8;;
  163. st8.spill [r2]=r24,8;;
  164. st8.spill [r2]=r25,8;;
  165. st8.spill [r2]=r26,8;;
  166. st8.spill [r2]=r27,8;;
  167. st8.spill [r2]=r28,8;;
  168. st8.spill [r2]=r29,8;;
  169. st8.spill [r2]=r30,8;;
  170. st8.spill [r2]=r31,8;;
  171. mov r4=ar.unat;;
  172. st8 [r2]=r4,8                // save User NaT bits for r16-r31
  173. mov ar.unat=r5                  // restore original unat
  174. bsw.0;;
  175. //save BRs
  176. add r4=8,r2                  // duplicate r2 in r4
  177. add r6=2*8,r2                // duplicate r2 in r4
  178. mov r3=b0
  179. mov r5=b1
  180. mov r7=b2;;
  181. st8 [r2]=r3,3*8
  182. st8 [r4]=r5,3*8
  183. st8 [r6]=r7,3*8;;
  184. mov r3=b3
  185. mov r5=b4
  186. mov r7=b5;;
  187. st8 [r2]=r3,3*8
  188. st8 [r4]=r5,3*8
  189. st8 [r6]=r7,3*8;;
  190. mov r3=b6
  191. mov r5=b7;;
  192. st8 [r2]=r3,2*8
  193. st8 [r4]=r5,2*8;;
  194. cSaveCRs:
  195. // save CRs
  196. add r4=8,r2                  // duplicate r2 in r4
  197. add r6=2*8,r2                // duplicate r2 in r4
  198. mov r3=cr0                      // cr.dcr
  199. mov r5=cr1                      // cr.itm
  200. mov r7=cr2;;                    // cr.iva
  201. st8 [r2]=r3,8*8
  202. st8 [r4]=r5,3*8
  203. st8 [r6]=r7,3*8;;            // 48 byte rements
  204. mov r3=cr8;;                    // cr.pta
  205. st8 [r2]=r3,8*8;;            // 64 byte rements
  206. // if PSR.ic=0, reading interruption registers causes an illegal operation fault
  207. mov r3=psr;;
  208. tbit.nz.unc p6,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
  209. (p6)    st8     [r2]=r0,9*8+160             // increment by 232 byte inc.
  210. begin_skip_intr_regs:
  211. (p6) br SkipIntrRegs;;
  212. add r4=8,r2                  // duplicate r2 in r4
  213. add r6=2*8,r2                // duplicate r2 in r6
  214. mov r3=cr16                     // cr.ipsr
  215. mov r5=cr17                     // cr.isr
  216.         mov     r7=r0;;                     // cr.ida => cr18 (reserved)
  217. st8 [r2]=r3,3*8
  218. st8 [r4]=r5,3*8
  219. st8 [r6]=r7,3*8;;
  220. mov r3=cr19                     // cr.iip
  221. mov r5=cr20                     // cr.idtr
  222. mov r7=cr21;;                   // cr.iitr
  223. st8 [r2]=r3,3*8
  224. st8 [r4]=r5,3*8
  225. st8 [r6]=r7,3*8;;
  226. mov r3=cr22                     // cr.iipa
  227. mov r5=cr23                     // cr.ifs
  228. mov r7=cr24;;                   // cr.iim
  229. st8 [r2]=r3,3*8
  230. st8 [r4]=r5,3*8
  231. st8 [r6]=r7,3*8;;
  232. mov r3=cr25;;                   // cr.iha
  233. st8 [r2]=r3,160;;               // 160 byte rement
  234. SkipIntrRegs:
  235. st8 [r2]=r0,168                 // another 168 byte .
  236. mov r3=cr66;;                   // cr.lid
  237. st8 [r2]=r3,40                  // 40 byte rement
  238. mov r3=cr71;;                   // cr.ivr
  239. st8 [r2]=r3,8
  240. mov r3=cr72;;                   // cr.tpr
  241. st8 [r2]=r3,24                  // 24 byte increment
  242. mov r3=r0;;                     // cr.eoi => cr75
  243. st8 [r2]=r3,168                 // 168 byte inc.
  244. mov r3=r0;;                     // cr.irr0 => cr96
  245. st8 [r2]=r3,16               // 16 byte inc.
  246. mov r3=r0;;                     // cr.irr1 => cr98
  247. st8 [r2]=r3,16               // 16 byte inc.
  248. mov r3=r0;;                     // cr.irr2 => cr100
  249. st8 [r2]=r3,16               // 16 byte inc
  250. mov r3=r0;;                     // cr.irr3 => cr100
  251. st8 [r2]=r3,16               // 16b inc.
  252. mov r3=r0;;                     // cr.itv => cr114
  253. st8 [r2]=r3,16               // 16 byte inc.
  254. mov r3=r0;;                     // cr.pmv => cr116
  255. st8 [r2]=r3,8
  256. mov r3=r0;;                     // cr.lrr0 => cr117
  257. st8 [r2]=r3,8
  258. mov r3=r0;;                     // cr.lrr1 => cr118
  259. st8 [r2]=r3,8
  260. mov r3=r0;;                     // cr.cmcv => cr119
  261. st8 [r2]=r3,8*10;;
  262. cSaveARs:
  263. // save ARs
  264. add r4=8,r2                  // duplicate r2 in r4
  265. add r6=2*8,r2                // duplicate r2 in r6
  266. mov r3=ar0                      // ar.kro
  267. mov r5=ar1                      // ar.kr1
  268. mov r7=ar2;;                    // ar.kr2
  269. st8 [r2]=r3,3*8
  270. st8 [r4]=r5,3*8
  271. st8 [r6]=r7,3*8;;
  272. mov r3=ar3                      // ar.kr3
  273. mov r5=ar4                      // ar.kr4
  274. mov r7=ar5;;                    // ar.kr5
  275. st8 [r2]=r3,3*8
  276. st8 [r4]=r5,3*8
  277. st8 [r6]=r7,3*8;;
  278. mov r3=ar6                      // ar.kr6
  279. mov r5=ar7                      // ar.kr7
  280. mov r7=r0;;                     // ar.kr8
  281. st8 [r2]=r3,10*8
  282. st8 [r4]=r5,10*8
  283. st8 [r6]=r7,10*8;;           // rement by 72 bytes
  284. mov r3=ar16                     // ar.rsc
  285. mov ar16=r0     // put RSE in enforced lazy mode
  286. mov r5=ar17                     // ar.bsp
  287. ;;
  288. mov r7=ar18;;                   // ar.bspstore
  289. st8 [r2]=r3,3*8
  290. st8 [r4]=r5,3*8
  291. st8 [r6]=r7,3*8;;
  292. mov r3=ar19;;                   // ar.rnat
  293. st8 [r2]=r3,8*13             // increment by 13x8 bytes
  294. mov r3=ar32;;                   // ar.ccv
  295. st8 [r2]=r3,8*4
  296. mov r3=ar36;;                   // ar.unat
  297. st8 [r2]=r3,8*4
  298. mov r3=ar40;;                   // ar.fpsr
  299. st8 [r2]=r3,8*4
  300. mov r3=ar44;;                   // ar.itc
  301. st8 [r2]=r3,160                 // 160
  302. mov r3=ar64;;                   // ar.pfs
  303. st8 [r2]=r3,8
  304. mov r3=ar65;;                   // ar.lc
  305. st8 [r2]=r3,8
  306. mov r3=ar66;;                   // ar.ec
  307. st8 [r2]=r3
  308. add r2=8*62,r2               //padding
  309. // save RRs
  310. mov ar.lc=0x08-1
  311. movl r4=0x00;;
  312. cStRR:
  313. mov r3=rr[r4];;
  314. st8 [r2]=r3,8
  315. add r4=1,r4
  316. br.cloop.sptk.few cStRR
  317. ;;
  318. end_os_mca_dump:
  319. br ia64_os_mca_done_dump;;
  320. //EndStub//////////////////////////////////////////////////////////////////////
  321. //++
  322. // Name:
  323. //       ia64_os_mca_proc_state_restore()
  324. //
  325. // Stub Description:
  326. //
  327. //       This is a stub to restore the saved processor state during MCHK
  328. //
  329. //--
  330. ia64_os_mca_proc_state_restore:
  331. // Restore bank1 GR16-31
  332. movl r2=ia64_mca_proc_state_dump // Convert virtual address
  333. ;; // of OS state dump area
  334. DATA_VA_TO_PA(r2) // to physical address
  335. ;;
  336. restore_GRs:                                    // restore bank-1 GRs 16-31
  337. bsw.1;;
  338. add r3=16*8,r2;;                // to get to NaT of GR 16-31
  339. ld8 r3=[r3];;
  340. mov ar.unat=r3;;                // first restore NaT
  341. ld8.fill r16=[r2],8;;
  342. ld8.fill r17=[r2],8;;
  343. ld8.fill r18=[r2],8;;
  344. ld8.fill r19=[r2],8;;
  345. ld8.fill r20=[r2],8;;
  346. ld8.fill r21=[r2],8;;
  347. ld8.fill r22=[r2],8;;
  348. ld8.fill r23=[r2],8;;
  349. ld8.fill r24=[r2],8;;
  350. ld8.fill r25=[r2],8;;
  351. ld8.fill r26=[r2],8;;
  352. ld8.fill r27=[r2],8;;
  353. ld8.fill r28=[r2],8;;
  354. ld8.fill r29=[r2],8;;
  355. ld8.fill r30=[r2],8;;
  356. ld8.fill r31=[r2],8;;
  357. ld8 r3=[r2],8;;              // increment to skip NaT
  358. bsw.0;;
  359. restore_BRs:
  360. add r4=8,r2                  // duplicate r2 in r4
  361. add r6=2*8,r2;;              // duplicate r2 in r4
  362. ld8 r3=[r2],3*8
  363. ld8 r5=[r4],3*8
  364. ld8 r7=[r6],3*8;;
  365. mov b0=r3
  366. mov b1=r5
  367. mov b2=r7;;
  368. ld8 r3=[r2],3*8
  369. ld8 r5=[r4],3*8
  370. ld8 r7=[r6],3*8;;
  371. mov b3=r3
  372. mov b4=r5
  373. mov b5=r7;;
  374. ld8 r3=[r2],2*8
  375. ld8 r5=[r4],2*8;;
  376. mov b6=r3
  377. mov b7=r5;;
  378. restore_CRs:
  379. add r4=8,r2                  // duplicate r2 in r4
  380. add r6=2*8,r2;;              // duplicate r2 in r4
  381. ld8 r3=[r2],8*8
  382. ld8 r5=[r4],3*8
  383. ld8 r7=[r6],3*8;;            // 48 byte increments
  384. mov cr0=r3                      // cr.dcr
  385. mov cr1=r5                      // cr.itm
  386. mov cr2=r7;;                    // cr.iva
  387. ld8 r3=[r2],8*8;;            // 64 byte increments
  388. //      mov cr8=r3                      // cr.pta
  389. // if PSR.ic=1, reading interruption registers causes an illegal operation fault
  390. mov r3=psr;;
  391. tbit.nz.unc p6,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
  392. (p6)    st8     [r2]=r0,9*8+160             // increment by 232 byte inc.
  393. begin_rskip_intr_regs:
  394. (p6) br rSkipIntrRegs;;
  395. add r4=8,r2                  // duplicate r2 in r4
  396. add r6=2*8,r2;;              // duplicate r2 in r4
  397. ld8 r3=[r2],3*8
  398. ld8 r5=[r4],3*8
  399. ld8 r7=[r6],3*8;;
  400. mov cr16=r3                     // cr.ipsr
  401. mov cr17=r5                     // cr.isr is read only
  402. //      mov     cr18=r7;;                   // cr.ida (reserved - don't restore)
  403. ld8 r3=[r2],3*8
  404. ld8 r5=[r4],3*8
  405. ld8 r7=[r6],3*8;;
  406. mov cr19=r3                     // cr.iip
  407. mov cr20=r5                     // cr.idtr
  408. mov cr21=r7;;                   // cr.iitr
  409. ld8 r3=[r2],3*8
  410. ld8 r5=[r4],3*8
  411. ld8 r7=[r6],3*8;;
  412. mov cr22=r3                     // cr.iipa
  413. mov cr23=r5                     // cr.ifs
  414. mov cr24=r7                     // cr.iim
  415. ld8 r3=[r2],160;;               // 160 byte increment
  416. mov cr25=r3                     // cr.iha
  417. rSkipIntrRegs:
  418. ld8 r3=[r2],168;;               // another 168 byte inc.
  419. ld8 r3=[r2],40;;                // 40 byte increment
  420. mov cr66=r3                     // cr.lid
  421. ld8 r3=[r2],8;;
  422. //      mov cr71=r3                     // cr.ivr is read only
  423. ld8 r3=[r2],24;;                // 24 byte increment
  424. mov cr72=r3                     // cr.tpr
  425. ld8 r3=[r2],168;;               // 168 byte inc.
  426. //      mov cr75=r3                     // cr.eoi
  427. ld8 r3=[r2],16;;             // 16 byte inc.
  428. //      mov cr96=r3                     // cr.irr0 is read only
  429. ld8 r3=[r2],16;;             // 16 byte inc.
  430. //      mov cr98=r3                     // cr.irr1 is read only
  431. ld8 r3=[r2],16;;             // 16 byte inc
  432. //      mov cr100=r3                    // cr.irr2 is read only
  433. ld8 r3=[r2],16;;             // 16b inc.
  434. //      mov cr102=r3                    // cr.irr3 is read only
  435. ld8 r3=[r2],16;;             // 16 byte inc.
  436. //      mov cr114=r3                    // cr.itv
  437. ld8 r3=[r2],8;;
  438. //      mov cr116=r3                    // cr.pmv
  439. ld8 r3=[r2],8;;
  440. //      mov cr117=r3                    // cr.lrr0
  441. ld8 r3=[r2],8;;
  442. //      mov cr118=r3                    // cr.lrr1
  443. ld8 r3=[r2],8*10;;
  444. //      mov cr119=r3                    // cr.cmcv
  445. restore_ARs:
  446. add r4=8,r2                  // duplicate r2 in r4
  447. add r6=2*8,r2;;              // duplicate r2 in r4
  448. ld8 r3=[r2],3*8
  449. ld8 r5=[r4],3*8
  450. ld8 r7=[r6],3*8;;
  451. mov ar0=r3                      // ar.kro
  452. mov ar1=r5                      // ar.kr1
  453. mov ar2=r7;;                    // ar.kr2
  454. ld8 r3=[r2],3*8
  455. ld8 r5=[r4],3*8
  456. ld8 r7=[r6],3*8;;
  457. mov ar3=r3                      // ar.kr3
  458. mov ar4=r5                      // ar.kr4
  459. mov ar5=r7;;                    // ar.kr5
  460. ld8 r3=[r2],10*8
  461. ld8 r5=[r4],10*8
  462. ld8 r7=[r6],10*8;;
  463. mov ar6=r3                      // ar.kr6
  464. mov ar7=r5                      // ar.kr7
  465. //      mov ar8=r6                      // ar.kr8
  466. ;;
  467. ld8 r3=[r2],3*8
  468. ld8 r5=[r4],3*8
  469. ld8 r7=[r6],3*8;;
  470. //      mov ar16=r3                     // ar.rsc
  471. //      mov ar17=r5                     // ar.bsp is read only
  472. mov ar16=r0     // make sure that RSE is in enforced lazy mode
  473. ;;
  474. mov ar18=r7;;                   // ar.bspstore
  475. ld8 r9=[r2],8*13;;
  476. mov ar19=r9                     // ar.rnat
  477. mov ar16=r3     // ar.rsc
  478. ld8 r3=[r2],8*4;;
  479. mov ar32=r3                     // ar.ccv
  480. ld8 r3=[r2],8*4;;
  481. mov ar36=r3                     // ar.unat
  482. ld8 r3=[r2],8*4;;
  483. mov ar40=r3                     // ar.fpsr
  484. ld8 r3=[r2],160;;               // 160
  485. //      mov ar44=r3                     // ar.itc
  486. ld8 r3=[r2],8;;
  487. mov ar64=r3                     // ar.pfs
  488. ld8 r3=[r2],8;;
  489. mov ar65=r3                     // ar.lc
  490. ld8 r3=[r2];;
  491. mov ar66=r3                     // ar.ec
  492. add r2=8*62,r2;;             // padding
  493. restore_RRs:
  494. mov r5=ar.lc
  495. mov ar.lc=0x08-1
  496. movl r4=0x00
  497. cStRRr:
  498. ld8 r3=[r2],8;;
  499. //      mov rr[r4]=r3                   // what are its access previledges?
  500. add r4=1,r4
  501. br.cloop.sptk.few cStRRr
  502. ;;
  503. mov ar.lc=r5
  504. ;;
  505. end_os_mca_restore:
  506. br ia64_os_mca_done_restore;;
  507. //EndStub//////////////////////////////////////////////////////////////////////
  508. // ok, the issue here is that we need to save state information so
  509. // it can be useable by the kernel debugger and show regs routines.
  510. // In order to do this, our best bet is save the current state (plus
  511. // the state information obtain from the MIN_STATE_AREA) into a pt_regs
  512. // format.  This way we can pass it on in a useable format.
  513. //
  514. //
  515. // SAL to OS entry point for INIT on the monarch processor
  516. // This has been defined for registration purposes with SAL
  517. // as a part of ia64_mca_init.
  518. //
  519. // When we get here, the follow registers have been
  520. // set by the SAL for our use
  521. //
  522. // 1. GR1 = OS INIT GP
  523. // 2. GR8 = PAL_PROC physical address
  524. // 3. GR9 = SAL_PROC physical address
  525. // 4. GR10 = SAL GP (physical)
  526. // 5. GR11 = Init Reason
  527. // 0 = Received INIT for event other than crash dump switch
  528. // 1 = Received wakeup at the end of an OS_MCA corrected machine check
  529. // 2 = Received INIT dude to CrashDump switch assertion
  530. //
  531. // 6. GR12 = Return address to location within SAL_INIT procedure
  532. GLOBAL_ENTRY(ia64_monarch_init_handler)
  533. #if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND)
  534. //
  535. // work around SAL bug that sends all processors to monarch entry
  536. //
  537. mov r17=cr.lid
  538. // XXX fix me: this is wrong: hard_smp_processor_id() is a pair of lid/eid
  539. movl r18=ia64_cpu_to_sapicid
  540. ;;
  541. dep r18=0,r18,61,3 // convert to physical address
  542. ;;
  543. shr.u r17=r17,16
  544. ld4 r18=[r18] // get the BSP ID
  545. ;;
  546. dep r17=0,r17,16,48
  547. ;;
  548. cmp4.ne p6,p0=r17,r18 // Am I the BSP ?
  549. (p6) br.cond.spnt slave_init_spin_me
  550. ;;
  551. #endif
  552. //
  553. // ok, the first thing we do is stash the information
  554. // the SAL passed to os
  555. //
  556. _tmp = r2
  557. movl _tmp=ia64_sal_to_os_handoff_state
  558. ;;
  559. dep _tmp=0,_tmp, 61, 3 // get physical address
  560. ;;
  561. st8 [_tmp]=r1,0x08;;
  562. st8 [_tmp]=r8,0x08;;
  563. st8 [_tmp]=r9,0x08;;
  564. st8 [_tmp]=r10,0x08;;
  565. st8 [_tmp]=r11,0x08;;
  566. st8 [_tmp]=r12,0x08;;
  567. // now we want to save information so we can dump registers
  568. SAVE_MIN_WITH_COVER
  569. ;;
  570. mov r8=cr.ifa
  571. mov r9=cr.isr
  572. adds r3=8,r2 // set up second base pointer
  573. ;;
  574. SAVE_REST
  575. // ok, enough should be saved at this point to be dangerous, and  supply
  576. // information for a dump
  577. // We need to switch to Virtual mode before hitting the C functions.
  578. //
  579. //
  580. //
  581. movl r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
  582. mov r3=psr // get the current psr, minimum enabled at this point
  583. ;;
  584. or r2=r2,r3
  585. ;;
  586. movl r3=IVirtual_Switch
  587. ;;
  588. mov cr.iip=r3 // short return to set the appropriate bits
  589. mov cr.ipsr=r2 // need to do an rfi to set appropriate bits
  590. ;;
  591. rfi
  592. ;;
  593. IVirtual_Switch:
  594. //
  595. // We should now be running virtual
  596. //
  597. // Lets call the C handler to get the rest of the state info
  598. //
  599. alloc r14=ar.pfs,0,0,1,0 // now it's safe (must be first in insn group!)
  600. ;; //
  601. adds out0=16,sp // out0 = pointer to pt_regs
  602. ;;
  603. br.call.sptk.many rp=ia64_init_handler
  604. .ret1:
  605. return_from_init:
  606. br.sptk return_from_init
  607. END(ia64_monarch_init_handler)
  608. //
  609. // SAL to OS entry point for INIT on the slave processor
  610. // This has been defined for registration purposes with SAL
  611. // as a part of ia64_mca_init.
  612. //
  613. GLOBAL_ENTRY(ia64_slave_init_handler)
  614. 1: br.sptk 1b
  615. END(ia64_slave_init_handler)