📄 excalib.s
字号:
stw p0, _PPC_ESF_P0(sp) /* save general register P0 */ mfspr p0, CRIT_SAVE_PC /* load saved PC to P0 */ stw p0, _PPC_ESF_PC(sp) /* save PC in ESF */ mfspr p0, CRIT_SAVE_MSR /* load saved MSR to P0 */ stw p0, _PPC_ESF_MSR(sp) /* save MSR in ESF */ stw p1, _PPC_ESF_P1(sp) /* save general register P1 */ mfcr p1 /* load CR to P1 */ stw p1, _PPC_ESF_CR(sp) /* save CR */# if (CPU == PPC405F) /* * we need the following fix for certain versions of PPC405F */# ifdef PPC405F_ERRATA_18 mtspr SPRG2, p0 /* save P0 (SRR1) */ mfspr p1, LR /* save current LR */ mtspr SPRG0, p1 bl fpCrtfix /* handle fix */ mfspr p1, SPRG0 /* load LR */ mtspr LR, p1 mfspr p0, SPRG2 /* restore P0 (SRR1) */# endif /* PPC405F_ERRATA_18 */# endif /* CPU == PPC405F */#if ((CPU == PPC405) || (CPU == PPC405F) || (CPU == PPC440) || \ (CPU == PPC85XX)) /* * Before we reenable the MMU, we need to ensure that the values * we pushed on the stack above are flushed out of cache. */ dcbf 0, sp /* push SP value to memory */ li p1, _PPC_ESF_LR dcbf p1, sp /* push LR value to memory */ li p1, _PPC_ESF_P0 dcbf p1, sp /* push P0 value to memory */ li p1, _PPC_ESF_PC dcbf p1, sp /* push PC value to memory */ li p1, _PPC_ESF_MSR dcbf p1, sp /* push MSR value to memory */ li p1, _PPC_ESF_P1 dcbf p1, sp /* push P1 value to memory */ li p1, _PPC_ESF_CR dcbf p1, sp /* push CR value to memory */ sync#endif /* CPU == PPC405, PPC405F, PPC440, PPC85XX */ /* * Now turn the data or/and instruction MMU on if they were * previously turned on. * the critical registers are save. Now the interrupt and machine * check can be re-enabled. If an interrupt or exception is detected * the previous state can be reconstructed. */ mfmsr p1 /* p1 = MSRval current */ /* p0 should have MSRval app */ mtspr SPRG2, p1 /* SPRG2 = MSRval current */ lis p1, HI( _MSR_CE | _MSR_IR | _MSR_DR | _MSR_IS | _MSR_DS | _PPC_MSR_EE ) ori p1, p1, LO( _MSR_CE | _MSR_IR | _MSR_DR | _MSR_IS | _MSR_DS | _PPC_MSR_EE ) and. p0, p1, p0 /* extract app IR,DR,CE,EE */ mfspr p1, SPRG2 /* p1 = MSRval before */ or p1, p1, p0 /* p1 = MSRval current with */ /* app IR,DR,CE,EE */ mtmsr p1 /* ENABLE INTERRUPT & MMU */ isync /* synchronize */ mfspr p0, LR /* p0 = exception number */ /* may be wrong if relocated *//* * The LR value is offset from the vector address by the size of the * bla and other instructions preceding it in excCrtConnectCode (or * in excExtCrtConnectCode if excExtendedVectors is in effect). * * The offset amounts to 4 * (ENT_CRT_OFF + 1) or 4 * EXT_ISR_CRT_OFF * respectively, however these symbols are defined in excArchLib.c * and the definitions are not accessible here. */ lis p1, HIADJ(excExtendedVectors) lwz p1, LO(excExtendedVectors)(p1) /* get excExtendedVectors */ cmpwi p1, 0 /* if 0, short vectors */ beq crtShortVec li p1, 20 /* 4 * (EXT_ISR_CRT_OFF - (ENT_CRT_OFF + 1)) */crtShortVec: addi p1, p1, 12 /* 4 * (ENT_CRT_OFF + 1) */ sub p0, p0, p1 stw p0, _PPC_ESF_VEC_OFF(sp) /* store to ESF */ mfspr p0, CTR /* load CTR to P0 */ stw p0, _PPC_ESF_CTR(sp) /* save CTR */ mfspr p1, XER /* load XER to P0 */ stw p1, _PPC_ESF_XER(sp) /* save XER */# if (CPU == PPC403) mfdcr p0, BEAR /* load BEAR to P0 */ stw p0, _PPC_ESF_BEAR(sp) /* save BEAR */ mfdcr p0, BESR /* load to P0 */ stw p0, _PPC_ESF_BESR(sp) /* save BESR */ li p0,0 /* clear BESR */ mtdcr BESR,p0 # elif ((CPU == PPC405) || (CPU == PPC405F)) /* * For PPC405, since the BEAR/BESR DCR numbers (strictly speaking * the PLB PEAR/PESR) are implementation dependant, we use * BSP provided functions to access these registers. */ mfspr p1, LR /* save current LR */ bl sysDcrPlbbearGet /* read BEAR into p0 */ stw p0, _PPC_ESF_BEAR(sp) /* save BEAR */ bl sysDcrPlbbesrGet /* read BESR into p0 */ stw p0, _PPC_ESF_BESR(sp) /* save BESR */ li p0,-1 /* clear BESR - write all 1s */ bl sysDcrPlbbesrClear /* write BESR from p0 */ mtspr LR, p1 /* restore current LR */# endif /* PPC40x */ /* * SPEFP code in handler not supported. No need to save for now. */#if FALSE#if (CPU == PPC85XX) mfspr p1, SPEFSCR /* load SPEFSCR to P1 */ stw p1, _PPC_ESF_SPEFSCR(sp) /* save SPEFSCR */#endif /* (CPU == PPC85XX) */#endif /* FALSE */# if (CPU == PPC85XX) mfspr p0, DBSR /* load DBSR to P0 */ stw p0, _PPC_ESF_ESR(sp) /* save DBSR */# endif /* CPU == PPC85XX */ stw r0, _PPC_ESF_R0(sp) /* save general register 0 */ addi r0, r1, _PPC_ESF_STK_SIZE stw r0, _PPC_ESF_R1(sp) /* save exception sp */ stw r2, _PPC_ESF_R2(sp) /* save general register 2 */# if TRUE /* optimization to test */ /* save the volatile register values on the ESF */ stw p2, _PPC_ESF_P2(sp) /* save general register 5 */ stw p3, _PPC_ESF_P3(sp) /* save general register 6 */ stw p4, _PPC_ESF_P4(sp) /* save general register 7 */ stw p5, _PPC_ESF_P5(sp) /* save general register 8 */ stw p6, _PPC_ESF_P6(sp) /* save general register 9 */ stw p7, _PPC_ESF_P7(sp) /* save general register 10 */ stw r11, _PPC_ESF_R11(sp) /* save general register 11 */ stw r12, _PPC_ESF_R12(sp) /* save general register 12 */ stw r13, _PPC_ESF_R13(sp) /* save general register 13 */ /* save the non volatile register values on the ESF */ stw t0, _PPC_ESF_T0(sp) /* save general register 14 */ stw t1, _PPC_ESF_T1(sp) /* save general register 15 */ stw t2, _PPC_ESF_T2(sp) /* save general register 16 */ stw t3, _PPC_ESF_T3(sp) /* save general register 17 */ stw t4, _PPC_ESF_T4(sp) /* save general register 18 */ stw t5, _PPC_ESF_T5(sp) /* save general register 19 */ stw t6, _PPC_ESF_T6(sp) /* save general register 20 */ stw t7, _PPC_ESF_T7(sp) /* save general register 21 */ stw t8, _PPC_ESF_T8(sp) /* save general register 22 */ stw t9, _PPC_ESF_T9(sp) /* save general register 23 */ stw t10, _PPC_ESF_T10(sp) /* save general register 24 */ stw t11, _PPC_ESF_T11(sp) /* save general register 25 */ stw t12, _PPC_ESF_T12(sp) /* save general register 26 */ stw t13, _PPC_ESF_T13(sp) /* save general register 27 */ stw t14, _PPC_ESF_T14(sp) /* save general register 28 */ stw t15, _PPC_ESF_T15(sp) /* save general register 29 */ stw t16, _PPC_ESF_T16(sp) /* save general register 30 */ stw t17, _PPC_ESF_T17(sp) /* save general register 31 */# else /* TRUE */ stmw p2, _PPC_ESF_P2(sp) /* save general register 5 */ /* through 31 */# endif /* TRUE */ blr /* return to caller */FUNC_END(excCrtEnt)/********************************************************************************* excCrtExit - default context restore routine upon critical exception exit** NOMANUAL* void excExit()*/FUNC_BEGIN(excCrtExit) /* restore dedicated and scratch registers */ lwz r0, _PPC_ESF_R0(sp) /* restore general register 0 */ lwz r2, _PPC_ESF_R2(sp) /* restore general register 2 */# if TRUE /* optimization to test */ /* restore volatile registers */ lwz p1, _PPC_ESF_P1(sp) /* restore general register 4 */ lwz p2, _PPC_ESF_P2(sp) /* restore general register 5 */ lwz p3, _PPC_ESF_P3(sp) /* restore general register 6 */ lwz p4, _PPC_ESF_P4(sp) /* restore general register 7 */ lwz p5, _PPC_ESF_P5(sp) /* restore general register 8 */ lwz p6, _PPC_ESF_P6(sp) /* restore general register 9 */ lwz p7, _PPC_ESF_P7(sp) /* restore general reg 10 */ lwz r11, _PPC_ESF_R11(sp) /* restore general reg 11 */ lwz r12, _PPC_ESF_R12(sp) /* restore general reg 12 */ lwz r13, _PPC_ESF_R13(sp) /* restore general reg 13 */ /* restore non-volatile registers */ /* * XXX TPR the non-volatile should not be restored because they are * not destroyed. To test or verify */ lwz t0, _PPC_ESF_T0(sp) /* restore general reg 14 */ lwz t1, _PPC_ESF_T1(sp) /* restore general reg 15 */ lwz t2, _PPC_ESF_T2(sp) /* restore general reg 16 */ lwz t3, _PPC_ESF_T3(sp) /* restore general reg 17 */ lwz t4, _PPC_ESF_T4(sp) /* restore general reg 18 */ lwz t5, _PPC_ESF_T5(sp) /* restore general reg 19 */ lwz t6, _PPC_ESF_T6(sp) /* restore general reg 20 */ lwz t7, _PPC_ESF_T7(sp) /* restore general reg 21 */ lwz t8, _PPC_ESF_T8(sp) /* restore general reg 22 */ lwz t9, _PPC_ESF_T9(sp) /* restore general reg 23 */ lwz t10, _PPC_ESF_T10(sp) /* restore general reg 24 */ lwz t11, _PPC_ESF_T11(sp) /* restore general reg 25 */ lwz t12, _PPC_ESF_T12(sp) /* restore general reg 26 */ lwz t13, _PPC_ESF_T13(sp) /* restore general reg 27 */ lwz t14, _PPC_ESF_T14(sp) /* restore general reg 28 */ lwz t15, _PPC_ESF_T15(sp) /* restore general reg 29 */ lwz t16, _PPC_ESF_T16(sp) /* restore general reg 30 */ lwz t17, _PPC_ESF_T17(sp) /* restore general reg 31 */# else /* TRUE */ lmw p1, _PPC_ESF_P1(sp) /* restore general register 5 */ /* through 31 */# endif /* TRUE */ /* restore user level special purpose registers */ lwz p0, _PPC_ESF_CTR(sp) /* load saved CTR to P0*/ mtspr CTR, p0 /* restore CTR */ lwz p0, _PPC_ESF_XER(sp) /* load saved XER to P0 */ mtspr XER, p0 /* restore XER */ lwz p0, _PPC_ESF_LR(sp) /* load saved LR to P0 */ mtspr LR, p0 /* restore LR */ lwz p0, _PPC_ESF_CR(sp) /* load the saved CR to P0 */ mtcrf 255,p0 /* restore CR */ /* * SPEFP code in handler not supported. No need to save for now. */#if FALSE#if (CPU==PPC85XX) lwz p0, _PPC_ESF_SPEFSCR(sp) /* load saved SPEFSCR to P0 */ mtspr SPEFSCR, p0 /* restore SPEFSCR */#endif /* (CPU==PPC85XX) */#endif /* FALSE */ /* XXX TPR this code can be optimized */ mfmsr p0 /* read msr */# ifdef _PPC_MSR_RI RI_MASK(p0, p0 ) /* mask RI bit */# endif /* _PPC_MSR_RI */ INT_MASK(p0,p0) /* clear EE bit in msr */ mtmsr p0 /* DISABLE INTERRUPT */ isync /* synchronize */ lwz p0, _PPC_ESF_PC(sp) /* load the saved PC to P0 */ mtspr CRIT_SAVE_PC, p0 /* and restore CRIT_SAVE_PC */ lwz p0, _PPC_ESF_MSR(sp) /* load the saved MSR to P0 */ mtspr CRIT_SAVE_MSR, p0 /* and restore CRIT_SAVE_MSR */ lwz p0, _PPC_ESF_P0(sp) /* restore p0 */ lwz sp, _PPC_ESF_SP(sp) /* restore the stack pointer */ rfci /* return to context of the */ /* task that got exception */FUNC_END(excCrtExit)#ifdef _PPC_MSR_MCE/******************************************************************************** excMchkEnt - default context save routine on machine check exception entrance* NOTE: The stack pointer is already set to the exception stack frame pointer.* The exception vector on the stack is saved as vector offset +* _EXC_CODE_SIZE.** NOMANUAL* void excMchkEnt()*/FUNC_BEGIN(excMchkEnt) /* At the entry of this function, the following is done */ /* mtspr SPRG4, p0 /@ save P0 to SPRG4 */ /* mfspr p0, LR /@ load LR to P0 */ /* bla excMchkEnt /@ call excMchkEnt */ /* * reserve a room equal to the size of the ESF. This memory space is * taken from the stack of the task which has produce the exception. * This memory space is used to save the processor critical register * values. */ stwu sp, - _PPC_ESF_STK_SIZE(sp) /* update SP */ stw p0, _PPC_ESF_LR(sp) /* save LR */ mfspr p0, SPRG4_W /* load saved P0 */ stw p0, _PPC_ESF_P0(sp) /* save general register P0 */ mfspr p0, MCSRR0 /* load saved PC to P0 */ stw p0, _PPC_ESF_PC(sp) /* save PC in ESF */ mfspr p0, MCSRR1 /* load saved MSR to P0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -