📄 windalib.s
字号:
* THEY ARE USED IN DISPATCH CODE WHILE SR IS 0X400000F0.** NOTE: Omitted _ALIGN_TEXT since this routine will be copied to vbr + 0x600.*/#if (SH7700_VEC_TABLE_OFFSET != 0x800)#error SH7700_VEC_TABLE_OFFSET != 0x800, check ivSh.h and adjust intStub.#endif#if (SH7700_INT_PRIO_TABLE_OFFSET != 0xc00)#error SH7700_INT_PRIO_TABLE_OFFSET != 0xc00, check ivSh.h and adjust intStub.#endif .align 2 .type _intStub,@function_intStub: stc vbr,r3; mov.l @(INT_EVT_ADRS,r3),r1 mov.l @(ARE_WE_NESTED,r3),r0; mov.l @r1,r2 /* r2: INTEVT */ rotl r0 bf.s intStubSaveRegs mov.l r0,@(ARE_WE_NESTED,r3) /* update areWeNested */#if (CPU==SH7750) mov.l @(INT_STACK_BASE,r3),sp /* switch to interrupt stack */ .word 0x4f32 /* stc.l sgr,@-sp : save task's sp */#else /* in default of sgr */ mov.l @(INT_STACK_BASE,r3),r0 mov.l sp,@-r0 /* save task's stack pointer */ mov r0,sp /* switch to interrupt stack */#endifintStubSaveRegs: mov.l r2,@-sp; tst r2,r2 stc.l ssr,@-sp; bt intStubNullEvt stc.l spc,@-sp; mov #-3,r1 /* load new sr to ssr */ /* load dispatch address to spc */ mov #0xc,r0; shld r1,r2 /* r2: 0, 4, 8, ... */ shll8 r0; /* r0: 0xc00 */ add r3,r0 mov.l @(r0,r2),r1; mov #0x8,r0 shll8 r0 /* r0: 0x800 */ tst r1,r1; add r3,r0 bt.s intStubStayBlocked; mov.l @(r0,r2),r0 ldc r1,ssr; ldc r0,spc rte; nopintStubStayBlocked: jmp @r0; nopintStubNullEvt: mov.l @(ARE_WE_NESTED,r3),r0; mov.l @(NULL_EVT_CNT,r3),r1 rotr r0; add #1,r1 mov.l r0,@(ARE_WE_NESTED,r3); mov.l r1,@(NULL_EVT_CNT,r3) bf intStubNullEvtNested rte; mov.l @(8,sp),spintStubNullEvtNested: rte; add #8,sp /* skip ssr/INTEVT on stack */intStubEnd: .align 2 .type _intStubSize,@object .size _intStubSize,4_intStubSize: .long intStubEnd - _intStub/******************************************************************************** intEnt - enter an interrupt service routine (SH7750/SH7700)** intEnt must be called at the entrance of an interrupt service routine.* This normally happens automatically, from the stub built by intConnect (2).* This routine should NEVER be called from C.** SEE ALSO: intConnect(2)* void intEnt ()*/ .align _ALIGN_TEXT .type _intEnt,@function_intEnt: mov.l r2,@-sp mov.l r3,@-sp mov.l r4,@-sp; mov.l IE_IntCnt,r0; mov.l r5,@-sp; mov.l @r0, r1; mov.l r6,@-sp; add #1, r1 mov.l r7,@-sp; mov.l IE_Errno, r2; sts.l mach,@-sp; mov.l @r2, r3; sts.l macl,@-sp; mov.l r3, @-sp /* push errno */ mov.l r1, @r0 /* bump count */#ifdef WV_INSTRUMENTATION mov.l IE_EvtAction,r3; mov.l @r3,r2; tst r2,r2 bf intEntInstr /* let him return */#endif rts; nop .align 2IE_IntCnt: .long _intCntIE_Errno: .long _errno#ifdef WV_INSTRUMENTATIONIE_EvtAction: .long _evtAction#endif#elif (CPU==SH7600 || CPU==SH7000)/******************************************************************************** intEnt - enter an interrupt service routine (SH7600/SH7000)** intEnt must be called at the entrance of an interrupt service routine.* This normally happens automatically, from the stub built by intConnect (2).* This routine should NEVER be called from C.** SEE ALSO: intConnect(2)* void intEnt ()* INTERNAL* [ task's stack ] [ interrupt stack ]** | | | |* |_______| |_______|* | sr | | sr |* |_ pc __| |_ pc __|* | pr | | pr |* | r0 | | r0 |* | r1 | vxIntStackBase -> |_______| | r1 |* | r2 | <-------------------- |task'sp| | r2 |* | | | r3 | | r3 |* | | | r4 | | r4 |* | | | r5 | | r5 |* | | | r6 | | r6 |* | | | r7 | | r7 |* | | | mach | | mach |* | | | macl | | macl |* | | sp -> | errno | | errno |* | | | | | |** (task) --------------------> (interrupt) --> (interrupt)** areWeNested: 0x80000000 -------------------> 0x00000001 ---> 0x00000002*/ .align _ALIGN_TEXT .type _intEnt,@function_intEnt: mov.l r2, @-sp; mov.l IE_IntLockSR,r2 mov.l IE_AreWeNested,r1; mov.l @r2,r0 stc sr,r2 /* save current sr */ /* update areWeNested */ ldc r0,sr /* LOCK INTERRUPTS */ mov.l @r1,r0 rotl r0#if (CPU==SH7000) mov.l r0,@r1 bf intEntNested#else bf.s intEntNested mov.l r0,@r1#endif mov.l IE_VxIntStackBase,r1; mov.l @r1,r0; mov.l sp,@-r0 /* save task's sp */ mov r0,sp /* switch to interrupt stack*/intEntNested: ldc r2,sr /* UNLOCK INTERRUPTS */ mov.l r3, @-sp mov.l r4, @-sp; mov.l IE_IntCnt,r0; mov.l r5, @-sp; mov.l @r0, r1; mov.l r6, @-sp; add #1, r1 mov.l r7, @-sp; mov.l IE_Errno, r2; sts.l mach,@-sp; mov.l @r2, r3; sts.l macl,@-sp; mov.l r3, @-sp /* save errno */ mov.l r1, @r0 /* bump count */#ifdef WV_INSTRUMENTATION mov.l IE_EvtAction,r3; mov.l @r3,r2; tst r2,r2 bf intEntInstr /* let him return */#endif rts; nop .align 2IE_IntLockSR: .long _intLockTaskSRIE_AreWeNested: .long _areWeNestedIE_VxIntStackBase: .long _vxIntStackBase /* kernelLib.c */IE_IntCnt: .long _intCntIE_Errno: .long _errno#ifdef WV_INSTRUMENTATIONIE_EvtAction: .long _evtAction#endif#endif /* CPU==SH7600 || CPU==SH7000 */#ifdef WV_INSTRUMENTATION/******************************************************************************** intEntInstr - windview instrumentation: enter an interrupt handler**/ .align _ALIGN_TEXT .type intEntInstr,@functionintEntInstr: /* LOCK INTERRUPTS */ mov.l IEI_IntLockSR,r1; mov.l r8,@-sp mov.l @r1,r0; stc.l sr,@-sp ldc r0,sr; sts.l pr,@-sp /* We're going to need the event ID, * so get it now. */ mov.l @(4,sp),r0; /* r0: sr */ mov #MIN_INT_ID,r8 shlr2 r0 shlr2 r0 and #0x0f,r0 /* r0: interrupt level */ add r0,r8 /* r8: event ID */ /* check if we need to log this event */ mov.l IEI_WvEvtClass,r1; mov.l IEI_WV_CLASS_1_ON,r3; mov.l @r1,r0; and r3,r0 cmp/eq r3,r0 bf intEntCheckTrg mov.l IEI_EvtLogT0,r1; mov.l @r1,r0; jsr @r0; /* evtLogT0 (eventID) */ mov r8,r4intEntCheckTrg: /* check if we need to evaluate trigger for this event */ mov.l IEI_TrgEvtClass,r1; mov.l IEI_TRG_CLASS_1_ON,r3; mov.l @r1,r0; mov #0,r7 /* r7: NULL */ and r3,r0 cmp/eq r3,r0 bf intEntInstDone /* r4 r5 r6 r7 +0 +4 +8 +12 */ /* trgCheck (eventID,index, 0, 0, 0, 0, 0, 0) */ mov.l r7,@-sp; mov.l r7,@-sp mov.l r7,@-sp; mov.l r7,@-sp mov.l IEI_TrgCheck,r1; mov r7,r6 mov.l @r1,r0; mov #TRG_CLASS1_INDEX,r5 jsr @r0; mov r8,r4 add #16,sp /* pop params */intEntInstDone: lds.l @sp+,pr ldc.l @sp+,sr /* UNLOCK INTERRUPT */ rts; mov.l @sp+,r8 .align 2IEI_IntLockSR: .long _intLockTaskSRIEI_WvEvtClass: .long _wvEvtClassIEI_WV_CLASS_1_ON: .long WV_CLASS_1_ONIEI_EvtLogT0: .long __func_evtLogT0IEI_TrgEvtClass: .long _trgEvtClassIEI_TRG_CLASS_1_ON: .long TRG_CLASS_1_ON IEI_TrgCheck: .long __func_trgCheck/******************************************************************************** intExitInstr - windview instrumentation: exit an interrupt handler**/ .align _ALIGN_TEXT .type intExitInstr,@functionintExitInstr: /* windview instrumentation - BEGIN * log event if work has been done in the interrupt handler. */ /* LOCK INTERRUPTS */ mov.l IXI_IntLockSR,r1; mov.l r8,@-sp mov.l @r1,r0; stc.l sr,@-sp ldc r0,sr; mov.l IXI_WorkQIsEmpty,r1; sts.l pr,@-sp mov.l @r1,r0; mov #EVENT_INT_EXIT,r8 tst r0,r0 bf intExitEvent /* workQ is empty */ mov #EVENT_INT_EXIT_K,r8intExitEvent: /* r8: event ID */ /* check if we need to log this event */ mov.l IXI_WvEvtClass,r1; mov.l IXI_WV_CLASS_1_ON,r3; mov.l @r1,r0; and r3,r0 cmp/eq r3,r0 bf intExitCheckTrg mov.l IXI_EvtLogT0,r1; mov.l @r1,r0; jsr @r0; /* evtLogT0 (eventID) */ mov r8,r4 intExitCheckTrg: /* check if we need to evaluate trigger for this event */ mov.l IXI_TrgEvtClass,r1; mov.l IXI_TRG_CLASS_1_ON,r3; mov.l @r1,r0; mov #0,r7 /* r7: NULL */ and r3,r0 cmp/eq r3,r0 bf intExitInstDone /* r4 r5 r6 r7 +0 +4 +8 +12 */ /* trgCheck (eventID,index, 0, 0, 0, 0, 0, 0) */ mov.l r7,@-sp; mov.l r7,@-sp mov.l r7,@-sp; mov.l r7,@-sp mov.l IXI_TrgCheck,r1; mov r7,r6 mov.l @r1,r0; mov #TRG_CLASS1_INDEX,r5 jsr @r0; mov r8,r4 add #16,sp /* pop params */intExitInstDone: lds.l @sp+,pr ldc.l @sp+,sr /* UNLOCK INTERRUPT */ bra intExitNoInstr; mov.l @sp+,r8 .align 2IXI_IntLockSR: .long _intLockTaskSRIXI_WorkQIsEmpty: .long _workQIsEmptyIXI_WvEvtClass: .long _wvEvtClassIXI_WV_CLASS_1_ON: .long WV_CLASS_1_ON /* eventP.h */IXI_EvtLogT0: .long __func_evtLogT0IXI_TrgEvtClass: .long _trgEvtClassIXI_TRG_CLASS_1_ON: .long TRG_CLASS_1_ON /* eventP.h */IXI_TrgCheck: .long __func_trgCheck#endif /* WV_INSTRUMENTATION */#if (CPU==SH7750 || CPU==SH7700)/******************************************************************************** intExit - exit an interrupt service routine (SH7750/SH7700)**/ .align _ALIGN_TEXT .type _intExit,@function /* r1: _errno (poped @intConnectCode) */_intExit: /* restore errno */ mov.l IX_Errno,r0; mov.l r1,@r0#ifdef WV_INSTRUMENTATION mov.l IX_EvtAction,r3; mov.l @r3,r2; tst r2,r2 bf intExitInstr /* ==> intExitInstr */intExitNoInstr: /* <== intExitInstr */#endif /* decrement intCnt */ mov.l IX_IntCnt,r2; mov.l @r2,r1; /* if in kernel, rte */ add #-1,r1 mov.l IX_KernelState,r0; mov.l r1,@r2 mov.l @r0,r1; mov.l IX_IntLockSR,r0; tst r1,r1; mov.l @r0,r2; bf intExitRestoreRegs /* if nested, just rte */ stc vbr,r1; mov.l IX_TaskIdCurrent,r5; mov.l @(ARE_WE_NESTED,r1),r0; mov.l IX_ReadyQHead,r4; cmp/eq #1,r0 bf intExitRestoreRegs /* LOCK INTERRUPTS */ /* if r7 is highest, don't reschedule */ ldc r2,sr; mov.l @r5,r7; mov.l @r4,r6; cmp/eq r7,r6 bt intExitRestoreRegs /* preemption locked? */ mov #WIND_TCB_LOCK_CNT,r0 /* is current task ready to run? */ mov.l @(r0,r7),r1; mov #WIND_TCB_STATUS,r0 tst r1,r1; mov.l @(r0,r7),r1; bt saveIntContext; tst r1,r1 /* WIND_READY(0x00)? */ bf saveIntContextintExitRestoreRegs: /* MD=1, RB=0, BL=0, IM=? */ lds.l @sp+,macl lds.l @sp+,mach mov.l IX_IntBlockSR,r0; mov.l @sp+,r7 mov.l @r0,r0; mov.l @sp+,r6 mov.l @sp+,r5 stc vbr,r1; mov.l @sp+,r4 add #INT_EXIT_STUB,r1; mov.l @sp+,r3 jmp @r1; mov.l @sp+,r2 .align 2IX_IntLockSR: .long _intLockTaskSRIX_TaskIdCurrent: .long _taskIdCurrentIX_ReadyQHead: .long _readyQHeadIX_Errno: .long _errnoIX_IntCnt: .long _intCntIX_KernelState: .long _kernelStateIX_IntBlockSR: .long _intBlockSR#ifdef WV_INSTRUMENTATIONIX_EvtAction: .long _evtAction#endif/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -