📄 windalib.s
字号:
lw k0, WIND_TCB_PC(t0) /* restore PC */ LW sp, WIND_TCB_SP(t0) /* restore task stack pointer */ .set noat LW AT, WIND_TCB_AT(t0) LW t0, WIND_TCB_T0(t0) .set noreorder#ifdef _WRS_R3K_EXC_SUPPORT j k0 /* context switch */ mtc0 k1, C0_SR /* restore status register */#else mtc0 k0, C0_EPC ori k1, SR_EXL mtc0 k1, C0_SR HAZARD_CP_WRITE eret#endif .set reorder .set at .end windLoadContext #endif /* PORTABLE *//********************************************************************************* intEnt - enter an interrupt service routine** This routine has been inlined in the common interrupt stub for* performance reasons on the R3k.** INTERNAL* On the R3K only three instructions are* needed therefore this routine is never called.* Also intCnt is used to discover if interrupts are nested.* .CS** lw k1, intCnt /* grab contents of intCnt* ...* addu k1, 1 /* increment intCnt* sw k1, intCnt /* update value* .CE** SEE ALSO: excIntStub()*/ /* xxx *//********************************************************************************* intExit - exit an interrupt service routine** Check the kernel ready queue to determine if resheduling is necessary. If* no higher priority task has been readied, and no kernel work has been queued,* then we return to the interrupted task.** If rescheduling is necessary, the context of the interrupted task is saved* in its associated TCB with the PC, SR and SP retrieved from the exception* frame on the master stack.** This routine must be branched to when exiting an interrupt service routine.* This normally happens automatically, from the stub built by intConnect (2).** This routine can NEVER be called from C.** It can only be jumped to because a jsr will push a return address on the* stack.** INTERNAL* This routine must preserve all registers up until the context is saved,* so any registers that are used to check the queues must first be saved on* the stack.** At the call to reschedule the value of taskIdCurrent must be in t0.** Restoration of errno has been moved into the common interrupt stub* for performance reasons on the R3k.** SEE ALSO: intConnect(2)* void intExit ()*/ .ent intExitintExit: /* we are on the interrupt stack here */ SETFRAME(intExit,3) subu sp, FRAMESZ(intExit) /* get some work space */ SW t0, FRAMER0(intExit)(sp) /* store registers which are used */ SW t1, FRAMER1(intExit)(sp) SW t2, FRAMER2(intExit)(sp)#ifdef WV_INSTRUMENTATION /* * windview instrumentation - BEGIN * log event if work has been done in the interrupt handler. */ lw t0, evtAction /* is WV/triggering on? */ beqz t0, noIntExit lw t0, wvEvtClass /* is WV instrumentation on? */ li t4, WV_CLASS_1_ON and t0, t0, t4 bne t4, t0, trgCheckIntExit /* * don't bother to save registers - they are all in * the exception frame */ lw t2, workQIsEmpty /* work in work queue? */ li a0, EVENT_INT_EXIT /* event id */ bnez t2, intExitEvent li a0, EVENT_INT_EXIT_K /* event id */intExitEvent: lw t1, _func_evtLogT0 jal t1 /* call evtLogT0 routine */trgCheckIntExit: lw t0, trgEvtClass li t4, TRG_CLASS_1_ON and t0, t0, t4 bne t4, t0, intExitBufOverflow lw t2, workQIsEmpty /* work in work queue? */ li a0, EVENT_INT_EXIT /* event id */ bnez t2, trgIntExitEvent li a0, EVENT_INT_EXIT_K /* event id */trgIntExitEvent: li a1, TRG_CLASS1_INDEX li a2, 0x0 lw t1, _func_trgCheck jal t1 /* call trgCheck routine */intExitBufOverflow: /* restore all registers */ LW t0,FRAMESZ(intExit)+E_STK_HI(sp) /* grab entry lo reg */ LW t1,FRAMESZ(intExit)+E_STK_LO(sp) /* grab entry hi reg */ mthi t0 /* restore entry hi reg */ mtlo t1 /* restore entry hi reg */0: LW v0,FRAMESZ(intExit)+E_STK_V0(sp) /* restore func ret 0 */ LW v1,FRAMESZ(intExit)+E_STK_V1(sp) /* restore func ret 1 */ LW a0,FRAMESZ(intExit)+E_STK_A0(sp) /* restore passed param 0 */ LW a1,FRAMESZ(intExit)+E_STK_A1(sp) /* restore passed param 1 */ LW a2,FRAMESZ(intExit)+E_STK_A2(sp) /* restore passed param 2 */ LW a3,FRAMESZ(intExit)+E_STK_A3(sp) /* restore passed param 3 */ /* restore temp reg 0 (below) */ /* restore temp reg 1 (below) */ /* restore temp reg 2 (below) */ LW t3,FRAMESZ(intExit)+E_STK_T3(sp) /* restore temp reg 3 */ LW t4,FRAMESZ(intExit)+E_STK_T4(sp) /* restore temp reg 4 */ LW t5,FRAMESZ(intExit)+E_STK_T5(sp) /* restore temp reg 5 */ LW t6,FRAMESZ(intExit)+E_STK_T6(sp) /* restore temp reg 6 */ LW t7,FRAMESZ(intExit)+E_STK_T7(sp) /* restore temp reg 7 */ LW t8,FRAMESZ(intExit)+E_STK_T8(sp) /* restore temp reg 8 */ LW ra,FRAMESZ(intExit)+E_STK_RA(sp) /* restore return addr */ LW t9,FRAMESZ(intExit)+E_STK_T9(sp) /* restore temp reg 9 */noIntExit: /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */ lw t0, intCnt subu t0, 1 sw t0, intCnt /* decrement intCnt */ lw t1, areWeNested /* load nested boolean */ subu t1, 1 /* decrement */ sw t1, areWeNested /* store nested boolean */ lw t2, kernelState /* if kernelState == TRUE */ bne t2, zero, intRte /* then just clean up and rte */ bne t1, zero, intRte /* if nested int then just rte */ lw t0, taskIdCurrent /* put current task in t0 */ lw t2, readyQHead /* compare to highest ready task */ beq t0, t2, intRte /* if same then don't reschedule */ lw t1, WIND_TCB_LOCK_CNT(t0) /* is task preemption allowed */ beq zero, t1, saveIntContext /* if yes, then save context */ lw t1, WIND_TCB_STATUS(t0) /* is task ready to run */ bne zero, t1, saveIntContext /* if no, then save context */intRte: LW t0, FRAMER0(intExit)(sp) /* restore registers used locally */ LW t1, FRAMER1(intExit)(sp) LW t2, FRAMER2(intExit)(sp) addu sp, FRAMESZ(intExit) /* recover stack work space */ .set noreorder .set noat lw k0, E_STK_EPC(sp) /* get the exception program counter */ LW AT, E_STK_AT(sp) /* restore AT reg */ LW sp, E_STK_SP(sp) /* restore the task stack pointer, no need to pop temp stack now */#ifdef _WRS_R3K_EXC_SUPPORT j k0 /* return to previous context */ rfe /* RESTORE INTERRUPTS */#else HAZARD_VR5400 mtc0 k0,C0_EPC /* return to previous context */ HAZARD_ERET eret /* RESTORE INTERRUPTS */#endif .set at .set reorder/* We are here if we have decided that rescheduling is a distinct possibility. * The context must be gathered and stored in the current task's tcb. * The stored stack pointers must be modified to clean up the stacks (ISP, MSP). */ saveIntContext: /* interrupts are still locked out */ li t1, 1 /* kernelState = TRUE; */ sw t1, kernelState lw k0, taskIdCurrent /* tcb to be fixed up */ lw t0, errno sw t0, WIND_TCB_ERRNO(k0) /* save errno */ LW t0, FRAMER0(intExit)(sp) /* restore working registers */ LW t1, FRAMER1(intExit)(sp) LW t2, FRAMER2(intExit)(sp) SW t0, WIND_TCB_T0(k0) /* and save in TCB */ SW t1, WIND_TCB_T1(k0) SW t2, WIND_TCB_T2(k0) move t0, k0 /* use t0 as taskIdCurrent */ addu sp, FRAMESZ(intExit) /* recover stack work space */ lw t2, E_STK_EPC(sp) /* get the exception PC */ LW t1, E_STK_SP(sp) /* get the process SP */ sw t2, WIND_TCB_PC(t0) /* store exception PC in TCB */ SW t1, WIND_TCB_SP(t0) /* store regs in tcb */ .set noat LW AT, E_STK_AT(sp) SW AT, WIND_TCB_AT(t0) .set at mfc0 k1, C0_SR HAZARD_CP_READ#ifdef _WRS_R3K_EXC_SUPPORT /* modify the status register ready to store in the task TCB */ and k0, k1, SR_KUMSK and k1, ~SR_KUMSK srl k0, 2 or k1, k0#else and k1,~SR_EXL#endif sw k1, WIND_TCB_SR(t0) /* store sr in TCB */ move sp, t1 /* work off task stack */ mtc0 k1, C0_SR /* UNLOCK INTERRUPTS *//** A window of vulnerabilty opens up here on the R3000. We need to* have epc,sp,and AT restored and have begun working off the task stack * by now. This is because intCnt == 0, and if we get interrupted* excIntStub will reset and muck the stack.*/ /* store registers starting */ SW t3, WIND_TCB_T3(t0) /* with remaining temp */ SW t4, WIND_TCB_T4(t0) /* registers so work */ SW t5, WIND_TCB_T5(t0) /* are available */ SW t6, WIND_TCB_T6(t0) SW t7, WIND_TCB_T7(t0) SW a0, WIND_TCB_A0(t0) /* save remaining registers */ SW a1, WIND_TCB_A1(t0) /* in TCB */ SW a2, WIND_TCB_A2(t0) SW a3, WIND_TCB_A3(t0) SW v0, WIND_TCB_V0(t0) SW v1, WIND_TCB_V1(t0) mflo v0 mfhi v1 SW v0, WIND_TCB_LO(t0) SW v1, WIND_TCB_HI(t0)0: SW s0, WIND_TCB_S0(t0) SW s1, WIND_TCB_S1(t0) SW s2, WIND_TCB_S2(t0) SW s3, WIND_TCB_S3(t0) SW s4, WIND_TCB_S4(t0) SW s5, WIND_TCB_S5(t0) SW s6, WIND_TCB_S6(t0) SW s7, WIND_TCB_S7(t0) SW t8, WIND_TCB_T8(t0) SW t9, WIND_TCB_T9(t0) SW s8, WIND_TCB_S8(t0) SW ra, WIND_TCB_RA(t0) j reschedule /* goto rescheduler */ .end intExit/********************************************************************************* vxTaskEntry - task startup code following spawn** This hunk of code is the initial entry point to every task created via* the "spawn" routines. taskCreate(2) has put the true entry point of the* task into the tcb extension before creating the task,* and then pushed exactly ten arguments (although the task may use* fewer) onto the stack. This code picks up the real entry point and calls it.* Upon return, the 10 task args are popped, and the result of the main* routine is passed to "exit" which terminates the task.* This way of doing things has several purposes. First a task is easily* "restartable" via the routine taskRestart(2) since the real* entry point is available in the tcb extension. Second, the call to the main* routine is a normal call including the usual stack clean-up afterwards,* which means that debugging stack trace facilities will handle the call of* the main routine properly. ** NOMANUAL* void vxTaskEntry () */ .ent vxTaskEntryvxTaskEntry: /* stack frame for 10 parameters created in taskLib */ lw t0, taskIdCurrent /* get current task id */ lw t1, WIND_TCB_ENTRY(t0) /* entry point for task is in tcb */ jal t1 /* call main routine */ move a0, v0 /* pass result to exit */ jal exit /* gone for good */ .end vxTaskEntry/********************************************************************************* windIntStackSet - set the interrupt stack pointer** This routine sets the interrupt stack pointer to the specified address.* It is only valid on architectures with an interrupt stack pointer.** NOMANUAL* void windIntStackSet (pBotStack)* char *pBotStack; /* pointer to bottom of interrupt stack **/ .ent windIntStackSetwindIntStackSet: j ra /* just return */ .end windIntStackSet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -