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

📄 windalib.s

📁 vxworks的源代码
💻 S
📖 第 1 页 / 共 4 页
字号:
	lw	k0, WIND_TCB_PC(t0)		/* restore PC */	LW	sp, WIND_TCB_SP(t0)		/* restore task stack pointer */	.set	noat	LW	AT, WIND_TCB_AT(t0)  	LW	t0, WIND_TCB_T0(t0)	.set	noreorder#ifdef _WRS_R3K_EXC_SUPPORT	j	k0				/* context switch */	mtc0	k1, C0_SR			/* restore status register */#else	mtc0	k0, C0_EPC	ori	k1, SR_EXL	mtc0	k1, C0_SR	HAZARD_CP_WRITE	eret#endif	.set	reorder	.set	at	.end 	windLoadContext #endif /* PORTABLE *//********************************************************************************* intEnt - enter an interrupt service routine** This routine has been inlined in the common interrupt stub for* performance reasons on the R3k.** INTERNAL* On the R3K only three instructions are* needed therefore this routine is never called.* Also intCnt is used to discover if interrupts are nested.* .CS**    lw      k1, intCnt   /* grab contents of intCnt*    ...*    addu    k1, 1        /* increment intCnt*    sw      k1, intCnt   /* update value* .CE** SEE ALSO: excIntStub()*/    /* xxx *//********************************************************************************* 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, SR and SP 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.** 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 t0.** Restoration of errno has been moved into the common interrupt stub* for performance reasons on the R3k.** SEE ALSO: intConnect(2)* void intExit ()*/	.ent	intExitintExit:					/* we are on the interrupt stack here */	SETFRAME(intExit,3)	subu 	sp, FRAMESZ(intExit)	/* get some work space */	SW	t0, FRAMER0(intExit)(sp) /* store registers which are used */	SW	t1, FRAMER1(intExit)(sp)	SW	t2, FRAMER2(intExit)(sp)#ifdef WV_INSTRUMENTATION        /*         * windview instrumentation - BEGIN         * log event if work has been done in the interrupt handler.         */        lw      t0, evtAction                   /* is WV/triggering on? */        beqz    t0, noIntExit        lw      t0, wvEvtClass                   /* is WV instrumentation on? */        li      t4, WV_CLASS_1_ON                           and     t0, t0, t4        bne     t4, t0, trgCheckIntExit        /*         * don't bother to save registers - they are all in         * the exception frame         */        lw      t2, workQIsEmpty                /* work in work queue? */        li      a0, EVENT_INT_EXIT              /* event id */        bnez    t2, intExitEvent        li      a0, EVENT_INT_EXIT_K            /* event id */intExitEvent:        lw      t1, _func_evtLogT0        jal     t1                              /* call evtLogT0 routine */trgCheckIntExit:        lw      t0, trgEvtClass        li      t4, TRG_CLASS_1_ON        and     t0, t0, t4        bne     t4, t0, intExitBufOverflow        lw      t2, workQIsEmpty                /* work in work queue? */        li      a0, EVENT_INT_EXIT              /* event id */        bnez    t2, trgIntExitEvent        li      a0, EVENT_INT_EXIT_K            /* event id */trgIntExitEvent:	li      a1, TRG_CLASS1_INDEX	li      a2, 0x0        lw      t1, _func_trgCheck        jal     t1                              /* call trgCheck routine */intExitBufOverflow:        /* restore all registers */        LW      t0,FRAMESZ(intExit)+E_STK_HI(sp) /* grab entry lo reg    */        LW      t1,FRAMESZ(intExit)+E_STK_LO(sp) /* grab entry hi reg    */        mthi    t0                               /* restore entry hi reg */        mtlo    t1                               /* restore entry hi reg */0:        LW      v0,FRAMESZ(intExit)+E_STK_V0(sp) /* restore func ret 0   */        LW      v1,FRAMESZ(intExit)+E_STK_V1(sp) /* restore func ret 1   */        LW      a0,FRAMESZ(intExit)+E_STK_A0(sp) /* restore passed param 0 */        LW      a1,FRAMESZ(intExit)+E_STK_A1(sp) /* restore passed param 1 */        LW      a2,FRAMESZ(intExit)+E_STK_A2(sp) /* restore passed param 2 */        LW      a3,FRAMESZ(intExit)+E_STK_A3(sp) /* restore passed param 3 */                                                 /* restore temp reg 0 (below) */                                                 /* restore temp reg 1 (below) */                                                 /* restore temp reg 2 (below) */        LW      t3,FRAMESZ(intExit)+E_STK_T3(sp) /* restore temp reg 3            */        LW      t4,FRAMESZ(intExit)+E_STK_T4(sp) /* restore temp reg 4 */        LW      t5,FRAMESZ(intExit)+E_STK_T5(sp) /* restore temp reg 5 */        LW      t6,FRAMESZ(intExit)+E_STK_T6(sp) /* restore temp reg 6 */        LW      t7,FRAMESZ(intExit)+E_STK_T7(sp) /* restore temp reg 7 */        LW      t8,FRAMESZ(intExit)+E_STK_T8(sp) /* restore temp reg 8 */        LW      ra,FRAMESZ(intExit)+E_STK_RA(sp) /* restore return addr */        LW      t9,FRAMESZ(intExit)+E_STK_T9(sp) /* restore temp reg 9 */noIntExit:        /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */	lw	t0, intCnt		subu	t0, 1	sw	t0, intCnt		/* decrement intCnt */	lw	t1, areWeNested		/* load nested boolean */	subu	t1, 1			/* decrement */	sw	t1, areWeNested		/* store nested boolean */	lw      t2, kernelState 	/* if kernelState == TRUE */	bne	t2, zero, intRte	/* then just clean up and rte */ 	bne     t1, zero, intRte	/* if nested int then just rte */	lw	t0, taskIdCurrent	/* put current task in t0 */	lw	t2, readyQHead 	 	/* compare to highest ready task */	beq	t0, t2, intRte       	/* if same then don't reschedule */	lw	t1, WIND_TCB_LOCK_CNT(t0)	/* is task preemption allowed */	beq	zero, t1, saveIntContext	/* if yes, then save context */	lw	t1, WIND_TCB_STATUS(t0)		/* is task ready to run */	bne	zero, t1, saveIntContext	/* if no, then save context */intRte:	LW	t0, FRAMER0(intExit)(sp)	/* restore registers used locally */	LW	t1, FRAMER1(intExit)(sp)	LW	t2, FRAMER2(intExit)(sp)	addu	sp, FRAMESZ(intExit)		/* recover stack work space */	.set 	noreorder	.set	noat	lw	k0, E_STK_EPC(sp)	/* get the exception program counter */	LW	AT, E_STK_AT(sp)	/* restore AT reg		*/	LW	sp, E_STK_SP(sp)	/* restore the task stack pointer,				   	   no need to pop temp stack now */#ifdef _WRS_R3K_EXC_SUPPORT	j	k0			/* return to previous context */	rfe				/* RESTORE INTERRUPTS */#else	HAZARD_VR5400	mtc0	k0,C0_EPC		/* return to previous context */	HAZARD_ERET	eret				/* RESTORE INTERRUPTS */#endif	.set	at	.set 	reorder/* 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 (ISP, MSP). */  saveIntContext:	/* interrupts are still locked out */	li	t1, 1 				/* kernelState = TRUE; */	sw	t1, kernelState 			lw	k0, taskIdCurrent		/* tcb to be fixed up */	lw	t0, errno	sw	t0, WIND_TCB_ERRNO(k0)		/* save errno */	LW	t0, FRAMER0(intExit)(sp)	/* restore working registers */	LW	t1, FRAMER1(intExit)(sp)				LW	t2, FRAMER2(intExit)(sp)	SW 	t0, WIND_TCB_T0(k0)		/* and save in TCB */	SW	t1, WIND_TCB_T1(k0)				SW	t2, WIND_TCB_T2(k0)				move	t0, k0				/* use t0 as taskIdCurrent */	addu	sp, FRAMESZ(intExit)		/* recover stack work space */	lw	t2, E_STK_EPC(sp)		/* get the exception PC */	LW	t1, E_STK_SP(sp)		/* get the process SP */	sw	t2, WIND_TCB_PC(t0)		/* store exception PC in TCB */	SW	t1, WIND_TCB_SP(t0)		/* store regs in tcb */	.set	noat	LW	AT, E_STK_AT(sp)	SW	AT, WIND_TCB_AT(t0) 	.set	at	mfc0	k1, C0_SR	HAZARD_CP_READ#ifdef _WRS_R3K_EXC_SUPPORT	/* modify the status register ready to store in the task TCB */	and 	k0, k1, SR_KUMSK	and	k1, ~SR_KUMSK	srl	k0, 2	or	k1, k0#else	and	k1,~SR_EXL#endif	sw	k1, WIND_TCB_SR(t0)		/* store sr in TCB */	move	sp, t1				/* work off task stack */	mtc0	k1, C0_SR			/* UNLOCK INTERRUPTS *//**	A window of vulnerabilty opens up here on the R3000.  We need to* 	have epc,sp,and AT restored and have begun working off the task stack *	by now.  This is because intCnt == 0, and if we get interrupted*	excIntStub will reset and muck the stack.*/						/* store registers starting */	SW	t3, WIND_TCB_T3(t0)             /*    with remaining  temp  */	SW	t4, WIND_TCB_T4(t0)		/*    registers so work     */	SW	t5, WIND_TCB_T5(t0)		/*    are available         */	SW	t6, WIND_TCB_T6(t0)	SW	t7, WIND_TCB_T7(t0)	SW	a0, WIND_TCB_A0(t0)		/* save remaining registers  */	SW	a1, WIND_TCB_A1(t0)		/*    in TCB                 */	SW	a2, WIND_TCB_A2(t0)	SW	a3, WIND_TCB_A3(t0)	SW	v0, WIND_TCB_V0(t0)	SW	v1, WIND_TCB_V1(t0)	mflo	v0	mfhi	v1	SW	v0, WIND_TCB_LO(t0)	SW	v1, WIND_TCB_HI(t0)0:	SW	s0, WIND_TCB_S0(t0)	SW	s1, WIND_TCB_S1(t0)	SW	s2, WIND_TCB_S2(t0)	SW	s3, WIND_TCB_S3(t0)	SW	s4, WIND_TCB_S4(t0)	SW	s5, WIND_TCB_S5(t0)	SW	s6, WIND_TCB_S6(t0)	SW	s7, WIND_TCB_S7(t0)	SW	t8, WIND_TCB_T8(t0)	SW	t9, WIND_TCB_T9(t0)	SW      s8, WIND_TCB_S8(t0)	SW	ra, WIND_TCB_RA(t0)			j	reschedule			/* goto rescheduler */	.end 	intExit/********************************************************************************* 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 () */	.ent	vxTaskEntryvxTaskEntry:   	/* stack frame for 10 parameters created in taskLib */	lw      t0, taskIdCurrent  /* get current task id */	lw      t1, WIND_TCB_ENTRY(t0)	/* entry point for task is in tcb */	jal     t1 		   /* call main routine */	move    a0, v0 		   /* pass result to exit */	jal     exit		   /* gone for good */	.end vxTaskEntry/********************************************************************************* 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 **/  	.ent windIntStackSetwindIntStackSet:	j	ra 		/* just return */	.end windIntStackSet

⌨️ 快捷键说明

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