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

📄 windalib.s

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 S
📖 第 1 页 / 共 3 页
字号:
* 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:	movl	_taskIdCurrent,%edx		/* move taskIdCurrent to edx */	cmpl	_readyQHead,%edx		/* compare highest ready task */	je	checkWorkQ			/* if same then time to leave */	cmpl	$0,WIND_TCB_LOCK_CNT(%edx)	/* is task preemption allowed */	jne	checkTaskReady			/* if no, check task is ready */saveTaskContext:	movl	(%esp),%eax			/* save return address as PC */	movl	%eax,WIND_TCB_PC(%edx)	pushfl					/* save a eflags */	popl	WIND_TCB_EFLAGS(%edx)		bts	$9,WIND_TCB_EFLAGS(%edx)	/* set IF to enable INT */	movl	%ebx,WIND_TCB_EBX(%edx)		/* e[adc]x are volatile */	movl	%esi,WIND_TCB_ESI(%edx)	movl	%edi,WIND_TCB_EDI(%edx)	movl	%ebp,WIND_TCB_EBP(%edx)	movl	%esp,WIND_TCB_ESP(%edx)	movl	$0,WIND_TCB_EAX(%edx)		/* clear saved eax for return */	addl	$4,WIND_TCB_ESP(%edx)		/* fix up SP for no ret adrs */	pushl	_errno				/* save errno */	popl	WIND_TCB_ERRNO(%edx)#ifdef PORTABLE	call	_reschedule#else	/* FALL THRU TO RESCHEDULE *//********************************************************************************* reschedule - rescheduler for VxWorks kernel** This routine is called when either intExit, or windExit, thinks the* context might change.  All of the contexts of all of the tasks are* accurately stored in the task control blocks when entering this function.* The status register is 0x800f0000. (Supervisor, Stack0, Interrupts UNLOCKED)** The register %edx must contain the value of _taskIdCurrent at the entrance to* this routine.** At the conclusion of this routine, taskIdCurrent will equal the highest* priority task eligible to run, and the kernel work queue will be empty.* If a context switch to a different task is to occur, then the installed* switch hooks are called.** NOMANUAL* void reschedule ()*/	.align 4,0x90_reschedule:	movl	_readyQHead,%eax		/* get highest task to %eax */	cmpl	$0,%eax	je	idle				/* idle if nobody ready */switchTasks:	movl	%eax,_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,_taskSwitchTable		/* any global switch hooks? */	jne	doSwitchHooks			/* any switch hooks to do */dispatch:	movl	WIND_TCB_ERRNO(%eax),%ecx	/* retore errno */	movl	%ecx,_errno	movl	WIND_TCB_ESP(%eax),%esp		/* push dummy except */	pushl	WIND_TCB_EFLAGS(%eax)		/* push EFLAGS */	pushl	_sysCodeSelector		/* 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,_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,_evtAction           /* is WindView on? */        je      noInst3	pushl	%eax				/* save regs */	pushl	%edx	pushl	%ecx	movl	$ WV_CLASS_1_ON,%eax        andl    _wvEvtClass,%eax          /* is event collection on? */        cmpl    $ WV_CLASS_1_ON,%eax          /* is event collection on? */        jne     trgCheckInst3	movl	__func_evtLogTSched,%edx	/* event log routine */	cmpl	$0,%edx        je      trgCheckInst3        movl	_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    _trgEvtClass,%eax       /* any trigger? */        jne      inst3Clean        movl    __func_trgCheck,%edx    /* triggering routine */	cmpl	$0,%edx        je      inst3Clean        movl	_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,_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.*/	.align 4,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,_evtAction           /* is WindView on? */        je      noInstIdle	pushal	cli				/* LOCK INTERRUPTS */	movl	$ WV_CLASS_1_ON,%eax        andl    _wvEvtClass,%eax          /* is event collection on? */        cmpl    $ WV_CLASS_1_ON,%eax          /* is event collection on? */        jne     trgCheckInstIdle	movl	__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    _trgEvtClass,%eax       /* any trigger? */        jne     instIdleClean        movl    __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,_kernelIsIdle	/* set idle flag for spyLib */idleLoop:	cmpl	$0,_workQIsEmpty	/* if work queue is still empty */	jne	idleLoop		/* keep hanging around */	movl	$0,_kernelIsIdle	/* unset idle flag for spyLib */	jmp	doWork			/* go do the work *//********************************************************************************* doSwapHooks - execute the tasks' swap hooks*/	.align 4,0x90doSwapHooks:	pushl	%eax			/* push pointer to new tcb */	pushl	%edx			/* push pointer to old tcb */	leal	_taskSwapTable,%edi	/* get adrs of task switch rtn list */	movl	$-4,%esi		/* start index at -1, heh heh */	jmp	doSwapShift		/* jump into the loop */	.align 4,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	_taskIdCurrent,%eax	/* restore %eax with taskIdCurrent */	cmpl	$0,_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*/	.align 4,0x90doSwitchHooks:	pushl	%eax			/* push pointer to new tcb */	pushl	%edx			/* push pointer to old tcb */doSwitchFromSwap:	leal	_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	_taskIdCurrent,%eax	/* restore %eax with taskIdCurrent */	jmp	dispatch		/* dispatch task *//********************************************************************************* doWork - empty the work queue* doWorkUnlock - unlock interrupts and empty the work queue*/	.align 4,0x90doWorkUnlock:	sti				/* UNLOCK INTERRUPTS */doWork:	call	_workQDoWork		/* empty the work queue */	movl	_taskIdCurrent,%edx	/* %edx = taskIdCurrent */	movl	_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

⌨️ 快捷键说明

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