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

📄 windalib.s

📁 VXWORKS源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
	 *     : %esi			    : return addr	 *     : %edi			    : %eax	 *     :			    V	 *     V	 *	 */	cmpl	$0,FUNC(vxIntStackEnabled) /* if vxIntStackEnabled == 0 then */	je	intEnt0			/* skip the interrupt stack switch */	movl	ESF0_CS+12(%esp), %eax	/* get CS in ESF0 */	cmpw	FUNC(sysCsInt), %ax	/* is it nested interrupt ? */	je	intEnt0			/*   yes: skip followings */	cmpl	$1,FUNC(intNest)	/* already in the interrupt stack? */	jne	intEnt0			/* skip the interrupt stack switch */	/* copy the supervisor stack to the interrupt stack. */intEntStackSwitch:	pushl	%ecx			/* save %ecx */	pushl	%esi			/* save %esi */	pushl	%edi			/* save %edi */	/* copy ESF0(12 bytes), errno, return addr, %eax */	subl	$ ESF0_NBYTES+12+4, FUNC(vxIntStackPtr) /* alloc */	movl	FUNC(vxIntStackPtr), %eax  /* get int-stack ptr */	leal	20(%esp), %ecx		   /* get addr of errno */	movl	%ecx, ESF0_NBYTES+12(%eax) /* save the original ESP */	leal	12(%esp), %esi		/* set the source addr */	movl	%eax, %edi		/* set the destination addr */	movl	$ ESF0_NLONGS+3, %ecx	/* set number of longs to copy */	cld				/* set direction ascending order */	rep				/* repeat next inst */	movsl				/* copy ESF0_NLONGS + 3 longs */	popl	%edi			/* restore %edi */	popl	%esi			/* restore %esi */	popl	%ecx			/* restore %ecx */	movl	%eax, %esp		/* switch to the interrupt stack */	/* now, we are in the interrupt stack */#endif	/* INT_STACK_USE */intEnt0:	pushl	ESF0_EFLAGS+12(%esp)	/* push the saved EFLAGS */	popfl				/* UNLOCK INTERRUPT */	popl	%eax			/* restore %eax */#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * enter an interrupt handler. 	 *	 * ALL registers must be saved.  	 */        cmpl    $0,FUNC(evtAction)		/* is WindView on? */        je	noIntEnt	pushal                          	/* save regs */	pushfl					/* save EFLAGS */	cli					/* LOCK INTERRUPTS */	movl	32+4(%esp),%edi		/* use %edi to store the return address */	movl	$ WV_CLASS_1_ON,%eax        andl    FUNC(wvEvtClass),%eax		/* is event collection on? */        cmpl    $ WV_CLASS_1_ON,%eax		/* is event collection on? */        jne     trgCheckIntEnt	movl	INT_CONNECT_CODE29(%edi), %eax	/* get IRQ number */	addl    $ MIN_INT_ID,%eax 		/* get event ID */	movl	FUNC(_func_evtLogT0),%edx	/* event log routine */	cmpl	$0,%edx	je	trgCheckIntEnt	pushl   %eax	call	*%edx				/* call event log routine */		addl    $4,%esptrgCheckIntEnt:	movl	$ TRG_CLASS_1,%eax     	orl 	$ TRG_ON,%eax        cmpl    FUNC(trgEvtClass),%eax		/* any trigger? */        jne     intEntClean	movl	INT_CONNECT_CODE29(%edi), %eax	/* get IRQ number */	addl    $ MIN_INT_ID,%eax 		/* get event ID */        movl    FUNC(_func_trgCheck),%edx	/* triggering routine */	cmpl	$0,%edx        je      intEntClean        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* obj */        pushl   $ 0                     	/* TRG_CLASS1_INDEX */        pushl   %eax                    	/* push event ID */        call    *%edx                   	/* call triggering routine */	addl    $32,%espintEntClean:	popfl					/* restore EFLAGS */	popal					/* restore regs */noIntEnt:	/* windview instrumentation - END */#endif  /* WV_INSTRUMENTATION */	ret/********************************************************************************* 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, EFLAGS and EFLAGS 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 edx.*/	.balign 16,0x90FUNC_LABEL(intExit)	popl	FUNC(errno)		/* restore errno */	pushl	%eax			/* push %eax onto the stack */#ifdef WV_INSTRUMENTATION        /* windview instrumentation - BEGIN         * log event if work has been done in the interrupt handler.         * NOTE: a0 is still on the stack         */        cmpl    $0,FUNC(evtAction)		/* is WindView on? */        je	noIntExit        pushl	%edx        pushl	%ecx	pushfl					/* save EFLAGS */	cli					/* LOCK INTERRUPTS */	movl	$ WV_CLASS_1_ON,%eax        andl    FUNC(wvEvtClass),%eax		/* is event collection on? */        cmpl    $ WV_CLASS_1_ON,%eax		/* is event collection on? */        jne     trgCheckIntExit	movl	FUNC(_func_evtLogT0),%edx	/* event log routine */	cmpl	$0,%edx	je	trgCheckIntExit        cmpl	$0,FUNC(workQIsEmpty)		/* work in work queue? */        jne     intExitEvent        pushl	$ EVENT_INT_EXIT_K		/* event id */        jmp     intExitContintExitEvent:        pushl	$ EVENT_INT_EXIT		/* event id */intExitCont:	call	*%edx				/* call event log routine */		addl 	$4,%esp trgCheckIntExit:	movl	$ TRG_CLASS_1,%eax     	orl 	$ TRG_ON,%eax        cmpl    FUNC(trgEvtClass),%eax		/* any trigger? */        jne      intExitClean        movl    FUNC(_func_trgCheck),%edx	/* triggering routine */	cmpl	$0,%edx        je      intExitClean        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* 0 */        pushl   $ 0                     	/* obj */        pushl   $ 0                     	/* TRG_CLASS1_INDEX */        cmpl	$0,FUNC(workQIsEmpty)		/* work in work queue? */        jne     trgIntExitEvent        pushl	$ EVENT_INT_EXIT_K		/* event id */        jmp     trgIntExitConttrgIntExitEvent:        pushl	$ EVENT_INT_EXIT		/* event id */trgIntExitCont:        call    *%edx                   	/* call triggering routine */	addl    $32,%espintExitClean:	popfl					/* UNLOCK INTERRUPTS */        popl	%ecx				/* restore regs */        popl	%edxnoIntExit:        /* windview instrumentation - END */#endif  /* WV_INSTRUMENTATION */	cli					/* LOCK INTERRUPTS */	decl	FUNC(intCnt)			/* decrement intCnt */	decl	FUNC(intNest)			/* decrement the private counter */        movl	ESF0_CS+4(%esp),%eax		/* if CS on stack is sysCsInt, */        cmpw	FUNC(sysCsInt),%ax		/*  then we were in an ISR */        je	intRte				/*  so just clean up/rte */#ifdef	INT_STACK_USE	/*	 * switch to the supervisor stack from the interrupt stack	 *         * stack growth in the 1st interrupt	 *   (supervisor stack)            (interrupt stack)	 *   ----------------------------------------------	 *     :                 +-----     supervisor SP	 *     ESF(12 bytes)	 |          ESF(12 bytes)    --- 1st int	 *     errno       <-----+	    : errno / %eax   --- 1st int	 *     :                            : %eax	 *     :                            :	 *     V                            V	 *         * stack growth in the 2nd interrupt	 *   (supervisor stack)            (interrupt stack)	 *   ----------------------------------------------	 *     :                 +-----     supervisor SP	 *     ESF(12 bytes)	 |          ESF(12 bytes)    --- 1st int	 *     errno       <-----+	    errno            --- 1st int	 *     :                            :	 *     :                            ESF(12 bytes)    --- 2nd int	 *     :                            : errno / %eax   --- 2nd int	 *     V                            : %eax	 *                                  :	 *                                  V	 *	 */	cmpl	$0,FUNC(vxIntStackEnabled) /* if vxIntStackEnabled == 0 then */	je	intExit0		/* skip the interrupt stack switch */	cmpl    $0, FUNC(intNest)	/* is it nested interrupt ? */	jne     intExit0		/*   yes: goto intRteInt */	popl	%eax			/* restore %eax */	addl	$ ESF0_NBYTES+12+4, FUNC(vxIntStackPtr) /* free */	movl	ESF0_NBYTES(%esp), %esp /* switch to supervisor stack */	popl	FUNC(errno)		/* restore errno */	pushl	%eax			/* save %eax */#endif	/* INT_STACK_USE */intExit0:	cmpl	$0,FUNC(kernelState)	/* if kernelState == TRUE then */	jne	intRte			/*  just clean up and rte */	movl	FUNC(taskIdCurrent),%eax /* put current task in %eax */	cmpl	FUNC(readyQHead),%eax 	/* compare to highest ready task */	je	intRte			/* if same then don't reschedule */	cmpl	$0,WIND_TCB_LOCK_CNT(%eax) /* is task preemption allowed */	je	saveIntContext		/* if yes, then save context */	cmpl	$0,WIND_TCB_STATUS(%eax) /* is task ready to run */	jne	saveIntContext		/* if no, then save context */intRte:	popl	%eax			/* restore %eax */	iret				/* 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 (SP). */	.balign 16,0x90saveIntContext:	/* interrupts are still locked out */	movl	$1,FUNC(kernelState)		/* kernelState = TRUE; */	movl	FUNC(taskIdCurrent),%eax	/* tcb to be fixed up */	popl	WIND_TCB_EAX(%eax)		/* store %eax in tcb */	popl	WIND_TCB_PC(%eax)		/* save pc in tcb */	leal	4(%esp),%esp			/* do not save %cs in tcb */	popl	WIND_TCB_EFLAGS(%eax)		/* save eflags in tcb */	sti					/* UNLOCK INTERRUPTS */	/* interrupts unlocked and using master stack*/	movl	%edx,WIND_TCB_EDX(%eax)		/* save %edx */	movl	%ecx,WIND_TCB_ECX(%eax)		/* save %ecx */	movl	%ebx,WIND_TCB_EBX(%eax)		/* save %ebx */	movl	%esi,WIND_TCB_ESI(%eax)		/* save %esi */	movl	%edi,WIND_TCB_EDI(%eax)		/* save %edi */	movl	%ebp,WIND_TCB_EBP(%eax)		/* save %ebp */	movl	%esp,WIND_TCB_ESP(%eax)		/* save %esp */	movl	FUNC(errno),%edx		/* save errno */	movl	%edx,WIND_TCB_ERRNO(%eax)	movl	%eax,%edx			/* taskIdCurrent into %edx */	jmp	FUNC(reschedule)		/* goto rescheduler *//********************************************************************************* 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 ()*/	.balign 16,0x90FUNC_LABEL(vxTaskEntry)	xorl	%ebp,%ebp		/* make sure frame pointer is 0 */	movl	FUNC(taskIdCurrent),%eax /* get current task id */	movl	WIND_TCB_ENTRY(%eax),%eax /* entry point for task is in tcb */	call	*%eax			/* call main routine */	addl	$40,%esp		/* pop args to main routine */	pushl	%eax			/* pass result to exit */	call	FUNC(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.* For I80X86, the switch to/from the interrupt stack is done by software.** NOMANUAL* void windIntStackSet (pBotStack)*     char *pBotStack;	/* pointer to bottom of interrupt stack **/	.balign 16,0x90FUNC_LABEL(windIntStackSet)	movl	SP_ARG1(%esp), %eax	/* get pBotStack */	movl	%eax, FUNC(vxIntStackPtr) /* set it to vxIntStackPtr */	ret/********************************************************************************* intStackEnable - enable the interrupt stack usage** This routine enables the interrupt stack usage.* This routine is only callable from the task level, returns ERROR otherwise.* The interrupt stack usage is disabled in the default configuration * for the backward compatibility.** RETURNS: OK, or ERROR if it is not in the task level.* STATUS intStackEnable *    (*    BOOL enable		/@ TRUE to enable, FALSE to disable @/*    )*/	.balign 16,0x90FUNC_LABEL(intStackEnable)	movl	%cs, %eax	cmpl	FUNC(sysCsSuper), %eax	/* is the CS for the task level? */	jne	intStackEnableError	/*   no: return ERROR */	xorl	%eax, %eax		/* zero for OK */	movl	SP_ARG1(%esp), %edx	/* get & set the parameter */		/* next "movl" instruction is atomic, so no intLock/Unlock is needed */	movl	%edx, FUNC(vxIntStackEnabled)	retintStackEnableError:	movl	$ ERROR, %eax	ret

⌨️ 快捷键说明

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