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

📄 windalib.s

📁 vxworks的源代码
💻 S
📖 第 1 页 / 共 4 页
字号:
* idle state because doWork will make subroutine calls that use the stack.  We* don't want to be on another tasks stack, we can't be on the interrupt* stack because intCnt == 0, and any interrupt would muck our stack.*/	.ent	idleidle:#ifdef WV_INSTRUMENTATION        /*         * windview instrumentation - BEGIN         * enter idle state         *         */        lw      t1, evtAction                   /* is instrumentation on? */        beqz    t1, noInstIdle	HAZARD_VR5400        mfc0    t2, C0_SR        li      t1, ~SR_INT_ENABLE        and     t1, t1, t2        mtc0    t1, C0_SR               /* LOCK INTERRUPTS */	HAZARD_INTERRUPT        lw      t0, wvEvtClass                   /* is instrumentation on? */        li      t1, WV_CLASS_1_ON                   /* is instrumentation on? */        and     t0, t0, t1        bne     t1, t0, trgCheckIdle        SETFRAME(idle,0)        subu    sp,FRAMESZ(idle)        li      a0, EVENT_WIND_EXIT_IDLE        lw      t1, _func_evtLogT0        jal     t1                              /* call evtLogT0 routine */noInstIdleRestore:        addu    sp, FRAMESZ(idle)trgCheckIdle:        lw      t0, trgEvtClass        li      t1, TRG_CLASS_1_ON        and     t0, t0, t1        bne     t1, t0, noInstIdle        SETFRAME(idle,0)        subu    sp,FRAMESZ(idle)        li      a0, EVENT_WIND_EXIT_IDLE        li      a1, TRG_CLASS1_INDEX        li      a2, 0x0        lw      t1, _func_trgCheck        jal     t1                              /* call trgCheck routine */        addu    sp, FRAMESZ(idle)noInstIdle:        /* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */	lw	t2, taskSrDefault	/* load default SR value */	li	t0, 1			/* load idle flag to reg */	HAZARD_VR5400	mtc0    t2, C0_SR        	/* UNLOCK INTERRUPTS */	sw	t0, kernelIsIdle	/* set idle flag for spyLib */idleLoop:	lw	t1, workQIsEmpty	/* if work queue is still empty */	bne	zero, t1, idleLoop	/* keep hanging around */	sw	zero, kernelIsIdle	/* unset idle flag for spyLib */	j	doWork			/* go do the work */	.end	idle/********************************************************************************* doSwapHooks - execute the tasks' swap hooks** S-regs are used for variables that must be preserved across* procedure calls.  We need not restore the S-regs because* kernelState = TRUE, so we will never overwrite them due* to an interrupt thread, and all registers are now available* for use at this point (tcb's acurrately saved).*/doSwapHooks:	SETFRAME(doSwapHooks,0)	subu	sp, FRAMESZ(doSwapHooks) /* make room for 2 params and ra */	move	s0, t0			/* load pointer to old tcb */	move	s1, t1			/* load pointer to new tcb */	la	s2, taskSwapTable	/* get adrs of task switch rtn list */	move	s3, t3			/* put mask in saved reg */	li	s4, 0x10000		/* load ending condition into reg */	j	doSwapShift		/* jump into the loop */doSwapHook:	move	a0, s0			/* pass taskIdPrevious */	move	a1, s1			/* pass taskIdCurrent */	lw	t1, -4(s2)		/* get task switch rtn into t1 */	jal	t1			/* call routine */doSwapShift:	andi	t2, s3, 0x8000		/* mask bit set ? */	sll	s3, 1			/* shift swapMask bit pattern left */	addi	s2, 4			/* increment taskSwapTable */	bne	zero, t2, doSwapHook	/* yes, call SwapHook */	blt	s3, s4, doSwapShift	/* if mask > 0x8000 all done */	addi	sp, FRAMESZ(doSwapHooks) /* clean up stack */	move	t1, s1			/* restore t1 with taskIdCurrent */	lw	t0, taskSwitchTable	/* any global switch hooks? */	beq	zero, t0, dispatch	/* if no then dispatch taskIdCurrent */	j	doSwitchFromSwap	/* do switch routines from swap *//********************************************************************************* doSwitchHooks - execute the global switch hooks*/doSwitchHooks:	move	s0, t0			/* load pointer to old tcb */	move	s1, t1			/* load pointer to new tcb */doSwitchFromSwap:	SETFRAME(doSwitchHooks,0)	subu	sp, FRAMESZ(doSwitchHooks) /* make room for 2 params and ra */	la	s2, taskSwitchTable	/* get adrs of task switch rtn list */	lw	t1, 0(s2)		/* get task switch rtn into t1 */doSwitchHook:	move	a0, s0			/* pass taskIdPrevious */	move	a1, s1			/* pass taskIdCurrent */	jal	t1			/* call routine */	addu	s2, 4			/* bump to next task switch routine */	lw	t1, 0(s2)		/* get next task switch rtn */	bne	zero, t1, doSwitchHook	/* loop */	move	t1, s1			/* restore t1 with taskIdCurrent */	addu	sp, FRAMESZ(doSwitchHooks) /* clean up stack */	j	dispatch		/* dispatch task *//********************************************************************************* doWork - empty the work queue* doWorkUnlock - unlock interrupts and empty the work queue** For doWorkUnlock, t0 must contain the value of the R3k SR before* interrupts were locked.  We do not need to preserve the ra on a* stack in these cases because state has been fully preserved at * this point.**/doWorkUnlock:	HAZARD_VR5400	mtc0	t0, C0_SR		/* UNLOCK interrupts */doWork:	jal	workQDoWork		/* empty the work queue */	lw	t0, taskIdCurrent	/* put taskIdCurrent into t0 */	lw	t1, readyQHead		/* get highest task to t1 */	beq	zero, t1, idle		/* nobody is ready so spin */	beq	t0, t1, dispatch	/* if the same dispatch */	j	switchTasks		/* not same, do switch */#else /* PORTABLE	portable version of windExit() and windLoadContext() *//********************************************************************************* windExitInt - exit kernel routine from interrupt level** windExit branches here if exiting kernel routine from int level* No rescheduling is necessary because the ISR will exit via intExit, and* intExit does the necessary rescheduling.*/windExitIntWork:	SETFRAME(windExitIntWork,0)	subu	sp, FRAMESZ(windExitIntWork)	 /* need some stack */	SW	ra, FRAMERA(windExitIntWork)(sp) /* save ra */	mtc0    t2, C0_SR        		 /* UNLOCK INTS */	jal	workQDoWork			 /* empty the work queue */	LW	ra, FRAMERA(windExitIntWork)(sp) /* restore ra */	addu	sp, FRAMESZ(windExitIntWork)	 /* restore stack */	.ent 	windExitIntwindExitInt:	mfc0	t2, C0_SR	HAZARD_CP_READ	li	t1, ~SR_INT_ENABLE	and	t1, t1, t2	mtc0	t1, C0_SR			/* LOCK INTERRUPTS */	HAZARD_INTERRUPT	lw	t0, workQIsEmpty		/* test for work to do */	beq	zero, t0, windExitIntWork	/* workQueue is not empty */	move	v0, zero			/* return OK */	sw      zero, kernelState 		/* else release exclusion */	mtc0    t2, C0_SR        		/* UNLOCK INTERRUPTS */	j       ra		 		/* back to calling task */	.end	windExitInt/******************************************************************************** windExit - PORTABLE VERSION of task level exit from kernel** This is the way out of kernel mutual exclusion.  If a higher priority task* than the current task is ready, then we invoke the rescheduler.  We* also invoke the rescheduler if any interrupts have occured which have added* work to the windWorkList.  If rescheduling is necessary,* the context of the calling task is saved with the PC pointing at the* next instruction after the jsr to this routine.  The SP in the tcb is* modified to ignore the return address on the stack.  Thus the context saved* is as if this routine was never called.** NOMANUAL* void windExit ()*/  	.ent	windExitwindExit:	lw      t0,intCnt			/* (intCnt == 0) == task code */	bne     zero, t0, windExitInt		/* exiting interrupt code? */taskCode:	lw	t0, taskIdCurrent		/* move taskIdCurrent into t0 */	lw	t1, readyQHead			/* compare highest ready task */	beq	t0, t1, checkWorkQ		/* if same then check workQ */	lw	t2, WIND_TCB_LOCK_CNT(t0)	/* allowed to switch tasks? */	beq	zero, t2, saveTaskContext	/* if yes, save task context */	lw	t2, WIND_TCB_STATUS(t0)		/* is task ready to run? */	bne	zero, t2, saveTaskContext	/* we blocked while taskLocked*/checkWorkQ:	mfc0	t2, C0_SR	HAZARD_CP_READ	li	t1, ~SR_INT_ENABLE	and	t1, t1, t2	mtc0	t1, C0_SR			/* LOCK INTERRUPTS */	HAZARD_INTERRUPT		lw	k0, workQIsEmpty		/* test for work to do */	beq	zero, k0, saveTaskContextUL	/* workQueue is not empty */	sw	zero, kernelState		/* else release exclusion */	mtc0    t2, C0_SR        		/* UNLOCK INTERRUPTS */	move	v0, zero			/* return OK */	j	ra				/* back to calling task */saveTaskContextUL:	mtc0    t2, C0_SR        		/* UNLOCK INTERRUPTS */saveTaskContext:	lw 	t1, errno	HAZARD_VR5400	mfc0	t2, C0_SR			/* make sure we have sr */	HAZARD_CP_READ	sw	t1, WIND_TCB_ERRNO(t0)		/* save errno */	SW	sp, WIND_TCB_SP(t0)	   	/* save stack pointer */	sw	ra, WIND_TCB_PC(t0)	   	/* save ra to be new PC 						   after call to here */	sw      t2, WIND_TCB_SR(t0)     	/* save SR in entirety */						/* load saved registers */						/* less volatile t0-t9 */	SW	zero, WIND_TCB_V0(t0)	   	/* windExit() returns OK */	mflo	t1	SW	t1, WIND_TCB_LO(t0)	mfhi	t2	SW	t2, 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	s8, WIND_TCB_S8(t0)	j	reschedule			/* goto rescheduler */	.end	windExit/********************************************************************************* 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.  This means that all registers * are available for usage since the prior task context was saved* before reschedule was called. There is no exception stack frame in the * MIPS architecture so none is simulated in doing the context switch.* Previous interrupt state and new context is restored. For R3k processors* a jump to PC places us in the new context. For all other ISA's, switching to* the new context is accomplished via an 'eret' and the EPC. ** Interrupts are locked on entry to this routine so moving the old status * register to the processor with a mtc0 will re-enable interrupts if previously * enabled. This is not an issue for non-R3k processors because the EXL bit is * being set in anticipation of the 'eret'. Interrupts are disabled by virtue of* it being set.** K1 and K0 are available for kernel use but ONLY in non-interruptible sections.** NOMANUAL* void windLoadContext ()*/	.ent	windLoadContextwindLoadContext:	lw      t0, taskIdCurrent   		/* current tid */	lw	t1, WIND_TCB_ERRNO(t0)		/* read errno */	LW	a0, WIND_TCB_A0(t0) 		/* restore saved registers */	LW	a1, WIND_TCB_A1(t0)	LW	a2, WIND_TCB_A2(t0)	LW	a3, WIND_TCB_A3(t0)	sw	t1, errno			/* save errno */	LW	v0, WIND_TCB_V0(t0)	LW	v1, WIND_TCB_V1(t0)	LW	t1, WIND_TCB_T1(t0)	LW	t2, WIND_TCB_T2(t0)	LW	t3, WIND_TCB_LO(t0)	LW	t4, WIND_TCB_HI(t0)	mtlo	t3	mthi	t40:	LW	t3, WIND_TCB_T3(t0)	LW	t4, WIND_TCB_T4(t0)	LW	t5, WIND_TCB_T5(t0)	LW	t6, WIND_TCB_T6(t0)	LW	t7, WIND_TCB_T7(t0)	LW	s0, WIND_TCB_S0(t0)	LW	s1, WIND_TCB_S1(t0)	LW	s2, WIND_TCB_S2(t0)	LW	s3, WIND_TCB_S3(t0)	LW	s4, WIND_TCB_S4(t0)	LW	s5, WIND_TCB_S5(t0)	LW	s6, WIND_TCB_S6(t0)	LW	s7, WIND_TCB_S7(t0)	LW	t8, WIND_TCB_T8(t0)	LW	t9, WIND_TCB_T9(t0)	LW      s8, WIND_TCB_S8(t0)	LW	ra, WIND_TCB_RA(t0)		/* restore return addr */	lw	k1, WIND_TCB_SR(t0)		/* load status register */

⌨️ 快捷键说明

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