📄 windalib.s
字号:
movel _trgEvtClass,d2 /* Load event class */ andl #TRG_CLASS_1_ON,d2 /* Examine these bits */ cmpl #TRG_CLASS_1_ON,d2 jne intEntInstDone /* Jump if not set */ /* Evaluate triggers */ /* moveml a1/a6,a7@- save regs */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ movel #TRG_CLASS1_INDEX,a7@- movel d1,a7@- /* push event ID onto int stack */ movel __func_trgCheck,a0 /* Call log fn */ jsr a0@ addl #32,a7 /* Pop params */ /* moveml a7@+,a1/a6 restore regs */intEntInstDone: movew a7@+,sr moveml a7@+,d0-d2/a0-a6 /* restore regs */noIntEnt: /* windview instrumentation - END */#endif rts/********************************************************************************* 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.** 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.** At the call to reschedule the value of taskIdCurrent must be in a0.*/#if (CPU == MC68020 || CPU == MC68040 || CPU == MC68060 || CPU == MC68LC040)_intExit: movel a7@+,_errno /* restore errno */ movel a0,a7@- /* push a0 onto interrupt stack */#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * enter an interrupt handler. * * ALL registers must be saved. */ tstl _evtAction /* intEnt instrumentation */ jeq noIntExit moveml d0-d2/a0-a6,a7@- /* save regs */ movew sr,a7@- /* save sr */ movew _intLockIntSR,sr /* LOCK INTERRUPTS */ /* * We're going to need the event ID and timestamp, * so get them now. */ tstl _workQIsEmpty /* work in work queue? */ jne intExitEvent movel #EVENT_INT_EXIT_K,d1 /* event ID is now in d1 */ jmp intExitContintExitEvent: movel #EVENT_INT_EXIT,d1 /* event ID is now in d1 */intExitCont: /* Check if we need to log this event */ movel _wvEvtClass,d2 /* Load event class */ andl #WV_CLASS_1_ON,d2 /* Examine these bits */ cmpl #WV_CLASS_1_ON,d2 jne intExitCheckTrg /* Jump if not set */ /* Log event */ movel d1,a7@- /* push event ID onto int stack */ movel __func_evtLogT0,a0 /* Call log fn */ jsr a0@ addl #0x4,a7 /* Pop params */intExitCheckTrg: /* Check if we need to evaluate triggers for this event */ movel _trgEvtClass,d2 /* Load event class */ andl #TRG_CLASS_1_ON,d2 /* Examine these bits */ cmpl #TRG_CLASS_1_ON,d2 jne intExitInstDone /* Jump if not set */ /* Evaluate triggers */ /* moveml a1/a6,a7@- save regs */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ movel #TRG_CLASS1_INDEX,a7@- movel d1,a7@- /* push event ID onto int stack */ movel __func_trgCheck,a0 jsr a0@ addl #32,a7 /* Pop params */ /* moveml a7@+,a1/a6 restore regs */intExitInstDone: movew a7@+,sr moveml a7@+,d0-d2/a0-a6 /* restore regs */noIntExit: /* windview instrumentation - END */#endif subl #1,_intCnt /* decrement intCnt */ tstl _kernelState /* if kernelState == TRUE then */ jne intRte /* just clean up and rte */ btst #4,a7@(4) /* if M bit is clear, then we were in */ jeq intRte /* in an ISR so just clean up/rte */ movew _intLockIntSR,sr /* LOCK INTERRUPTS */ movel _taskIdCurrent,a0 /* put current task in a0 */ cmpl _readyQHead,a0 /* compare to highest ready task */ jeq intRte /* if same then don't reschedule */ tstl a0@(WIND_TCB_LOCK_CNT) /* is task preemption allowed */ jeq saveIntContext /* if yes, then save context */ tstl a0@(WIND_TCB_STATUS) /* is task ready to run */ jne saveIntContext /* if no, then save context */intRte: movel a7@+,a0 /* restore a0 */ rte /* UNLOCK INTERRUPTS *//* 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 */ movel #1,_kernelState /* kernelState = TRUE; */ movel _taskIdCurrent,a0 /* tcb to be fixed up */ movel a7@+,a0@(WIND_TCB_AREGS) /* store a0 in tcb */#if (CPU != MC68060) movel _vxIntStackBase,a7 /* fix up isp */#endif /* (CPU != MC68060) */ movew #0x3000,sr /* UNLOCK INTS, switch to msp */ /* interrupts unlocked and using master stack*/ movew a7@,a0@(WIND_TCB_SR) /* save sr in tcb */ movel a7@(2),a0@(WIND_TCB_PC) /* save pc in tcb */ movew a7@(6),a0@(WIND_TCB_FOROFF) /* save format/offset */ moveml d0-d7,a0@(WIND_TCB_DREGS) /* d0-d7 */ moveml a1-a7,a0@(WIND_TCB_AREGS4) /* a1-a7 */ addl #8,a0@(WIND_TCB_SSP) /* adj master stack ptr */ movel _errno,a0@(WIND_TCB_ERRNO) /* save errno */ jra _reschedule /* goto rescheduler */#endif /* (CPU==MC68020 || CPU==MC68040 || CPU==MC68060 || CPU==MC68LC040) */#if (CPU == MC68000 || CPU==MC68010 || CPU==CPU32)_intExit: movel a7@+,_errno /* restore errno */ movel d0,a7@- /* push d0 onto interrupt stack */ movel a0,a7@- /* push a0 onto interrupt stack */#ifdef WV_INSTRUMENTATION /* windview instrumentation - BEGIN * enter an interrupt handler. * * ALL registers must be saved. */ tstl _evtAction /* intEnt instrumentation */ jeq noIntExit moveml d0-d2/a0,a7@- /* save regs */ movew sr,a7@- /* save sr */ movew _intLockIntSR,sr /* LOCK INTERRUPTS */ /* * We're going to need the event ID and timestamp, * so get them now. */ tstl _workQIsEmpty /* work in work queue? */ jne intExitEvent movel #EVENT_INT_EXIT_K,d1 /* event ID is now in d1 */ jmp intExitContintExitEvent: movel #EVENT_INT_EXIT,d1 /* event ID is now in d1 */intExitCont: /* Check if we need to log this event */ movel _wvEvtClass,d2 /* Load event class */ andl #WV_CLASS_1_ON,d2 /* Examine these bits */ cmpl #WV_CLASS_1_ON,d2 jne intExitCheckTrg /* Jump if not set */ /* Log event */ movel d1,a7@- /* push event ID onto int stack */ movel __func_evtLogT0,a0 /* Call log fn */ jsr a0@ addl #4,a7 /* Pop params */intExitCheckTrg: /* Check if we need to evaluate triggers for this event */ movel _trgEvtClass,d2 /* Load event class */ andl #TRG_CLASS_1_ON,d2 /* Examine these bits */ cmpl #TRG_CLASS_1_ON,d2 jne intExitInstDone /* Jump if not set */ /* Evaluate triggers */ moveml a1/a6,a7@- /* save regs */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ clrl a7@- /* push 0 / NULL */ movel #TRG_CLASS1_INDEX,a7@- movel d1,a7@- /* push event ID onto int stack */ movel __func_trgCheck,a0 jsr a0@ addl #32,a7 /* Pop params */ moveml a7@+,a1/a6 /* restore regs */intExitInstDone: movew a7@+,sr moveml a7@+,d0-d2/a0 /* restore regs */noIntExit: /* windview instrumentation - END */#endif subl #1,_intCnt /* decrement intCnt */ tstl _kernelState /* if kernelState == TRUE */ jne intRte /* then just clean up and rte */ movew a7@(8),d0 /* get the sr off the stack into d0 */ andw #0x0700,d0 /* if the interrupt level > 0 */ jne intRte /* then came from ISR...clean up/rte */ movew _intLockIntSR,sr /* LOCK INTERRUPTS */ movel _taskIdCurrent,a0 /* put current task into a0 */ cmpl _readyQHead,a0 /* compare to highest ready task */ jeq intRte /* if same then don't reschedule */ tstl a0@(WIND_TCB_LOCK_CNT) /* is task preemption allowed */ jeq saveIntContext /* if yes, then save context */ tstl a0@(WIND_TCB_STATUS) /* is task ready to run */ jne saveIntContext /* if no, then save context */intRte: movel a7@+,a0 /* restore a0 */ movel a7@+,d0 /* restore d0 */ rte /* UNLOCKS INTERRUPT and return to interupted *//* We come 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 pointer must be modified to clean up the SSP. */saveIntContext: /* interrupts are still locked out */ movel #1,_kernelState /* kernelState = TRUE; */ movel _taskIdCurrent,a0 /* tcb to be fixed up */ movel a7@+,a0@(WIND_TCB_AREGS) /* store a0 in tcb */ movel a7@+,a0@(WIND_TCB_DREGS) /* store d0 in tcb */ movew #0x3000,sr /* unlock int., switch to msp */ /* interrupts unlocked and using master stack*/ movew a7@,a0@(WIND_TCB_SR) /* save sr in tcb */ movel a7@(2),a0@(WIND_TCB_PC) /* save pc in tcb */ moveml d1-d7,a0@(WIND_TCB_DREGS4) /* d1-d7 */ moveml a1-a7,a0@(WIND_TCB_AREGS4) /* a1-a7 */#if (CPU == MC68000) addl #6,a0@(WIND_TCB_SSP) /* adj master stack ptr */#endif /* (CPU == MC68000) */#if (CPU == MC68010 || CPU==CPU32) movew a7@(6),a0@(WIND_TCB_FOROFF) /* save format/offset */ addl #8,a0@(WIND_TCB_SSP) /* adj master stack ptr */#endif /* (CPU==MC68010 || CPU==CPU32) */ movel _errno,a0@(WIND_TCB_ERRNO) /* save errno */ jmp _reschedule /* goto rescheduler */#endif /* (CPU==MC68000 || CPU==MC68010 || CPU==CPU32) *//********************************************************************************* 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 ()*/_vxTaskEntry: movel #0,a6 /* make sure frame pointer is 0 */ movel _taskIdCurrent,a0 /* get current task id */ movel a0@(WIND_TCB_ENTRY),a0 /* entry point for task is in tcb */ jsr a0@ /* call main routine */ addl #40,a7 /* pop args to main routine */ movel d0,a7@- /* pass result to exit */ jsr _exit /* gone for good *//********************************************************************************* 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* (* char *pBotStack /@ pointer to bottom of interrupt stack @/* )*/_windIntStackSet: link a6,#0#if (CPU == MC68020 || CPU==MC68040 || CPU==MC68LC040) movel a6@(ARG1),d1 /* get new botOfIsp */ movew sr,d0 /* save sr */ movew _intLockIntSR,sr /* LOCK INTERRUPTS */ movel d1,a7 /* set stack */ movew d0,sr /* UNLOCK INTERRUPTS */ movel d1,_vxIntStackBase /* update the global variable */#endif /* (CPU == MC68020 || CPU == MC68040 || CPU==MC68LC040) */ unlk a6 rts
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -