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

📄 windalib.s

📁 VXWORKS源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
* If a context switch to a different task is to occur, then the installed* switch hooks are called.** NOMANUAL* void reschedule ()*/	.balign 16,0x90FUNC_LABEL(reschedule)	movl	FUNC(readyQHead),%eax		/* get highest task to %eax */	cmpl	$0,%eax	je	idle				/* idle if nobody ready */switchTasks:	movl	%eax,FUNC(taskIdCurrent)	/* update taskIdCurrent */ 	movw	WIND_TCB_SWAP_IN(%eax),%bx	/* swap hook mask into %bx */ 	orw	WIND_TCB_SWAP_OUT(%edx),%bx	/* or in swap out hook mask */ 	jne	doSwapHooks			/* any swap hooks to do */ 	cmpl	$0,FUNC(taskSwitchTable)	/* any global switch hooks? */	jne	doSwitchHooks			/* any switch hooks to do */dispatch:	movl	WIND_TCB_ERRNO(%eax),%ecx	/* retore errno */	movl	%ecx,FUNC(errno)	movl	WIND_TCB_ESP(%eax),%esp		/* push dummy except */	pushl	WIND_TCB_EFLAGS(%eax)		/* push EFLAGS */	pushl	FUNC(sysCsSuper)		/* push CS */	pushl	WIND_TCB_PC(%eax) 		/* push PC */	movl	WIND_TCB_EDX(%eax),%edx		/* restore registers */	movl	WIND_TCB_ECX(%eax),%ecx	movl	WIND_TCB_EBX(%eax),%ebx	movl	WIND_TCB_ESI(%eax),%esi	movl	WIND_TCB_EDI(%eax),%edi	movl	WIND_TCB_EBP(%eax),%ebp	movl	WIND_TCB_EAX(%eax),%eax	cli					/* LOCK INTERRUPTS */	cmpl	$0,FUNC(workQIsEmpty)		/* if work q is not empty */	je	doWorkUnlock			/* then unlock and do work */#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * exit windExit with dispatch;	 */        cmpl    $0,FUNC(evtAction)		/* is WindView on? */        je      noInst3	pushl	%eax				/* save regs */	pushl	%edx	pushl	%ecx	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     trgCheckInst3	movl	FUNC(_func_evtLogTSched),%edx	/* event log routine */	cmpl	$0,%edx        je      trgCheckInst3        movl	FUNC(taskIdCurrent),%eax	/* current task */        movl	WIND_TCB_PRIORITY(%eax),%ecx        pushl	%ecx	                        /* WIND_TCB_PRIORITY */        pushl	%eax	                        /* taskIdCurrent */        /* Here we try to determine if the task is running at an         * inherited priority, if so a different event is generated.         */        cmpl	WIND_TCB_PRI_NORMAL(%eax),%ecx        jge     noInst3Inheritance		/* no inheritance */        pushl	$ EVENT_WIND_EXIT_DISPATCH_PI        jmp     inst3Inheritance		/* no inheritance */noInst3Inheritance:        pushl	$ EVENT_WIND_EXIT_DISPATCH	/* event id */inst3Inheritance:        call    *%edx                           /* call evtsched routine */	addl    $12,%esptrgCheckInst3:	movl	$ TRG_CLASS_1,%eax     	orl 	$ TRG_ON,%eax        cmpl    FUNC(trgEvtClass),%eax		/* any trigger? */        jne      inst3Clean        movl    FUNC(_func_trgCheck),%edx	/* triggering routine */	cmpl	$0,%edx        je      inst3Clean        movl	FUNC(taskIdCurrent),%eax	/* current task */        movl	WIND_TCB_PRIORITY(%eax),%ecx        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl	%ecx	                /* WIND_TCB_PRIORITY */        pushl	%eax	                /* taskIdCurrent */        pushl   $ 0                     /* obj */        pushl   $ 0                     /* TRG_CLASS1_INDEX */        /* Here we try to determine if the task is running at an         * inherited priority, if so a different event is generated.         */        cmpl	WIND_TCB_PRI_NORMAL(%eax),%ecx        jge     noTrgInst3Inheritance		/* no inheritance */        pushl	$ EVENT_WIND_EXIT_DISPATCH_PI        jmp     trgInst3Inheritance		/* no inheritance */noTrgInst3Inheritance:        pushl	$ EVENT_WIND_EXIT_DISPATCH	/* event id */trgInst3Inheritance:        call    *%edx                   /* call triggering routine */	addl    $32,%espinst3Clean:	popl	%ecx			/* restore regs */	popl	%edx	popl	%eaxnoInst3:	/* windview instrumentation - END */#endif  /* WV_INSTRUMENTATION */	movl	$0,FUNC(kernelState)		/* release kernel mutex */	iret					/* UNLOCK INTERRUPTS *//********************************************************************************* idle - spin here until there is more work to do** When the kernel is idle, we spin here continually checking for work to do.*/	.balign 16,0x90idle:#ifdef WV_INSTRUMENTATION        /* windview instrumentation - BEGIN         * enter idle state         *         * NOTE: I am making the assumption here that it is okay to         * modify the %eax,%edx,%ecx registers. They are not being saved.         */        cmpl    $0,FUNC(evtAction)	/* is WindView on? */        je      noInstIdle	pushal	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     trgCheckInstIdle	movl	FUNC(_func_evtLogT0),%edx /* event log routine */	cmpl	$0,%edx        je      trgCheckInstIdle        pushl	$ EVENT_WIND_EXIT_IDLE  /* event id */	call	*%edx			/* call event log routine */		addl    $4,%esptrgCheckInstIdle:	movl	$ TRG_CLASS_1,%eax     	orl 	$ TRG_ON,%eax        cmpl    FUNC(trgEvtClass),%eax		/* any trigger? */        jne     instIdleClean        movl    FUNC(_func_trgCheck),%edx	/* triggering routine */	cmpl	$0,%edx	je	instIdleClean        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* 0 */        pushl   $ 0                     /* obj */        pushl   $ 0                     /* TRG_CLASS1_INDEX */        pushl   $ EVENT_WIND_EXIT_IDLE	/* EVENT_WIND_EXIT_IDLE */        call    *%edx                   /* call triggering routine */	addl 	$32,%esp instIdleClean:	popalnoInstIdle:	/* windview instrumentation - END */#endif  /* WV_INSTRUMENTATION */	sti				/* UNLOCK INTERRUPTS (just in case) */	movl	$1,FUNC(kernelIsIdle)	/* set idle flag for spyLib */idleLoop:        cmpl    $0,FUNC(workQIsEmpty)   /* if work queue has work to do */        je      goDoWork		/* no more idling */	/* PAUSE instruction operates like a NOP in earlier IA-32 processors */        .byte   0xf3, 0x90              /* PAUSE should be in the loop */#ifdef X86_POWER_MANAGEMENT	cmp     $0, FUNC(vxIdleRtn)	/* is Power Management enabled ? */	je	idleLoop		/* no: stay in loop */        call    *FUNC(vxIdleRtn)        /* call routine set by vxPowerModeSet */#else        jmp     idleLoop                /* keep hanging around */#endif /* X86_POWER_MANAGEMENT */goDoWork:	/* there is some work to do, can't remain idle now */        movl    $0,FUNC(kernelIsIdle)   /* unset idle flag for spyLib */        jmp     doWork                  /* go do the work */#ifdef X86_POWER_MANAGEMENT/********************************************************************************* vxIdleAutoHalt - place the processor in AutoHalt mode when nothing to do*/        .balign 16,0x90FUNC_LABEL(vxIdleAutoHalt)        sti                             /* make sure interrupts are enabled */        nop                             /* delay a bit */        cmpl    $0,FUNC(workQIsEmpty)   /* if work queue is still empty */        je      vpdRet                  /* there is work to do - return */        hlt                             /* nothing to do - go in AutoHalt */vpdRet:        ret#endif /* X86_POWER_MANAGEMENT *//********************************************************************************* doSwapHooks - execute the tasks' swap hooks*/	.balign 16,0x90doSwapHooks:	pushl	%eax			/* push pointer to new tcb */	pushl	%edx			/* push pointer to old tcb */	leal	FUNC(taskSwapTable),%edi /* get adrs of task switch rtn list */	movl	$-4,%esi		/* start index at -1, heh heh */	jmp	doSwapShift		/* jump into the loop */	.balign 16,0x90doSwapHook:	movl	(%esi,%edi,1),%ecx	/* call task switch rtn into r3+4*n */	call	*%ecxdoSwapShift:	addl	$4,%esi			/* bump swap table index */	shlw	$1,%bx			/* shift swapMask bit pattern left */	jc	doSwapHook		/* if carry bit set then do ix hook */	jne	doSwapShift		/* any bits still set */					/* no need to clean stack */	movl	FUNC(taskIdCurrent),%eax /* restore %eax with taskIdCurrent */	cmpl	$0,FUNC(taskSwitchTable) /* any global switch hooks? */	je	dispatch		/* if no then dispatch taskIdCurrent */	jmp	doSwitchFromSwap	/* do switch routines from swap *//********************************************************************************* doSwitchHooks - execute the global switch hooks*/	.balign 16,0x90doSwitchHooks:	pushl	%eax			/* push pointer to new tcb */	pushl	%edx			/* push pointer to old tcb */doSwitchFromSwap:	leal	FUNC(taskSwitchTable),%edi /* get adrs of task switch rtn list */	movl	(%edi),%esi		/* get task switch rtn into %esi */doSwitchHook:	call	*%esi			/* call routine */	addl	$4,%edi			/* bump to next task switch routine */	movl	(%edi),%esi		/* get next task switch rtn */	cmpl	$0,%esi	jne	doSwitchHook		/* check for end of table (NULL) */					/* no need to clean stack */	movl	FUNC(taskIdCurrent),%eax /* restore %eax with taskIdCurrent */	jmp	dispatch		/* dispatch task *//********************************************************************************* doWork - empty the work queue* doWorkUnlock - unlock interrupts and empty the work queue*/	.balign 16,0x90doWorkUnlock:	sti				/* UNLOCK INTERRUPTS */doWork:	call	FUNC(workQDoWork)	/* empty the work queue */	movl	FUNC(taskIdCurrent),%edx /* %edx = taskIdCurrent */	movl	FUNC(readyQHead),%eax	/* %eax = highest task */	cmpl	$0,%eax	je	idle			/* nobody is ready so spin */	cmpl	%edx,%eax		/* compare to last task */	je	dispatch		/* if the same dispatch */	jmp	switchTasks		/* not same, do switch */#endif	/* PORTABLE */#ifdef PORTABLE/********************************************************************************* windLoadContext - load the register context from the control block** The registers of the current executing task, (the one reschedule chose),* are restored from the control block.  Then the appropriate exception frame* for the architecture being used is constructed.  To unlock interrupts and* enter the new context we simply use the instruction rte.** NOMANUAL* void windLoadContext ()*/	.balign 16,0x90FUNC_LABEL(windLoadContext)	movl	FUNC(taskIdCurrent),%eax	/* current tid */	movl	WIND_TCB_ERRNO(%eax),%ecx	/* save errno */	movl	%ecx,FUNC(errno)	movl	WIND_TCB_ESP(%eax),%esp		/* push dummy except. */	pushl	WIND_TCB_EFLAGS(%eax)		/* push eflags */	pushl	FUNC(sysCsSuper)		/* push CS */	pushl	WIND_TCB_PC(%eax)		/* push pc */	movl	WIND_TCB_EDX(%eax),%edx		/* restore registers */	movl	WIND_TCB_ECX(%eax),%ecx	movl	WIND_TCB_EBX(%eax),%ebx	movl	WIND_TCB_ESI(%eax),%esi	movl	WIND_TCB_EDI(%eax),%edi	movl	WIND_TCB_EBP(%eax),%ebp	movl	WIND_TCB_EAX(%eax),%eax	iret					/* enter task's context. */#endif	/* PORTABLE *//********************************************************************************* intEnt - enter an interrupt service routine** intEnt must be called at the entrance of an interrupt service routine.* This normally happens automatically, from the stub built by intConnect (2).* This routine should NEVER be called from C.** SEE ALSO: intConnect(2)* void intEnt ()*/	.balign 16,0x90FUNC_LABEL(intEnt)	cli				/* LOCK INTERRUPTS */	pushl	(%esp)			/* bump return address up a notch */	pushl	%eax	movl	FUNC(errno),%eax	/* save errno where return adress was */	movl	%eax,8(%esp)	incl	FUNC(intCnt)		/* increment the counter */	incl	FUNC(intNest)		/* increment the private counter */#ifdef	INT_STACK_USE	/*	 * switch to the interrupt stack from the supervisor stack 	 * used by a task running in the supervisor mode	 *	 * if we are already in the interrupt stack, no stack switch will	 * happen.  It happens in the following cases:	 *   int - exc(break/trace) - int	 *   int - int - exc(break/trace) - int	 * To detect if the interrupt stack is already in use, the	 * private counter intNest is used.  Checking the CS in ESF does	 * not work in the above cases.  But the checking the CS in ESF	 * is necessary to detect the nesting interrupt before and after	 * the counter is manipulated.         *         * stack growth in the 1st interrupt	 *   (supervisor stack)            (interrupt stack)	 *   ----------------------------------------------	 *     :                 +-----     supervisor SP	 *     ESF(12 bytes)	 |          ESF(12 bytes)	 *     errno       <-----+	    errno	 *     return addr       	    : return addr	 *     %eax			    : %eax	 *     : %ecx			    V	 *     : %esi			    	 *     : %edi			    	 *     :	 *     V	 *         * stack growth in the 2nd interrupt (nested interrupt)	 *   (supervisor stack)            (interrupt stack)	 *   ----------------------------------------------	 *     :                 +-----     supervisor SP	 *     ESF(12 bytes)	 |          ESF(12 bytes)    --- 1st int	 *     errno       <-----+	    errno            --- 1st int	 *     return addr       	    :	 *     %eax			    ESF(12 bytes)    --- 2nd int	 *     : %ecx			    errno            --- 2nd int

⌨️ 快捷键说明

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