📄 mca_asm.s
字号:
GET_IA64_MCA_DATA(r2) ;; add r2 = IA64_MCA_CPU_STACK_OFFSET+IA64_MCA_STACK_SIZE-16, r2 ;; mov r12=r2 // establish new stack-pointer // Enter virtual mode from physical mode VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)ia64_os_mca_virtual_begin: // Call virtual mode handler movl r2=ia64_mca_ucmc_handler;; mov b6=r2;; br.call.sptk.many b0=b6;;.ret0: // Revert back to physical mode before going back to SAL PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)ia64_os_mca_virtual_end: // restore the original stack frame here GET_IA64_MCA_DATA(r2) ;; add r2 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2 ;; movl r4=IA64_PSR_MC ;; rse_return_context(r4,r3,r2) // switch from interrupt context for RSE // let us restore all the registers from our PSI structure mov r8=gp ;;begin_os_mca_restore: br ia64_os_mca_proc_state_restore;;ia64_os_mca_done_restore: OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2);; // branch back to SALE_CHECK ld8 r3=[r2];; mov b0=r3;; // SAL_CHECK return address // release lock movl r3=ia64_mca_serialize;; DATA_VA_TO_PA(r3);; st8.rel [r3]=r0 br b0 ;;ia64_os_mca_dispatch_end://EndMain////////////////////////////////////////////////////////////////////////++// Name:// ia64_os_mca_proc_state_dump()//// Stub Description://// This stub dumps the processor state during MCHK to a data area////--ia64_os_mca_proc_state_dump:// Save bank 1 GRs 16-31 which will be used by c-language code when we switch// to virtual addressing mode. GET_IA64_MCA_DATA(r2) ;; add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2 ;;// save ar.NaT mov r5=ar.unat // ar.unat// save banked GRs 16-31 along with NaT bits bsw.1;; st8.spill [r2]=r16,8;; st8.spill [r2]=r17,8;; st8.spill [r2]=r18,8;; st8.spill [r2]=r19,8;; st8.spill [r2]=r20,8;; st8.spill [r2]=r21,8;; st8.spill [r2]=r22,8;; st8.spill [r2]=r23,8;; st8.spill [r2]=r24,8;; st8.spill [r2]=r25,8;; st8.spill [r2]=r26,8;; st8.spill [r2]=r27,8;; st8.spill [r2]=r28,8;; st8.spill [r2]=r29,8;; st8.spill [r2]=r30,8;; st8.spill [r2]=r31,8;; mov r4=ar.unat;; st8 [r2]=r4,8 // save User NaT bits for r16-r31 mov ar.unat=r5 // restore original unat bsw.0;;//save BRs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 mov r3=b0 mov r5=b1 mov r7=b2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=b3 mov r5=b4 mov r7=b5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=b6 mov r5=b7;; st8 [r2]=r3,2*8 st8 [r4]=r5,2*8;;cSaveCRs:// save CRs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 mov r3=cr.dcr mov r5=cr.itm mov r7=cr.iva;; st8 [r2]=r3,8*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; // 48 byte rements mov r3=cr.pta;; st8 [r2]=r3,8*8;; // 64 byte rements// if PSR.ic=0, reading interruption registers causes an illegal operation fault mov r3=psr;; tbit.nz.unc p6,p0=r3,PSR_IC;; // PSI Valid Log bit pos. test(p6) st8 [r2]=r0,9*8+160 // increment by 232 byte inc.begin_skip_intr_regs:(p6) br SkipIntrRegs;; add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 mov r3=cr.ipsr mov r5=cr.isr mov r7=r0;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=cr.iip mov r5=cr.ifa mov r7=cr.itir;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=cr.iipa mov r5=cr.ifs mov r7=cr.iim;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=cr25;; // cr.iha st8 [r2]=r3,160;; // 160 byte rementSkipIntrRegs: st8 [r2]=r0,152;; // another 152 byte . add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 mov r3=cr.lid// mov r5=cr.ivr // cr.ivr, don't read it mov r7=cr.tpr;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=r0 // cr.eoi => cr67 mov r5=r0 // cr.irr0 => cr68 mov r7=r0;; // cr.irr1 => cr69 st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=r0 // cr.irr2 => cr70 mov r5=r0 // cr.irr3 => cr71 mov r7=cr.itv;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=cr.pmv mov r5=cr.cmcv;; st8 [r2]=r3,7*8 st8 [r4]=r5,7*8;; mov r3=r0 // cr.lrr0 => cr80 mov r5=r0;; // cr.lrr1 => cr81 st8 [r2]=r3,23*8 st8 [r4]=r5,23*8;; adds r2=25*8,r2;;cSaveARs:// save ARs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 mov r3=ar.k0 mov r5=ar.k1 mov r7=ar.k2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=ar.k3 mov r5=ar.k4 mov r7=ar.k5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=ar.k6 mov r5=ar.k7 mov r7=r0;; // ar.kr8 st8 [r2]=r3,10*8 st8 [r4]=r5,10*8 st8 [r6]=r7,10*8;; // rement by 72 bytes mov r3=ar.rsc mov ar.rsc=r0 // put RSE in enforced lazy mode mov r5=ar.bsp ;; mov r7=ar.bspstore;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; mov r3=ar.rnat;; st8 [r2]=r3,8*13 // increment by 13x8 bytes mov r3=ar.ccv;; st8 [r2]=r3,8*4 mov r3=ar.unat;; st8 [r2]=r3,8*4 mov r3=ar.fpsr;; st8 [r2]=r3,8*4 mov r3=ar.itc;; st8 [r2]=r3,160 // 160 mov r3=ar.pfs;; st8 [r2]=r3,8 mov r3=ar.lc;; st8 [r2]=r3,8 mov r3=ar.ec;; st8 [r2]=r3 add r2=8*62,r2 //padding// save RRs mov ar.lc=0x08-1 movl r4=0x00;;cStRR: dep.z r5=r4,61,3;; mov r3=rr[r5];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR ;;end_os_mca_dump: br ia64_os_mca_done_dump;;//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 GET_IA64_MCA_DATA(r2) ;; add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2restore_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 cr.dcr=r3 mov cr.itm=r5 mov cr.iva=r7;; ld8 r3=[r2],8*8;; // 64 byte increments// mov cr.pta=r3// if PSR.ic=1, reading interruption registers causes an illegal operation fault mov r3=psr;; tbit.nz.unc p6,p0=r3,PSR_IC;; // PSI Valid Log bit pos. test(p6) st8 [r2]=r0,9*8+160 // increment by 232 byte inc.begin_rskip_intr_regs:(p6) br rSkipIntrRegs;; 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 cr.ipsr=r3// mov cr.isr=r5 // cr.isr is read only ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov cr.iip=r3 mov cr.ifa=r5 mov cr.itir=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov cr.iipa=r3 mov cr.ifs=r5 mov cr.iim=r7 ld8 r3=[r2],160;; // 160 byte increment mov cr.iha=r3rSkipIntrRegs: ld8 r3=[r2],152;; // another 152 byte inc. add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2;; // duplicate r2 in r6 ld8 r3=[r2],8*3 ld8 r5=[r4],8*3 ld8 r7=[r6],8*3;; mov cr.lid=r3// mov cr.ivr=r5 // cr.ivr is read only mov cr.tpr=r7;; ld8 r3=[r2],8*3 ld8 r5=[r4],8*3 ld8 r7=[r6],8*3;;// mov cr.eoi=r3// mov cr.irr0=r5 // cr.irr0 is read only// mov cr.irr1=r7;; // cr.irr1 is read only ld8 r3=[r2],8*3 ld8 r5=[r4],8*3 ld8 r7=[r6],8*3;;// mov cr.irr2=r3 // cr.irr2 is read only// mov cr.irr3=r5 // cr.irr3 is read only mov cr.itv=r7;; ld8 r3=[r2],8*7 ld8 r5=[r4],8*7;; mov cr.pmv=r3 mov cr.cmcv=r5;; ld8 r3=[r2],8*23 ld8 r5=[r4],8*23;; adds r2=8*23,r2 adds r4=8*23,r4;;// mov cr.lrr0=r3// mov cr.lrr1=r5 adds r2=8*2,r2;;restore_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 ar.k0=r3 mov ar.k1=r5 mov ar.k2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; mov ar.k3=r3 mov ar.k4=r5 mov ar.k5=r7;; ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; mov ar.k6=r3 mov ar.k7=r5 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;;// mov ar.rsc=r3// mov ar.bsp=r5 // ar.bsp is read only mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode ;; mov ar.bspstore=r7;; ld8 r9=[r2],8*13;; mov ar.rnat=r9 mov ar.rsc=r3 ld8 r3=[r2],8*4;; mov ar.ccv=r3 ld8 r3=[r2],8*4;; mov ar.unat=r3 ld8 r3=[r2],8*4;; mov ar.fpsr=r3 ld8 r3=[r2],160;; // 160// mov ar.itc=r3 ld8 r3=[r2],8;; mov ar.pfs=r3 ld8 r3=[r2],8;; mov ar.lc=r3 ld8 r3=[r2];; mov ar.ec=r3 add r2=8*62,r2;; // paddingrestore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 movl r4=0x00;;cStRRr: dep.z r7=r4,61,3 ld8 r3=[r2],8;; mov rr[r7]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; mov ar.lc=r5 ;;end_os_mca_restore: br ia64_os_mca_done_restore;;//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 following 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 procedureGLOBAL_ENTRY(ia64_monarch_init_handler) .prologue#ifdef XEN /* Need in ia64_monarch_init_handler? */ // Set current to ar.k6 GET_THIS_PADDR(r2,cpu_kr);; add r2=IA64_KR_CURRENT_OFFSET,r2;; ld8 r2=[r2];; mov ar.k6=r2;;#endif // stash the information the SAL passed to os SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2) ;; 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 // // Let's call the C handler to get the rest of the state info // alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) ;; adds out0=16,sp // out0 = pointer to pt_regs ;; DO_SAVE_SWITCH_STACK .body adds out1=16,sp // out0 = pointer to switch_stack br.call.sptk.many rp=ia64_init_handler.ret1:return_from_init: br.sptk return_from_initEND(ia64_monarch_init_handler)//// 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.//GLOBAL_ENTRY(ia64_slave_init_handler)1: br.sptk 1bEND(ia64_slave_init_handler)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -