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

📄 windalib.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
📖 第 1 页 / 共 3 页
字号:
/* windALib.s - internal VxWorks kernel assembly library *//* Copyright 1984-1998 Wind River Systems, Inc. */	.data	.globl	_copyright_wind_river	.long	_copyright_wind_river/*modification history--------------------03a,17jun98,cjtc fix 68060 crash when logging. (SPR 21321)02z,26mar98,nps  bug fixes for wv2.0 port.02y,04mar98,nps  completed triggering instrumentation.02x,04mar98,nps  upgrade to WV2.0, triggering not complete.02w,08jul96,sbs  made windview instrumentation conditionally compiled02r,31oct94,tmk  added MC68LC040 support.02q,31may94,tpr  added MC68060 cpu support.02v,04mar94,smb  added some kernel optimisations		 EVENT_WIND_EXIT_NODISPATCH does not log taskIdCurrent		 introduced EVENT_INT_EXIT_K		 removed EVENT_WIND_EXIT_IDLENOT02u,03feb94,smb  changed interrupt locks to respect intLockLevelSet()02t,28jan94,smb  corrected intCnt check, optimised idle loop02s,24jan94,smb  added EVENT_WIND_EXIT_DISPATCH_PI and		 EVENT_WIND_EXIT_NODISPATCH_PI02r,19jan94,smb  fixed modhist for 02q		 event buffer overrun fix SPR #290402q,19jan94,smb  added instrumentation02p,23aug92,jcf  changed bxxx to jxx.  removed AS_WORKS_WELL.02o,04jul92,jcf  private header files.02n,26may92,rrr  the tree shuffle02m,04oct91,rrr  passed through the ansification filter		  -fixed #else and #endif		  -changed VOID to void		  -changed ASMLANGUAGE to _ASMLANGUAGE		  -changed copyright notice02l,25sep91,yao   added support for CPU32.02k,28aug91,shl   added support for MC68040, cleaned up #if CPU,		  updated copyright.02j,24aug91,jcf	  windExitInt empties work queue. fixed elr modhist.02i,17may91,elr   made portable for Motorola's SVR402h,22jan91,jcf   made portable to the 68000/68010.02g,01oct90,dab   changed conditional compilation identifier from		    HOST_SUN to AS_WORKS_WELL.02f,12sep90,dab   changed tstl a<n> to cmpl #0,a<n>. changed complex           +lpf     addressing modes instructions to .word's to make		    non-SUN hosts happy.  changed jra to jmp in 680[01]0		    section of _intExit.02e,15jul90,jcf   moved emptyWorkQ to workQDoWork () in workQALib.		  unlocked interrupts for idle in OPTIMIZED windExit ().02d,27jun90,jcf   unlocked interrupts for idle in PORTABLE windExit ()02c,26jun90,jcf   fixed PORTABLE version for wind.		  unlocked interrupts when saving context.02b,23apr90,jcf   changed name and moved to src/68k.02a,20aug89,jcf   version 2.0 enhancements.01g,29mar89,shl   documentation.01f,29mar89,shl   changed syntax of TCB_AREGS +4, TCB_AREGS +8, TCB_DREGS +4,		  andTCB_DREGS +8 to TCB_AREGS4, TCB_AREGS8 TCB_DREGS4,		  and TCB_DREGS8 respectively so to make force host happy01e,30oct88,jcf   fixed erroneous conditional compile that broke 68000 version.01d,31aug88,jcf   changed exception frame handling to preserve format/offset		    word, so floating point works correctly.		  changed windIntStackSet to modify variable _ispBot.01c,23aug88,gae   documentation; moved TCB definitions to wind.h.01b,12aug88,jcf   reworked stack usage and optimized as per code review.01a,13mar88,jcf   written.*//*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.*/#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 */#ifdef PORTABLE	.globl	_windLoadContext	/* needed by portable reschedule () */#else	.globl	_reschedule		/* optimized reschedule () routine */#endif	/* PORTABLE */	.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,sr		/* LOCK INTERRUPTS */	tstl	_workQIsEmpty			/* test for work to do */	jeq 	windExitIntWork			/* workQueue is not empty */#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * enter an interrupt handler. 	 *	 * ALL registers must be saved.  	 */	tstl	_evtAction		/* intEnt instrumentation */        jeq     noWindE	moveml  d0-d3/a0-a1,a7@-           /* save regs */        movel   #EVENT_WIND_EXIT_NODISPATCH,d1 /* event ID is now in d1 */        movel   _taskIdCurrent, a0         /* current task */        movel   a0@(WIND_TCB_PRIORITY),d3  /* ...and priority  */        /* 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     windECheckTrg          /* Jump if not set */         /* Here we try to determine if the task is running at an         * inherited priority, if so a different event is generated.         */        cmpl    a0@(WIND_TCB_PRI_NORMAL), d3        jge     windE1Inheritance                 /* no inheritance */        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1 /* replace event ID */windE1Inheritance:        /* Log event */        movel   d3,a7@-                 /* push priority */        movel   #0,a7@-                 /* push unused param */        movel   d1,a7@-                 /* push event ID onto int stack */        movel   __func_evtLogTSched,a1  /* Call log fn */        jsr     a1@        addl    #12,a7                  /* Pop params */windECheckTrg:        /* 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     windEInstDone           /* Jump if not set */        movel   _taskIdCurrent, a0         /* current task */                                           /* priority intact in d3 */        cmpl    a0@(WIND_TCB_PRI_NORMAL),d3        jge     windE1InheritanceTrg    /* no inheritance */        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1 /* replace event ID */windE1InheritanceTrg:        /* Evaluate triggers */        clrl    a7@-                     /* push 0 / NULL */        clrl    a7@-                     /* push 0 / NULL */        clrl    a7@-                     /* push 0 / NULL */        movel   d3,a7@-                  /* push priority */        movel   a0,a7@-                  /* push task ID  */        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 */windEInstDone:	moveml  a7@+,d0-d3/a0-a1           /* restore regs */noWindE:	/* windview instrumentation - END */#endif	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,sr		/* LOCK INTERRUPTS */	tstl	_workQIsEmpty			/* test for work to do */	jeq 	doWorkPreSave			/* workQueue is not empty */#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * enter an interrupt handler. 	 *	 * ALL registers must be saved.  	 */	tstl	_evtAction		/* intEnt instrumentation */        jeq     noChkW	moveml  d0-d3/a0-a1,a7@-           /* save regs */        movel   #EVENT_WIND_EXIT_NODISPATCH,d1 /* event ID is now in d1 */        movel   _taskIdCurrent, a0         /* current task */        movel   a0@(WIND_TCB_PRIORITY),d3  /* ...and priority  */        /* 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     chkWCheckTrg          /* Jump if not set */         /* Here we try to determine if the task is running at an         * inherited priority, if so a different event is generated.         */        cmpl    a0@(WIND_TCB_PRI_NORMAL), d3        jge     chkW1Inheritance                 /* no inheritance */        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1 /* replace event ID */chkW1Inheritance:        /* Log event */        movel   d3,a7@-                 /* push priority */        movel   a0,a7@-                 /* push task ID onto int stack */        movel   d1,a7@-                 /* push event ID onto int stack */        movel   __func_evtLogTSched,a1  /* Call log fn */        jsr     a1@        addl    #12,a7                   /* Pop params */chkWCheckTrg:        /* 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     chkWInstDone           /* Jump if not set */        movel   _taskIdCurrent, a0         /* current task */                                           /* priority intact in d3 */        cmpl    a0@(WIND_TCB_PRI_NORMAL),d3        jge     chkW1InheritanceTrg    /* no inheritance */        movel   #EVENT_WIND_EXIT_NODISPATCH_PI, d1 /* replace event ID */chkW1InheritanceTrg:        /* Evaluate triggers */        clrl    a7@-                     /* push 0 / NULL */        clrl    a7@-                     /* push 0 / NULL */        clrl    a7@-                     /* push 0 / NULL */        clrl    a7@-                     /* push 0 / NULL */        movel   d3,a7@-                  /* push priority */        movel   a0,a7@-                  /* push task ID  */        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 */chkWInstDone:	moveml  a7@+,d0-d3/a0-a1           /* restore regs */noChkW:	/* windview instrumentation - END */#endif	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	#0x3000,a0@(WIND_TCB_SR)	/* save a brand new SR */	clrw	a0@(WIND_TCB_FOROFF)		/* clear the format/offset */	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 */	addql	#4,a0@(WIND_TCB_SSP)		/* fix up SP for no ret adrs */

⌨️ 快捷键说明

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