📄 mca_asm.s
字号:
mov r3=ar66;; // ar.ec st8 [r2]=r3 add r2=8*62,r2 //padding // save RRs mov ar.lc=0x08-1 movl r4=0x00;;cStRR: mov r3=rr[r4];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR ;;end_os_mca_dump: BRANCH(ia64_os_mca_done_dump, r2, p0, -0x10) ;;//EndStub////////////////////////////////////////////////////////////////////////++// Name:// ia64_os_mca_proc_state_restore()// // Stub Description://// This is a stub to restore the saved processor state during MCHK////--ia64_os_mca_proc_state_restore:// Restore bank1 GR16-31 movl r2=ia64_mca_proc_state_dump // Convert virtual address ;; // of OS state dump area DATA_VA_TO_PA(r2) // to physical address ;;restore_GRs: // restore bank-1 GRs 16-31 bsw.1;; add r3=16*8,r2;; // to get to NaT of GR 16-31 ld8 r3=[r3];; mov ar.unat=r3;; // first restore NaT ld8.fill r16=[r2],8;; ld8.fill r17=[r2],8;; ld8.fill r18=[r2],8;; ld8.fill r19=[r2],8;; ld8.fill r20=[r2],8;; ld8.fill r21=[r2],8;; ld8.fill r22=[r2],8;; ld8.fill r23=[r2],8;; ld8.fill r24=[r2],8;; ld8.fill r25=[r2],8;; ld8.fill r26=[r2],8;; ld8.fill r27=[r2],8;; ld8.fill r28=[r2],8;; ld8.fill r29=[r2],8;; ld8.fill r30=[r2],8;; ld8.fill r31=[r2],8;; ld8 r3=[r2],8;; // increment to skip NaT bsw.0;;restore_BRs: add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2;; // duplicate r2 in r4 ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov b0=r3 mov b1=r5 mov b2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov b3=r3 mov b4=r5 mov b5=r7;; ld8 r3=[r2],2*8 ld8 r5=[r4],2*8;; mov b6=r3 mov b7=r5;;restore_CRs: add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2;; // duplicate r2 in r4 ld8 r3=[r2],8*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; // 48 byte increments mov cr0=r3 // cr.dcr mov cr1=r5 // cr.itm mov cr2=r7;; // cr.iva ld8 r3=[r2],8*8;; // 64 byte increments// mov cr8=r3 // cr.pta// if PSR.ic=1, reading interruption registers causes an illegal operation fault mov r3=psr;; tbit.nz.unc p2,p0=r3,PSR_IC;; // PSI Valid Log bit pos. test(p2) st8 [r2]=r0,9*8+160 // increment by 160 byte inc.begin_rskip_intr_regs: BRANCH(rSkipIntrRegs, r9, p2, 0x0) ;; add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2;; // duplicate r2 in r4 ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov cr16=r3 // cr.ipsr mov cr17=r5 // cr.isr is read only// mov cr18=r7;; // cr.ida ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov cr19=r3 // cr.iip mov cr20=r5 // cr.idtr mov cr21=r7;; // cr.iitr ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov cr22=r3 // cr.iipa mov cr23=r5 // cr.ifs mov cr24=r7 // cr.iim ld8 r3=[r2],160;; // 160 byte increment mov cr25=r3 // cr.iha rSkipIntrRegs: ld8 r3=[r2],168;; // another 168 byte inc. ld8 r3=[r2],40;; // 40 byte increment mov cr66=r3 // cr.lid ld8 r3=[r2],8;;// mov cr71=r3 // cr.ivr is read only ld8 r3=[r2],24;; // 24 byte increment mov cr72=r3 // cr.tpr ld8 r3=[r2],168;; // 168 byte inc.// mov cr75=r3 // cr.eoi ld8 r3=[r2],16;; // 16 byte inc.// mov cr96=r3 // cr.irr0 is read only ld8 r3=[r2],16;; // 16 byte inc.// mov cr98=r3 // cr.irr1 is read only ld8 r3=[r2],16;; // 16 byte inc// mov cr100=r3 // cr.irr2 is read only ld8 r3=[r2],16;; // 16b inc.// mov cr102=r3 // cr.irr3 is read only ld8 r3=[r2],16;; // 16 byte inc.// mov cr114=r3 // cr.itv ld8 r3=[r2],8;;// mov cr116=r3 // cr.pmv ld8 r3=[r2],8;;// mov cr117=r3 // cr.lrr0 ld8 r3=[r2],8;;// mov cr118=r3 // cr.lrr1 ld8 r3=[r2],8*10;;// mov cr119=r3 // cr.cmcvrestore_ARs: add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2;; // duplicate r2 in r4 ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov ar0=r3 // ar.kro mov ar1=r5 // ar.kr1 mov ar2=r7;; // ar.kr2 ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov ar3=r3 // ar.kr3 mov ar4=r5 // ar.kr4 mov ar5=r7;; // ar.kr5 ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; mov ar6=r3 // ar.kr6 mov ar7=r5 // ar.kr7// mov ar8=r6 // ar.kr8 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;;// mov ar16=r3 // ar.rsc// mov ar17=r5 // ar.bsp is read only mov ar16=r0 // make sure that RSE is in enforced lazy mode ;; mov ar18=r7;; // ar.bspstore ld8 r9=[r2],8*13;; mov ar19=r9 // ar.rnat mov ar16=r3 // ar.rsc ld8 r3=[r2],8*4;; mov ar32=r3 // ar.ccv ld8 r3=[r2],8*4;; mov ar36=r3 // ar.unat ld8 r3=[r2],8*4;; mov ar40=r3 // ar.fpsr ld8 r3=[r2],160;; // 160// mov ar44=r3 // ar.itc ld8 r3=[r2],8;; mov ar64=r3 // ar.pfs ld8 r3=[r2],8;; mov ar65=r3 // ar.lc ld8 r3=[r2];; mov ar66=r3 // ar.ec add r2=8*62,r2;; // padding restore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 movl r4=0x00cStRRr: ld8 r3=[r2],8;;// mov rr[r4]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; mov ar.lc=r5 ;;end_os_mca_restore: BRANCH(ia64_os_mca_done_restore, r2, p0, -0x20) ;; //EndStub//////////////////////////////////////////////////////////////////////// ok, the issue here is that we need to save state information so// it can be useable by the kernel debugger and show regs routines.// In order to do this, our best bet is save the current state (plus// the state information obtain from the MIN_STATE_AREA) into a pt_regs// format. This way we can pass it on in a useable format.// //// SAL to OS entry point for INIT on the monarch processor// This has been defined for registration purposes with SAL // as a part of ia64_mca_init.//// When we get here, the follow registers have been// set by the SAL for our use// // 1. GR1 = OS INIT GP// 2. GR8 = PAL_PROC physical address// 3. GR9 = SAL_PROC physical address// 4. GR10 = SAL GP (physical)// 5. GR11 = Init Reason// 0 = Received INIT for event other than crash dump switch// 1 = Received wakeup at the end of an OS_MCA corrected machine check// 2 = Received INIT dude to CrashDump switch assertion// // 6. GR12 = Return address to location within SAL_INIT procedure .text .align 16.global ia64_monarch_init_handler .proc ia64_monarch_init_handler ia64_monarch_init_handler:#if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND) // // work around SAL bug that sends all processors to monarch entry // mov r17=cr.lid movl r18=__cpu_physical_id ;; dep r18=0,r18,61,3 // convert to physical address ;; shr.u r17=r17,16 ld4 r18=[r18] // get the BSP ID ;; dep r17=0,r17,16,48 ;; cmp4.ne p6,p0=r17,r18 // Am I the BSP ?(p6) br.cond.spnt slave_init_spin_me ;;#endif //// ok, the first thing we do is stash the information// the SAL passed to os//_tmp = r2 movl _tmp=ia64_sal_to_os_handoff_state ;; dep _tmp=0,_tmp, 61, 3 // get physical address ;; st8 [_tmp]=r1,0x08;; st8 [_tmp]=r8,0x08;; st8 [_tmp]=r9,0x08;; st8 [_tmp]=r10,0x08;; st8 [_tmp]=r11,0x08;; st8 [_tmp]=r12,0x08;;// now we want to save information so we can dump registers SAVE_MIN_WITH_COVER ;; mov r8=cr.ifa mov r9=cr.isr adds r3=8,r2 // set up second base pointer ;; SAVE_REST // ok, enough should be saved at this point to be dangerous, and supply// information for a dump// We need to switch to Virtual mode before hitting the C functions.//// // movl r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN mov r3=psr // get the current psr, minimum enabled at this point ;; or r2=r2,r3 ;; movl r3=IVirtual_Switch ;; mov cr.iip=r3 // short return to set the appropriate bits mov cr.ipsr=r2 // need to do an rfi to set appropriate bits ;; rfi ;;IVirtual_Switch: // // We should now be running virtual // // Lets call the C handler to get the rest of the state info // alloc r14=ar.pfs,0,0,1,0 // now it's safe (must be first in insn group!) ;; // adds out0=16,sp // out0 = pointer to pt_regs ;; br.call.sptk.few rp=ia64_init_handler.ret1:return_from_init: br.sptk return_from_init .endp//// SAL to OS entry point for INIT on the slave processor// This has been defined for registration purposes with SAL // as a part of ia64_mca_init.// .text .align 16.global ia64_slave_init_handler.proc ia64_slave_init_handleria64_slave_init_handler: slave_init_spin_me: br.sptk slave_init_spin_me ;; .endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -