📄 excalib.s
字号:
/* before clearing EXL */ and k1, ~SR_EXL /* reenable previous exception state */#endif mtc0 k1, C0_SR HAZARD_CP_WRITE .set noat mflo AT /* read entry lo reg */ SW AT,E_STK_LO(sp) /* save entry lo reg */ mfhi AT /* read entry hi reg */ SW AT,E_STK_HI(sp) /* save entry hi reg */0: .set at SW zero, E_STK_ZERO(sp) /* save zero */ SW zero, E_STK_K1(sp) /* dummy value to k1 */ SW v1,E_STK_V1(sp) /* save func return 1 */ SW a0,E_STK_A0(sp) /* save passed param 0 */ SW a1,E_STK_A1(sp) /* save passed param 1 */ SW a2,E_STK_A2(sp) /* save passed param 2 */ SW a3,E_STK_A3(sp) /* save passed param 3 */ SW t0,E_STK_T0(sp) /* save temp reg 0 */ SW t1,E_STK_T1(sp) /* save temp reg 1 */ SW t2,E_STK_T2(sp) /* save temp reg 2 */ SW t3,E_STK_T3(sp) /* save temp reg 3 */ SW t4,E_STK_T4(sp) /* save temp reg 4 */ SW t5,E_STK_T5(sp) /* save temp reg 5 */ SW t6,E_STK_T6(sp) /* save temp reg 6 */ SW t7,E_STK_T7(sp) /* save temp reg 7 */ SW t8,E_STK_T8(sp) /* save temp reg 8 */ SW t9,E_STK_T9(sp) /* save temp reg 9 */ SW s0,E_STK_S0(sp) /* save saved reg 0 */ SW s1,E_STK_S1(sp) /* save saved reg 1 */ SW s2,E_STK_S2(sp) /* save saved reg 2 */ SW s3,E_STK_S3(sp) /* save saved reg 3 */ SW s4,E_STK_S4(sp) /* save saved reg 4 */ SW s5,E_STK_S5(sp) /* save saved reg 5 */ SW s6,E_STK_S6(sp) /* save saved reg 6 */ SW s7,E_STK_S7(sp) /* save saved reg 7 */ SW s8,E_STK_FP(sp) /* save saved reg 8 */ SW gp,E_STK_GP(sp) /* save global pointer? */ SW ra, E_STK_RA(sp) /* save return address */ srl a0, v0, 2 /* pass vector number */ move a1, sp /* pass exc stack frame */ la a2, E_STK_SR(sp) /* pass general register ptr */ la t0, excBsrTbl addu v0, t0 lw v0, (v0) /* grab routine addr */ jal v0 /* jump to routine, only return from remote breakpoints */excReturn: LW v0,E_STK_V0(sp) /* restore func ret 0 */ LW v1,E_STK_V1(sp) /* restore func ret 0 */ LW a0,E_STK_A0(sp) /* restore param 0 */ LW a1,E_STK_A1(sp) /* restore param 1 */ LW a2,E_STK_A2(sp) /* restore param 2 */ LW a3,E_STK_A3(sp) /* restore param 3 */ LW t0,E_STK_T0(sp) /* restore temp reg 0 */ LW t1,E_STK_T1(sp) /* restore temp reg 1 */ LW t2,E_STK_T2(sp) /* restore temp reg 2 */ LW t3,E_STK_T3(sp) /* restore temp reg 3 */ LW t4,E_STK_T4(sp) /* restore temp reg 4 */ LW t5,E_STK_T5(sp) /* restore temp reg 5 */ LW t6,E_STK_T6(sp) /* restore temp reg 6 */ LW t7,E_STK_T7(sp) /* restore temp reg 7 */ LW s0,E_STK_S0(sp) /* restore saved reg 0 */ LW s1,E_STK_S1(sp) /* restore saved reg 1 */ LW s2,E_STK_S2(sp) /* restore saved reg 2 */ LW s3,E_STK_S3(sp) /* restore saved reg 3 */ LW s4,E_STK_S4(sp) /* restore saved reg 4 */ LW s5,E_STK_S5(sp) /* restore saved reg 5 */ LW s6,E_STK_S6(sp) /* restore saved reg 6 */ LW s7,E_STK_S7(sp) /* restore saved reg 7 */ LW s8,E_STK_FP(sp) /* restore saved reg 8 */ LW gp,E_STK_GP(sp) /* restore global ptr? */ LW ra,E_STK_RA(sp) /* restore return addr */ LW t9,E_STK_LO(sp) /* grab entry hi reg */ mtlo t9 /* restore entry hi reg */ LW t9,E_STK_HI(sp) /* grab entry lo reg */ mthi t9 /* restore entry hi reg */0:#ifndef _WRS_R3K_EXC_SUPPORT /* ensure that IMASK is clear before enabling EXL */ li t9,SR_IE mtc0 t9,C0_SR HAZARD_CP_WRITE#endif lw t9,E_STK_SR(sp) /* read old SR */#ifndef _WRS_R3K_EXC_SUPPORT or t9, SR_EXL#else /* _WRS_R3K_EXC_SUPPORT */ /* Shift IEc and KUc bits in the SR left by 2 prior to executing * the rfe instruction and resuming in the requested context. * excExcHandle (excArchLib.c) shifted the SR down * by 2 when we first entered the exception. */ and t8, t9,0x00000003 sll t8, 2 and t9, 0xFFFFFFF0 or t9, t8 #endif mtc0 t9, C0_SR /* restore SR (EXL set) */ HAZARD_CP_WRITE .set noat LW AT,E_STK_AT(sp) /* restore AT reg */ LW t8,E_STK_T8(sp) /* restore temp reg 8 */ LW t9,E_STK_T9(sp) /* restore temp reg 9 */ lw k1,E_STK_EPC(sp) /* grab pc */ addu sp, ESTKSIZE /* restore stack */ .set noreorder#ifdef _WRS_R3K_EXC_SUPPORT j k1 /* restart with old state */ rfe /* reenable ints if enable previous is set */#else mtc0 k1,C0_EPC HAZARD_ERET eret#endif .set reorder .set at .end excStub/********************************************************************************* excIntStub - Catch and dispatch interrupts ** This is the interrupt dispatcher that is pointed to by the general * exception vector. In this routine we take care of saving state, and* jumping to the appropriate routines. On exit from handling we also* return here to restore state properly.** This routine is not callable!! This routine does not include save and* restore of floating point state.** INTERNAL* The goal here is to turn interrupts back on a quickly as possible.* Some guidelines we have followed are that k0 and k1 can ONLY be * used in non-interruptible sections. Control is finally passed to intExit* with interrupts disabled. Also, before we turn interrupts back on we must * save as a minimum the state of the processor that changed upon interrupt * generation (volatile registers). Volatile registers include the EPC, * and STATUS registers. Also saved before interrupts are enabled, are the * sp, v0, and at regs. These registers are not volatile, but used in reading * and saving volatile registers, and calculation of the interrupted processor * state. Saved registers (s regs) are not saved upon interrupts because the * MIPS compiler philosophy is to save any s-regs they use before any call.** at - so assembler can use at (non-volatile)* sp - we use interrupt stack (non-volatile)* epc - changed upon excpt generation (volatile)* cause - changed upon excpt generation (volatile)* status - must read to bugging int (volatile)* badva - changed upon excpt generation (volatile)* v0 - holds calculated int cause (non-volatile)** All interrupts that are not pending are allowed. This is done by* using the cause and status registers to determine which external* interrupts are pending and shutting specifically those off.** Interrupt priority is either 0-7 or 7-0 depending on the value of* sysHashOrder in sysLib.c.** The pad field of the intPrioTable determines whether to call a* BSP provided interrupt demultiplex function. If the pad field* is zero there no multiplexing necessary, otherwise the pad field* is passed to the multiplex routine as the base interrupt vector* for the multiplex group.** The offset field is the interrupt vector to use, or if the pad* field is non zero, the address of the multiplex routine.** See intPrioTable in sysLib.c , and excBsrTbl in excArchLib.c for a * clearer picture.** NOMANUAL* void excIntStub()*/ .globl excIntStub .ent excIntStubexcIntStub: .set noat/* * Are we nested interrupt ??? */ /* k1 should now contain areWeNested */ bne k1, zero, nested /* if in isr don't reset sp */ lw k0, vxIntStackBase /* else {grab addr of int stack */ subu k0, ESTKSIZE /* make room for frame */ SW sp, E_STK_SP(k0) /* save sp on int stack */ move sp, k0 /* init new int stack ptr} */ b save_critical /* jump over stack manip */nested: SW sp, E_STK_SP-ESTKSIZE(sp) /* save sp in new intstk frame */ subu sp, ESTKSIZE /* make new int stk frame */save_critical: SW AT,E_STK_AT(sp) /* save as resvd reg */ .set at#ifndef WV_INSTRUMENTATION SW v0,E_STK_V0(sp) /* save return reg 0 */#endif /* WV_INSTRUMENTATION */ /* * The following code replaces intEnt so I don't need * to save ra while interrupts are masked */ addu k1, 1 /* increment areWeNested */ sw k1, areWeNested /* update value */ lw k1, intCnt /* load intCnt */ addu k1, 1 /* increment intCnt */ sw k1, intCnt /* update value */#ifdef WV_INSTRUMENTATION/* * Begin state save */intStateSave: SW zero,E_STK_ZERO(sp) /* init zero reg storage */ SW v0,E_STK_V0(sp) /* save func return 0 */ SW v1,E_STK_V1(sp) /* save func return 1 */ SW a0,E_STK_A0(sp) /* save passed param 0 */ SW a1,E_STK_A1(sp) /* save passed param 1 */ SW a2,E_STK_A2(sp) /* save passed param 2 */ SW a3,E_STK_A3(sp) /* save passed param 3 */ SW t0,E_STK_T0(sp) /* save temp reg 0 */ SW t1,E_STK_T1(sp) /* save temp reg 1 */ SW t2,E_STK_T2(sp) /* save temp reg 2 */ SW t3,E_STK_T3(sp) /* save temp reg 3 */ SW t4,E_STK_T4(sp) /* save temp reg 4 */ SW t5,E_STK_T5(sp) /* save temp reg 5 */ SW t6,E_STK_T6(sp) /* save temp reg 6 */ SW t7,E_STK_T7(sp) /* save temp reg 7 */ SW t8,E_STK_T8(sp) /* save temp reg 8 */ SW t9,E_STK_T9(sp) /* save temp reg 9 */ SW ra,E_STK_RA(sp) /* save return address */ mflo t2 /* read entry lo reg */ mfhi t3 /* read entry hi reg */ SW t2,E_STK_LO(sp) /* save entry lo reg */ SW t3,E_STK_HI(sp) /* save entry hi reg */0: #else /* WV_INSTRUMENTATION */ lw k0,errno sw k0,E_ERRNO(sp) /* save errno */#endif /* WV_INSTRUMENTATION */ .set noreorder mfc0 k1, C0_SR /* read status register */ mfc0 k0, C0_EPC /* read exception pc */ mfc0 v0, C0_CAUSE /* read cause register */ HAZARD_CP_READ sw k1, E_STK_SR(sp) /* save status on stack */ sw k0, E_STK_EPC(sp) /* save EPC on stack */ sw v0, E_STK_CAUSE(sp) /* save cause on stack */ .set reorder#ifdef WV_INSTRUMENTATION /* * windview instrumentation - BEGIN * enter an interrupt handler. */ lw t0, evtAction /* is instrumentation on? */ beqz t0, noIntEnt /* we are checking * if ((wvEvtClass&(WV_CLASS_1_ON)) != (WV_CLASS_1_ON)) * leave WV instrumentation and check triggering */ lw t0, wvEvtClass li t4, WV_CLASS_1_ON and t0, t0, t4 bne t4, t0, trgCheckIntEnt /* interrupts are locked * all registers are saved * k1 has STATUS and v0 has CAUSE from above */ lw t4, sysHashOrder /* load address of hash table */ and t1, k1, SR_IMASK /* t1 = IM[7:0] */ and t1, v0 /* t1 = IM[7:0] & IP[7:0] */ bnez t1, 0f /* if interrupt, skip down; */ /* dont check extended bits */ lw t2, intStubSelect beqz t2, 0f /* if not using Rm7K, skip down; */ /* dont check extended bits */ srl t2, v0, CAUSE_EXTMASKSHIFT /* align IP in CAUSE with ICR */ cfc0 t1, C0_1_IC /* get ICR */ HAZARD_CP_READ and t1, IC_IMASK /* t1 = IM[15:8] */ and t1, t2 /* t1 = IM[15:8] & IP[15:8] */ beqz t1, 0f /* if still no interrupt, skip */ /* use low-order interrupt */ srl t1, IC_IMASKSHIFT /* right justify */ addu t1, t4 /* calculate table index */ lbu t2, 0(t1) /* read table index */ addu t2, 8 /* adjust to upper half */ b 1f /* skip down to function call *//* get to here if IP[7:0] -or- not using Rm7k extended interrrupts */0: srl t1, SR_IMASKSHIFT /* right justify */ addu t1, t4 /* calculate table index */ lbu t2, 0(t1) /* read table index *//* make the function call */1: addu a0, t2, MIN_INT_ID+1 lw t1, _func_evtLogT0 jal t1 /* call evtLogT0 routine */ lw v0, E_STK_CAUSE(sp) /* restore the value of v0. We */ /* might have lost it in evtLogT0 */trgCheckIntEnt: lw t0, trgEvtClass li t4, TRG_CLASS_1_ON and t0, t0, t4 bne t4, t0, noIntEnt lw t4, sysHashOrder /* load address of hash table */ and t1, k1, SR_IMASK /* t1 = IM[7:0] */ and t1, v0 /* t1 = IM[7:0] & IP[7:0] */ bnez t1, 0f /* if interrupt, skip down; */ /* dont check extended bits */ lw t2, intStubSelect beqz t2, 0f /* if not using Rm7K, skip down; */ /* dont check extended bits */ srl t2, v0, CAUSE_EXTMASKSHIFT /* align IP in CAUSE with ICR */ cfc0 t1, C0_1_IC /* get ICR */ HAZARD_CP_READ and t1, IC_IMASK /* t1 = IM[15:8] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -