⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windalib.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
📖 第 1 页 / 共 3 页
字号:
/* windALib.s - internal VxWorks kernel assembly library *//* Copyright 1984-2000 Wind River Systems, Inc. */	.data	.globl	_copyright_wind_river	.long	_copyright_wind_river/*modification history--------------------01h,09may03,dee  fix SPR 8591301g,26nov02,dee  fix SPR# 8510501f,01mar02,tcr  fix interrupt instrumentation (SPR 73858)01e,26nov01,dee  remove references to _DIAB_TOOL01d,09nov00,dh   WV support01c,07jul00,dh   Adding MAC support01b,14jun00,dh   Mods to compile for Coldfire.01a,17mar00,dra  Created from T1.0.1 ColdFire and T2 m68k ports.*//*DESCRIPTIONThis module contains internals to the VxWorks kernel.These routines have been coded in assembler because they are eitherspecific to this processor, or they have been optimized for performance.WARNINGThe assembler instructions to move to and from the MAC registers arecoded as .word values rather than correct mnemonics. This is because thefile must be compiled with the -m5200 switch, and with this switch theassembler doesn;t recognise these instructions. However, we must have themin order to support all the 52xx and 53xx families in one library archive.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "private/eventP.h"#include "private/taskLibP.h"#include "private/semLibP.h"#include "private/workQLibP.h"	.globl	_windExit		/* routine to exit mutual exclusion */	.globl	_vxTaskEntry		/* task entry wrapper */	.globl	_intEnt			/* interrupt entrance routine */	.globl	_intExit		/* interrupt exit routine */	.globl	_windIntStackSet	/* interrupt stack set routine */	.globl	_intEntTrap		/* interrupt handler trap */	.globl	__coldfireHasMac	/* MAC support needed */#ifdef PORTABLE	.globl	_windLoadContext	/* needed by portable reschedule () */#else	.globl	_reschedule		/* optimized reschedule () routine */#endif	/* PORTABLE */	.data	.even__coldfireHasMac:	.long	0			/* defaults to no mac support */	.text	.even/********************************************************************************* windExitInt - exit kernel routine from interrupt level** windExit branches here if exiting kernel routine from int level* No rescheduling is necessary because the ISR will exit via intExit, and* intExit does the necessary rescheduling.  Before leaving kernel state* the work queue is emptied.*/windExitIntWork:	movew	d0,sr				/* UNLOCK INTERRUPTS */	jsr	_workQDoWork			/* empty the work queue */windExitInt:	movew   sr,d0	movew	_intLockIntSR,d1		/* LOCK INTERRUPTS */	movew	d1,sr	tstl	_workQIsEmpty			/* test for work to do */	jeq 	windExitIntWork			/* workQueue is not empty */#ifdef WV_INSTRUMENTATION	/* wv0: windExit (interrupt) */	/* Is instrumentation on?	*/	tstl	_evtAction        jeq     wv0_skip	/* Save registers.	*/	subl	#24,a7	moveml  d0-d3/a0-a1,a7@	        /* Do we need to log this event?	*/        movel   _wvEvtClass,d2        andl    #WV_CLASS_1_ON,d2        cmpl    #WV_CLASS_1_ON,d2        jne     wv0_chkTrig         movel   _taskIdCurrent, a0		/* current task */        movel   a0@(WIND_TCB_PRIORITY),d3	/* ...and priority  */        /* Is the task running with an inherited priority? If so,	 * a different event is logged.	*/        movel   #EVENT_WIND_EXIT_NODISPATCH,d1        cmpl    a0@(WIND_TCB_PRI_NORMAL), d3        jge     wv0_log        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1wv0_log:        /* Now log the event.	*/        movel   d3,a7@-        movel   #0,a7@-        movel   d1,a7@-        movel   __func_evtLogTSched,a1        jsr     a1@        addl    #12,a7wv0_chkTrig:        /* Do we need to evaluate triggers for this event?	*/        movel   _trgEvtClass,d2        andl    #TRG_CLASS_1_ON,d2        cmpl    #TRG_CLASS_1_ON,d2        jne     wv0_restore        movel   _taskIdCurrent, a0		/* current task */        movel   a0@(WIND_TCB_PRIORITY),d3	/* ...and priority  */        /* Is the task running with an inherited priority? If so,	 * a different event is logged.	*/        movel   #EVENT_WIND_EXIT_NODISPATCH,d1        cmpl    a0@(WIND_TCB_PRI_NORMAL),d3        jge     wv0_trigger        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1wv0_trigger:        /* Evaluate triggers.	*/        clrl    a7@-				/* param 8 - unused */        clrl    a7@-				/* param 7 - unused */        clrl    a7@-				/* param 6 - unused */        movel   d3,a7@-				/* param 5 - priority */        movel   a0,a7@-				/* param 4 - task id */        clrl    a7@-				/* param 3 - unused */        movel   #TRG_CLASS1_INDEX,a7@-		/* param 2 - class index */        movel   d1,a7@-				/* param 1 - event id */        movel   __func_trgCheck,a0        jsr     a0@        addl    #32,a7				/* Pop params */wv0_restore:	moveml  a7@,d0-d3/a0-a1			/* restore regs */	addl	#24,a7wv0_skip:#endif	/* WV_INSTRUMENTATION wv0 */	clrl	_kernelState			/* else release exclusion */	movew	d0,sr				/* UNLOCK INTERRUPTS */	clrl	d0				/* return OK */	rts					/* back to calling task *//********************************************************************************* checkTaskReady - check that taskIdCurrent is ready to run** This code branched to by windExit when it finds preemption is disabled.* It is possible that even though preemption is disabled, a context switch* must occur.  This situation arrises when a task block during a preemption* lock.  So this routine checks if taskIdCurrent is ready to run, if not it* branches to save the context of taskIdCurrent, otherwise it falls thru to* check the work queue for any pending work.*/checkTaskReady:	tstl	a0@(WIND_TCB_STATUS)	/* is task ready to run */	jne 	saveTaskContext		/* if no, we blocked with preempt off */	/* FALL THRU TO CHECK WORK QUEUE *//********************************************************************************* checkWorkQ -	check the work queue for any work to do** This code is branched to by windExit.  Currently taskIdCurrent is highest* priority ready task, but before we can return to it we must check the work* queue.  If there is work we empty it via doWorkPreSave, otherwise we unlock* interrupts, clear d0, and return to taskIdCurrent.*/checkWorkQ:	movew	_intLockTaskSR,d1		/* LOCK INTERRUPTS */	movew	d1,sr	tstl	_workQIsEmpty			/* test for work to do */	jeq 	doWorkPreSave			/* workQueue is not empty */#ifdef WV_INSTRUMENTATION	/* wv1: windExit (task, no dispatch) */	/* Is instrumentation on?	*/	tstl	_evtAction        jeq     wv1_skip	/* Save registers.	*/	subl	#24,a7	moveml  d0-d3/a0-a1,a7@	        /* Do we need to log this event?	*/        movel   _wvEvtClass,d2        andl    #WV_CLASS_1_ON,d2        cmpl    #WV_CLASS_1_ON,d2        jne     wv1_chkTrig         movel   _taskIdCurrent, a0		/* current task */        movel   a0@(WIND_TCB_PRIORITY),d3	/* ...and priority  */        /* Is the task running with an inherited priority? If so,	 * a different event is logged.	*/        movel   #EVENT_WIND_EXIT_NODISPATCH,d1        cmpl    a0@(WIND_TCB_PRI_NORMAL), d3        jge     wv1_log        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1wv1_log:        /* Now log the event.	*/        movel   d3,a7@-        movel   a0,a7@-        movel   d1,a7@-        movel   __func_evtLogTSched,a1        jsr     a1@        addl    #12,a7wv1_chkTrig:        /* Do we need to evaluate triggers for this event?	*/        movel   _trgEvtClass,d2        andl    #TRG_CLASS_1_ON,d2        cmpl    #TRG_CLASS_1_ON,d2        jne     wv1_restore        movel   _taskIdCurrent, a0		/* current task */        movel   a0@(WIND_TCB_PRIORITY),d3	/* ...and priority  */        /* Is the task running with an inherited priority? If so,	 * a different event is logged.	*/        movel   #EVENT_WIND_EXIT_NODISPATCH,d1        cmpl    a0@(WIND_TCB_PRI_NORMAL),d3        jge     wv1_trigger        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1wv1_trigger:        /* Evaluate triggers.	*/        clrl    a7@-				/* param 8 - unused */        clrl    a7@-				/* param 7 - unused */        clrl    a7@-				/* param 6 - unused */        movel   d3,a7@-				/* param 5 - priority */        movel   a0,a7@-				/* param 4 - task id */        clrl    a7@-				/* param 3 - unused */        movel   #TRG_CLASS1_INDEX,a7@-		/* param 2 - class index */        movel   d1,a7@-				/* param 1 - event id */        movel   __func_trgCheck,a0        jsr     a0@        addl    #32,a7				/* Pop params */wv1_restore:	moveml  a7@,d0-d3/a0-a1			/* restore regs */	addl	#24,a7wv1_skip:#endif	/* WV_INSTRUMENTATION wv1 */	clrl	_kernelState			/* else release exclusion */	movew	#0x3000,sr			/* UNLOCK INTERRUPTS */	clrl	d0				/* return OK */	rts					/* back to calling task *//********************************************************************************* doWorkPreSave - empty the work queue with current context not saved** We try to empty the work queue here, rather than let reschedule* perform the work because there is a strong chance that the* work we do will not preempt the calling task.  If this is the case, then* saving the entire context just to restore it in reschedule is a waste of* time.  Once the work has been emptied, the ready queue must be checked to* see if reschedule must be called, the check of the ready queue is done by* branching back up to checkTaskCode.*/doWorkPreSave:	movew	#0x3000,sr			/* UNLOCK INTERRUPTS */	jsr	_workQDoWork			/* empty the work queue */	jra 	checkTaskSwitch			/* back up to test if tasks *//******************************************************************************** windExit - task level exit from kernel** Release kernel mutual exclusion (kernelState) and dispatch any new task if* necessary.  If a higher priority task than the current task has been made* ready, then we invoke the rescheduler.  Before releasing mutual exclusion,* the work queue is checked and emptied if necessary.** If rescheduling is necessary, the context of the calling task is saved in its* associated TCB with the PC pointing at the next instruction after the jsr to* this routine.  The SSP in the tcb is modified to ignore the return address* on the stack.  Thus the context saved is as if this routine was never called.** Only the volatile registers d0,d1,a0,a1 are safe to use until the context* is saved in saveTaskContext.** At the call to reschedule the value of taskIdCurrent must be in a0.** RETURNS: OK or*	   ERROR if semaphore timeout occurs.** NOMANUAL* STATUS windExit ()*/	_windExit:	tstl	_intCnt			/* if intCnt == 0 we're from task */	jne 	windExitInt		/* else we're exiting interrupt code */	/* FALL THRU TO CHECK THAT CURRENT TASK IS STILL HIGHEST *//********************************************************************************* checkTaskSwitch - check to see if taskIdCurrent is still highest task** We arrive at this code either as the result of falling thru from windExit,* or if we have finished emptying the work queue.  We compare taskIdCurrent* with the highest ready task on the ready queue.  If they are same we* go to a routine to check the work queue.  If they are different and preemption* is allowed we branch to a routine to make sure that taskIdCurrent is really* ready (it may have blocked with preemption disabled).  If they are different* we save the context of taskIdCurrent and fall thru to reschedule.*/checkTaskSwitch:	movel	_taskIdCurrent,a0		/* move taskIdCurrent into a0 */	cmpl	_readyQHead,a0			/* compare highest ready task */	jeq 	checkWorkQ			/* if same then time to leave */	tstl	a0@(WIND_TCB_LOCK_CNT)		/* is task preemption allowed */	jne 	checkTaskReady			/* if no, check task is ready */saveTaskContext:	movel	a7@,a0@(WIND_TCB_PC)		/* save return address as PC */	movew	sr,d0	movew	d0,a0@(WIND_TCB_SR)		/* save current SR in TCB */	moveml	d2-d7,a0@(WIND_TCB_DREGS8)	/* d2-d7; d0,d1 are volatile */	moveml	a2-a7,a0@(WIND_TCB_AREGS8)	/* a2-a7; a0,a1 are volatile */	clrl	a0@(WIND_TCB_DREGS)		/* clear saved d0 for return */	tstl	__coldfireHasMac	jeq 	saveTaskCtxtMacEnd		/* jump if no MAC */saveTaskCtxtMac:	.word	0xa180				/* movel acc,d0 */	movel	d0,a0@(WIND_TCB_MAC)		/* save MAC */	.word	0xa980				/* movel macsr,d0 */	movew	d0,a0@(WIND_TCB_MACSR)		/* save MACSR */	.word	0xad80				/* movel mask,d0 */	movew	d0,a0@(WIND_TCB_MASK)		/* save MASK */saveTaskCtxtMacEnd:	addql	#4,a0@(WIND_TCB_SSP)		/* fix up SP for no ret adrs */	movel	_errno,d0			/* save errno */	movel	d0,a0@(WIND_TCB_ERRNO)		/* save errno */#ifdef PORTABLE	jsr	_reschedule			/* goto rescheduler */#else	/* FALL THRU TO RESCHEDULE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -