📄 intvectoralib.s
字号:
cfc0 t3, C0_1_IC /* get IntControl */ SW t3, E_STK_ZERO(sp) /* stash IntCount in ESF */ lw k0, intActiveIPL /* get mark for calling vector */ sll k0, 3 /* mult index by 2*word size */ lw t1, intVecTable+0(k0) /* get index into Bsr table */ lw t2, intVecTable+4(k0) /* get mask bits for this IPL */ and k0, t2, 0xff00 /* isolate IM[15:8] */ not k0 /* invert interrupt mask */ and t3, k0 /* apply the mask */ ctc0 t3, C0_1_IC /* set IntControl */ and k0, t2, 0x00ff /* isolate IM[7:0] */ sll k0, 8 /* align with SR[IM] field */ not k0 /* invert interrupt mask */ and k1, k0 /* apply the mask */ and k1, ~SR_EXL mtc0 k1, C0_SR /* enable interrupts w/ new mask */ /* * Begin state save */#ifndef WV_INSTRUMENTATIONintStateSave: mflo t2 /* read entry lo reg */ SW t2,E_STK_LO(sp) /* save entry lo reg */ mfhi t2 /* read entry hi reg */ SW t2,E_STK_HI(sp) /* save entry hi reg */0: /* save func return 0, see above */ 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 */ /* save temp reg 1, see above */ /* save temp reg 2, see above */ /* save temp reg 3, see above */ 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 */#endif /* WV_INSTRUMENTATION *//* * Call the application ISR */ move a0, t1 /* pass vector number */ move a1, sp /* pass exc stack frame */ sll t1, 2 /* mult index by wordsize */ lw v1, excBsrTbl(t1) /* get ISR address */ jal v1 /* jump to service routine *//* * Begin state restoration */Restore: lw t2,E_ERRNO(sp) sw t2,errno /* restore errno */ LW v1,E_STK_V1(sp) /* restore func ret 0 */ LW a0,E_STK_A0(sp) /* restore passed param 0 */ LW a1,E_STK_A1(sp) /* restore passed param 1 */ LW a2,E_STK_A2(sp) /* restore passed param 2 */ LW a3,E_STK_A3(sp) /* restore passed param 3 */ LW t0,E_STK_T0(sp) /* restore temp reg 0 */ 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 t8,E_STK_T8(sp) /* restore temp reg 8 */ 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: LW t9,E_STK_T9(sp) /* restore temp reg 9 */ /* * Registers restored after this point must only be registers * which are considered volatile. This currently * includes SR, EPC, AT, sp, v0, t1, and t2. Any additions to * the volatile set of registers (see comments above) should * be mirrored with restores after the label restoreVolatile. */restoreVolatile: lw t1,E_STK_SR(sp) /* read old SR */ /* ensure imask == 0 before setting EXL */ li v0,SR_IE HAZARD_VR5400 mtc0 v0,C0_SR HAZARD_CP_WRITE .set noreorder LW t2, E_STK_ZERO(sp) /* get IntCount from ESF */ ctc0 t2, C0_1_IC /* set IntControl */ mtc0 t1,C0_SR /* put on processor */ .set reorder LW v0,E_STK_V0(sp) /* restore func ret 0 */ LW t3,E_STK_T3(sp) /* restore temp reg 3 */ LW t2,E_STK_T2(sp) /* restore temp reg 2 */ LW t1,E_STK_T1(sp) /* restore temp reg 1 */ j intExit /* exit kernel, exception frame */ /* on interrupt stack */ intVectorStubEnd: .end intVectorStub/*********************************************************************** intVectorVecInit - Initialization routine which installs the interrupt* vector service routines to their proper locations* in memory and initializes the appropriate registers* so as to enable vectored interupt handling** NOMANUAL* void intVectorVecInit()*/ .ent intVectorVecInitintVectorVecInit: SETFRAME(intVectorVecInit,3) subu sp, FRAMESZ(intVectorVecInit) /* need some stack */ sw ra, FRAMERA(intVectorVecInit)(sp) /* save ra */ sw s6, FRAMER0(intVectorVecInit)(sp) /* save s6 */ sw s7, FRAMER1(intVectorVecInit)(sp) /* save s7 *//* * first copy the special backwards-compatibility handler for IPL 15 */ la a0, intVectorVec15 /* source */ li a1, IPL15_VECTOR_ADDR /* destination */ lw a2, intVecSize15 /* number of bytes to copy */ /* save s0 so we can use it */ la s7, bcopy /* now call bcopy() */ jal s7/* * next copy the interrupt handler for IPLs 0-14 */ la s6, intVectorVec0 /* a0 gets wrecked by bcopy * after each call, so use s0 */ move a0, s6 /* source */ li a1, IPL0_VECTOR_ADDR /* destination */ lw a2, intVecSize0 /* number of bytes to copy */ jal s7 /* bcopy() still in s7 */ move a0, s6 /* restore source arg */ li a1, IPL1_VECTOR_ADDR /* load new destination */ jal s7 move a0, s6 li a1, IPL2_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL3_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL4_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL5_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL6_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL7_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL8_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL9_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL10_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL11_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL12_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL13_VECTOR_ADDR jal s7 move a0, s6 li a1, IPL14_VECTOR_ADDR jal s7/* * manually update the memory locations of the vector mark index * start with vector 14 and decrement until vector 0 */ li t0, MAGIC_INSTRUCT_V14 /* t0 = instruct + mark */ li t1, IPL14_VECTOR_ADDR+VECTOR_MARK_OFFSET /* t1 = vector address to write */ and t2, t0, 0xffffff00 /* t2 = mask for mark equals 0 */0: sw t0, (t1) /* update the address */ subu t1, VECTOR_SPACING /* get next vector address */ subu t0, 1 /* decrement the mark */ bne t0, t2, 0b /* finished once mark is zero *//* * now sync the D-cache */ li a0, IPL0_VECTOR_ADDR li a1, IPL15_VECTOR_ADDR+VECTOR_SPACING la s7, cacheTextUpdate /* sync cache */ jal s7/* * lastly, initialize the registers */ cfc0 t1, C0_1_IC /* read the IntControl register */ or t1, VS_VECTOR_MASK /* set the VS field for */ /* spacing between vectors */ ctc0 t1, C0_1_IC /* write the ICR */ li t1, IPL_DEFAULT_LO /* set all IPLs to level 15 */ ctc0 t1, C0_1_IPLLO li t1, IPL_DEFAULT_HI ctc0 t1, C0_1_IPLHI mfc0 t1, C0_CAUSE /* read the CAUSE register */ or t1, CAUSE_IV /* turn interrupt vectoring ON */ mtc0 t1, C0_CAUSE /* write the CAUSE register */ lw s7, FRAMER1(intVectorVecInit)(sp) /* restore s7 */ lw s6, FRAMER0(intVectorVecInit)(sp) /* restero s6 */ lw ra, FRAMERA(intVectorVecInit)(sp) /* restore ra */ addu sp, FRAMESZ(intVectorVecInit) j ra /* return */ .end intVectorVecInit/*********************************************************************** intVectorVec<0-14> - Instructions to load at the Rm7000 vectored interrupt* vectors** These instructions are copied to 0x80000200 + (VS * IPL), the vectored* interrupt vector by the startup routine intVectorVecInit. We must use the* assembler pseudo op .noat so the la instruction will not use the at* register and mess with process state. The .set noreorder takes instruction* reorder control away from the assembler, and puts it in our hands. We are* using load address and jump to register so that we may run vxWorks out of* prom (see j and jal instruction definitions).** WARNING:* DO NOT MODIFY THIS ROUTINE WITHOUT ALSO UPDATING THE CONSTANTS* AT THE TOP OF THIS FILE** NOMANUAL* void intVectorVec<0-14>()*/ .ent intVectorVec0 .set noatintVectorVec0: li k0, INTERRUPT_VECTOR_0 /* mark which vector */ la k1, intActiveIPL /* is calling the handler */ sw k0, (k1) la k0, intVectorStub j k0 /* jump to interrupt handler */intVecEnd0: .set at .end intVectorVec0 .data .align 4intVecSize0: .word intVecEnd0-intVectorVec0 .text/*********************************************************************** intVectorVec15 - Instructions to load at the Rm7000 interrupt * priority level (IPL) 15 vector** These instructions are copied to 0x80000200 + (VS * IPL_15), the vectored * interrupt address, by the startup routine intVectorVecInit. This routine is* unique to the rest of the IPLs because IPL15 is reserved for backwards* compatibility. It only calls intStub.** We must use the assembler pseudo op .noat so the la instruction will not* use the at register and mess with process state. We are using load * address and jump to register so that we may run vxWorks out of prom (see j,* and jal instruction definitions).** NOMANUAL* void intVectorVec15()*/ .ent intVectorVec15 .set noatintVectorVec15: lw k1, areWeNested /* grab areWeNested */ la k0, excIntStub j k0 /* jump to interrupt handler */intVecEnd15: .set at .end intVectorVec15 .data .align 4intVecSize15: .word intVecEnd15-intVectorVec15 .text
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -