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

📄 windalib.s

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 S
📖 第 1 页 / 共 3 页
字号:
/********************************************************************************* 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 ()*/_windLoadContext:	movl	_taskIdCurrent,%eax		/* current tid */	movl	WIND_TCB_ERRNO(%eax),%ecx	/* save 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	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 ()*/	.align 4,0x90_intEnt:	pushl	(%esp)			/* bump return address up a notch */	pushl	%eax	movl	_errno,%eax		/* save errno where return adress was */	movl	%eax,8(%esp)	popl	%eax	incl	_intCnt			/* Bump the counter */#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * enter an interrupt handler. 	 *	 * ALL registers must be saved.  	 */        cmpl    $0,_evtAction           /* is WindView on? */        je	noIntEnt	pushal                          /* save regs */	cli				/* LOCK INTERRUPTS */	movl	32(%esp),%edi		/* use %edi to store the return address */	movl	$ WV_CLASS_1_ON,%eax        andl    _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_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    _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_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:	sti	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.*/	.align 4,0x90_intExit:	popl	_errno			/* restore errno */	pushl	%eax			/* push %eax onto interrupt 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,_evtAction           /* is WindView on? */        je	noIntExit        pushl	%edx        pushl	%ecx	cli	movl	$ WV_CLASS_1_ON,%eax        andl    _wvEvtClass,%eax          /* is event collection on? */        cmpl    $ WV_CLASS_1_ON,%eax          /* is event collection on? */        jne     trgCheckIntExit	movl	__func_evtLogT0,%edx	/* event log routine */	cmpl	$0,%edx	je	trgCheckIntExit        cmpl	$0,_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    _trgEvtClass,%eax       /* any trigger? */        jne      intExitClean        movl    __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,_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:	sti					/* UNLOCK INTERRUPTS */        popl	%ecx				/* restore regs */        popl	%edxnoIntExit:        /* windview instrumentation - END */#endif  /* WV_INSTRUMENTATION */	decl	_intCnt			/* decrement intCnt */	cmpl	$0,_kernelState		/* if kernelState == TRUE then */	jne	intRte			/*  just clean up and rte */        movw	8(%esp),%ax		/* if CS on stack and CS on IDT is */        cmpw	_intIdtSelector,%ax	/*  same, then we were */        je	intRte			/*  in an ISR so just clean up/rte */	cli				/* LOCK INTERRUPTS */	movl	_taskIdCurrent,%eax	/* put current task in %eax */	cmpl	_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). */	.align 4,0x90saveIntContext:	/* interrupts are still locked out */	movl	$1,_kernelState			/* kernelState = TRUE; */	movl	_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	_errno,%edx			/* save errno */	movl	%edx,WIND_TCB_ERRNO(%eax)	movl	%eax,%edx			/* taskIdCurrent into %edx */	jmp	_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 ()*/	.align 4,0x90_vxTaskEntry:	xorl	%ebp,%ebp		/* make sure frame pointer is 0 */	movl	_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	_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.** NOMANUAL* void windIntStackSet (pBotStack)*     char *pBotStack;	/* pointer to bottom of interrupt stack **/	.align 4,0x90_windIntStackSet:	ret

⌨️ 快捷键说明

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