📄 windalib.s
字号:
** saveIntContext (SH7750/SH7700)** 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.*/ .align _ALIGN_TEXT .type saveIntContext,@function /* r3: _intLockTaskSR */ /* r4: ReadyQHead */ /* r5: TaskIdCurrent */ /* r6: _readyQHead */ /* r7: _taskIdCurrent */saveIntContext: /* interrupts are still locked out, and not nested */ mov.l SI_KernelState,r0; mov #1,r1; mov.w SI_WINDTCB_MACL,r6; mov.l r1,@r0; add r7,r6 mov.l @sp+,r0; mov.l @sp+,r1; mov.l r0,@r6 /* save macl */ mov.l @sp+,r0; mov.l r1,@-r6 /* save mach */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r7 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r6 */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r5 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r4 */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r3 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r2 */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r1 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r0 */ mov.l @sp+,r1;/*spc*/ mov.l r0,@-r6 /* save pr */ mov.l @sp+,r0;/*ssr*/ add #80,r6 mov.l @(4,sp),sp;/*task'sp*/ mov.l r0,@r6 /* save ssr */ mov.l r1,@-r6 /* save spc */ /* update areWeNested */ stc vbr,r2; mov.l sp,@-r6 /* save sp */ mov.l @(ARE_WE_NESTED,r2),r1; mov.l SI_intUnlockSR,r0 rotr r1; mov.l @r0,r0 mov.l r1,@(ARE_WE_NESTED,r2); ldc r0,sr /* UNLOCK INTERRUPTS */ mov.l r14,@-r6 /* save r14 */ mov.l r13,@-r6 /* save r13 */ mov.l r12,@-r6 /* save r12 */ mov.l r11,@-r6; mov.l SI_Errno,r3; /* save r11 */ mov.l r10,@-r6; mov.l @r3,r1; /* save r10 */ mov.l r9, @-r6; mov #WIND_TCB_ERRNO,r0 /* save r9 */ mov.l r8, @-r6; extu.b r0,r0 /* save r8 */#ifndef PORTABLE bra _reschedule; mov.l r1,@(r0,r7) /* save errno */ /* r3: SI_Errno */ /* r4: ReadyQHead */ /* r5: TaskIdCurrent */ /* r6: (invalid) */ /* r7: _taskIdCurrent */#else /* PORTABLE */ mov.l SI_Reschedule,r6 jmp @r6; mov.l r1,@(r0,r7) /* save errno */ .align 2SI_Reschedule: .long _reschedule#endif /* PORTABLE */ .align 2SI_KernelState: .long _kernelStateSI_Errno: .long _errnoSI_intUnlockSR: .long _intUnlockSRSI_WINDTCB_MACL: .word WIND_TCB_MACL /* see regsSh.h */#elif (CPU==SH7600 || CPU==SH7000)/******************************************************************************** intExit - exit an interrupt service routine (SH7600/SH7000)** 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 interrupt 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.** SEE ALSO: intConnect(2)* void intExit ()* 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.*/ .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; /* save sr in r3 */ mov.l @r2,r1; stc sr,r3; add #-1,r1 /* if in kernel, rte */ 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; /* r2: _intLockTaskSR */ bf intRte /* if nested, just rte */ mov.l IX_AreWeNested,r1; mov.l IX_TaskIdCurrent,r5; mov.l @r1,r0; mov.l IX_ReadyQHead,r4; cmp/eq #1,r0 bf intRte; /* 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 intRte /* 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 saveIntContext /* r2: _intLockTaskSR, r4: ReadyQHead, r6: _readyQHead */ /* r3: saved sr, r5: TaskIdCurrent, r7: _taskIdCurrent */ .type intRte,@functionintRte: ldc r3,sr /* UNLOCK INTERRUPTS */ lds.l @sp+,macl lds.l @sp+,mach mov.l @sp+,r7 mov.l @sp+,r6 mov.l @sp+,r5 mov.l @sp+,r4 mov.l @sp+,r3 mov.l IX_AreWeNested,r1; ldc r2,sr /* LOCK INTERRUPTS */ mov.l @r1,r0; rotr r0#if (CPU==SH7000) mov.l r0,@r1 bf intRteNested#else bf.s intRteNested mov.l r0,@r1 /* update areWeNested */#endif mov.l @sp,sp /* return to task's stack */intRteNested: mov.l @sp+,r2 mov.l @sp+,r1 mov.l @sp+,r0 lds.l @sp+,pr rte; /* UNLOCK INTERRUPTS */ nop .align 2IX_IntCnt: .long _intCntIX_IntLockSR: .long _intLockTaskSRIX_ReadyQHead: .long _readyQHeadIX_TaskIdCurrent: .long _taskIdCurrentIX_KernelState: .long _kernelStateIX_AreWeNested: .long _areWeNestedIX_Errno: .long _errno#ifdef WV_INSTRUMENTATIONIX_EvtAction: .long _evtAction#endif/******************************************************************************** saveIntContext (SH7600/SH7000 version)** 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).** INTERNAL** [ task's stack ] [ interrupt stack ]** | |* +----------> |_______| +8* | | sr | +4* | sp -> |_ pc __| 0* | ^ | pr |* | ^ | r0 |* | ^ | r1 | vxIntStackBase -> |_______|* | ^ | r2 | <-------------------- |task'sp|* | | | ^ | r3 |* | | | ^ | r4 |* | | | ^ | r5 |* | | | ^ | r6 |* | | | ^ | r7 |* | | | ^ | mach |* | | | sp -> | macl |* | | | | |* |* | _________________* | WIND_TCB_SR 0x17c | sr | +80* | WIND_TCB_PC 0x178 | pc | +76* +----------- WIND_TCB_R15 0x174 | sp + 8 | +72* WIND_TCB_R14 0x170 | r14 | +68* WIND_TCB_R13 0x16c | r13 | +64* WIND_TCB_R12 0x168 | r12 | +60* WIND_TCB_R11 0x164 | r11 | +56* WIND_TCB_R10 0x160 | r10 | +52* WIND_TCB_R9 0x15c | r9 | +48* WIND_TCB_R8 0x158 | r8 | +44* r2 -> WIND_TCB_MACL 0x154 | macl | +40* WIND_TCB_MACH 0x150 | mach | +36* WIND_TCB_R7 0x14c | r7 | +32* WIND_TCB_R6 0x148 | r6 | +28* WIND_TCB_R5 0x144 | r5 | +24* WIND_TCB_R4 0x140 | r4 | +20* WIND_TCB_R3 0x13c | r3 | +16* WIND_TCB_R2 0x138 | r2 | +12* WIND_TCB_R1 0x134 | r1 | +8* WIND_TCB_R0 0x130 | r0 | +4* WIND_TCB_PR 0x12c | pr | +0* WIND_TCB_GBR 0x128 | |* WIND_TCB_VBR 0x124 | | (regsSh.h)* | |* WIND_TCB_REGS 0x124 |_______________| (taskLibP.h)* 0x120 |_____ sr ______|* 0x11c |_____ pc ______|* EXC_INFO 0x118 |_valid_|_vecNum| (excShLib.h)* | |* WIND_TCB_ERRNO | _errno |* | |* r7 -> WIND_TCB 0x0 |_______________| (taskLib.h)*/ .align _ALIGN_TEXT .type saveIntContext,@function /* r2: _intLockTaskSR */ /* r3: saved sr */ /* r4: ReadyQHead */ /* r5: TaskIdCurrent */ /* r6: _readyQHead */ /* r7: _taskIdCurrent */saveIntContext: /* interrupts are still locked out, and not nested */ mov.l SI_KernelState,r0; mov #1,r1; mov.w SI_WINDTCB_MACL,r6; mov.l r1,@r0; add r7,r6 ldc r3,sr /* UNLOCK INTERRUPTS */ mov.l @sp+,r0 mov.l @sp+,r1; mov.l r0,@r6 /* save macl */ mov.l @sp+,r0; mov.l r1,@-r6 /* save mach */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r7 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r6 */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r5 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r4 */ mov.l r0,@-r6 /* save r3 */ mov.l SI_AreWeNested,r1; ldc r2,sr /* LOCK INTERRUPTS */ mov.l @r1,r0; mov.l @sp,sp; /* return to task's stack */ rotr r0 mov.l r0,@r1 /* update areWeNested */ ldc r3,sr /* UNLOCK INTERRUPTS */ mov.l @sp+,r1; mov.l @sp+,r0; mov.l r1,@-r6 /* save r2 */ mov.l @sp+,r1; mov.l r0,@-r6 /* save r1 */ mov.l @sp+,r0; mov.l r1,@-r6 /* save r0 */ mov.l r0,@-r6 /* save pr */ xor r0,r0 ldc r0,sr /* UNLOCK INTERRUPTS */ mov.l @(4,sp),r1; add #80,r6 mov.l @sp,r0; mov.l r1,@r6 /* save sr */ mov.l r0,@-r6 /* save pc */ mov sp, r0 /* keep sp untouched */ add #8, r0 /* adjust sp to be saved in tcb */ mov.l r0, @-r6 /* save sp */ mov.l r14,@-r6 /* save r14 */ mov.l r13,@-r6 /* save r13 */ mov.l r12,@-r6 /* save r12 */ mov.l r11,@-r6; mov.l SI_Errno,r3; /* save r11 */ mov.l r10,@-r6; mov.l @r3,r1; /* save r10 */ mov.l r9, @-r6; mov #WIND_TCB_ERRNO,r0 /* save r9 */ mov.l r8, @-r6; extu.b r0,r0 /* save r8 */#ifndef PORTABLE bra _reschedule; mov.l r1,@(r0,r7) /* save errno */ /* r3: Errno */ /* r4: ReadyQHead */ /* r5: TaskIdCurrent */ /* r6: (invalid) */ /* r7: _taskIdCurrent */#else /* PORTABLE */ mov.l SI_Reschedule,r6 jmp @r6; mov.l r1,@(r0,r7) /* save errno */ .align 2SI_Reschedule: .long _reschedule#endif /* PORTABLE */ .align 2SI_KernelState: .long _kernelStateSI_AreWeNested: .long _areWeNestedSI_Errno: .long _errnoSI_WINDTCB_MACL: .word WIND_TCB_MACL /* TCB offset */#endif /* CPU==SH7600 || CPU==SH7000 */#ifdef WV_INSTRUMENTATION/******************************************************************************** noDispatchInstr - windview instrumentation: exit windExit with NO dispatch**/ .align _ALIGN_TEXT .type noDispatchInstr,@functionnoDispatchInstr: mov.l NDI_TaskIdCurrent,r1; mov.l r8,@-sp mov #WIND_TCB_PRIORITY,r0; mov.l r9,@-sp mov.l @r1,r8; /* r8: taskID */ sts.l pr,@-sp mov.l @(r0,r8),r9; /* r9: priority */ /* check if we need to log this event */ mov.l NDI_WvEvtClass,r1; mov.l NDI_WV_CLASS_1_ON,r3; mov.l @r1,r0; and r3,r0 cmp/eq r3,r0 bf noDispatchCheckTrg /* Here we try to determine if the task is running at an * inherited priority, if so a different event is generated. */ mov #WIND_TCB_PRI_NORMAL,r0 mov.l @(r0,r8),r1; mov #EVENT_WIND_EXIT_NODISPATCH,r4 cmp/ge r1,r9 /* normalPriority <= priority */ bt noDispatchEvtLog /* no inheritance */ mov #EVENT_WIND_EXIT_NODISPATCH_PI,r4noDispatchEvtLog: /* r4: event ID */ mov.l NDI_EvtLogTSched,r1; mov.l @r1,r0; mov r9,r6 /* r4 r5 r6 */ jsr @r0; mov r8,r5 /* evtLogTSched (eventID,taskID,pri) */noDispatchCheckTrg: mov.l NDI_TrgEvtClass,r1; mov.l NDI_TRG_CLASS_1_ON,r3; mov.l @r1,r0; mov #0,r2 /* r2: NULL */ and r3,r0 cmp/eq r3,r0 bf noDispatchInstDone mov #WIND_TCB_PRI_NORMAL,r0 mov.l @(r0,r8),r1; mov #EVENT_WIND_EXIT_NODISPATCH,r4 cmp/ge r1,r9 /* normalPriority <= priority */ bt noDispatchEvalTrg /* no inheritance */ mov #EVENT_WIND_EXIT_NODISPATCH_PI,r4noDispatchEvalTrg: /* r4: event ID */ /* r4 r5 r6 r7 +0 +4 +8 +12 */ /* trgCheck (eventID,index,taskID,priority, 0, 0, 0, 0) */ mov.l r2,@-sp; mov.l r2,@-sp mov.l r2,@-sp; mov.l r2,@-sp mov.l NDI_TrgCheck,r1; mov r9,r7 mov.l @r1,r0; mov r8,r6 jsr @r0; mov #TRG_CLASS1_INDEX,r5 add #16,sp /* pop params */noDispatchInstDone: lds.l @sp+,pr mov.l @sp+,r9 rts; mov.l @sp+,r8 .align 2NDI_TaskIdCurrent: .long _taskIdCurrentNDI_WvEvtClass: .long _wvEvtClassNDI_WV_CLASS_1_ON: .long WV_CLASS_1_ONNDI_EvtLogTSched: .long __func_evtLogTSchedNDI_TrgEvtClass: .long _trgEvtClassNDI_TRG_CLASS_1_ON: .long TRG_CLASS_1_ONNDI_TrgCheck: .long __func_trgCheck#ifndef PORTABLE/******************************************************************************** dispatchInstr - windview instrumentation: exit windExit with dispatch**/ .align _ALIGN_TEXT .type dispatchInstr,@functiondispatchInstr: mov.l DII_TaskIdCurrent,r12; mov.l r0,@-sp mov #WIND_TCB_PRIORITY,r0; mov.l r1,@-sp mov.l @r12,r11; /* r11: task ID */ mov.l r2,@-sp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -