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

📄 semalib.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
📖 第 1 页 / 共 3 页
字号:
noSemGiveEvt:	/* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */	lbu	v1, SEM_TYPE(a0)		/* put the sem class into v1 */	bne	zero, v1, semGiveNotBinary	/* opt for BINARY if v1==0 */		/* BINARY SEMAPHORE OPTIMIZATION */semBGive:					/* a0 = semId! */	HAZARD_VR5400	mfc0	t0, C0_SR	li	t1, ~SR_INT_ENABLE	and	t1, t1, t0	mtc0	t1, C0_SR			/* LOCK INTERRUPTS */	HAZARD_INTERRUPT	la	t3, semClass			/* get semClass address */	lw	t2, SEM_CLASS(a0)		/* read semIdClass */	bne	t2, t3, semIsInvalidUnlock	/* valid semaphore? */1:	lw	v0, SEM_Q_HEAD(a0)		/* */	lw	t2, SEM_STATE (a0)		/* pOwner */	sw	v0, SEM_STATE(a0)		/* */	bne	zero, v0, semQGet		/* if not empty get from Q */ 	lw	t3, SEM_EVENTS_TASKID (a0)	/* Branch if either previous */	beq	zero, t2, semGiveReturn		/* semOwner or taskId are */	beq	zero, t3, semGiveReturn		/* NULL. *//* * a0 - semId * t0 - was used with interrupts * t1 - was used with interrupts * t3 - semId->events.taskId * v0 - NULL * v1 - NULL */semEvRsrcSend:	li      t4, 1	sw      t4, kernelState                 /* KERNEL ENTER */	HAZARD_VR5400	mtc0  t0, C0_SR                         /* UNLOCK INTERRUPTS */	HAZARD_INTERRUPT	lw      t4, errno	SETFRAME(semBGive,3)                    /* Create stack frame      */	subu    sp, FRAMESZ(semBGive)           /* Create some stack space */	SW      ra, FRAMERA(semBGive)(sp)       /* Save return address     */	SW      t4, FRAMER1(semBGive)(sp)       /* Save errno              */	SW      a0, FRAMER0(semBGive)(sp)       /* Save semId              */	lw      a1, SEM_EVENTS_REGISTERED (a0)  /* semId->events.registered */	move    a0, t3                          /* semId->events.taskId     */	jal     eventRsrcSend                   /* eventRsrcSend (a0, a1)   */ 	LW      a0, FRAMER0(semBGive)(sp)       /* Restore semId  */	LW      t4, FRAMER1(semBGive)(sp)       /* Restore errno  */ 	/*	 * Recall that for boolean expressions, 0 & x = 0, and 1 & x = x.  The	 * return value of eventRsrcSend () is either OK, or ERROR (0, -1).	 * If evSendStatus is the return value ...	 *              evSendStatus & x = {0, evSendStatus}.	 * Thus after AND-ing, a single test can be performed.	 *	 * Also recall for the boolean expressions 0 | x = x, and 1 | x = 1.	 *              evSendStatus | x = {x, 1}	 */ 	move    t3, zero                        /* Default return OK */ 	lb      t5, SEM_OPTIONS (a0)            /* Combine two tests into */	and     t5, t5, v0                      /* one.  Refer to previous */	andi    t5, SEM_EVENTSEND_ERR_NOTIFY    /* comments above. */	beq     t5, zero, semBGiveEvtOptions 	li	t4, S_eventLib_EVENTSEND_FAILED       /* Set new errno */ 	sub     t3, zero, 1                     /* New return value */	sw      zero, SEM_EVENTS_TASKID (a0)    /* Clear taskId */	j       semBGiveEvtOptionsDone semBGiveEvtOptions:	lb      t5, SEM_EVENTS_OPTIONS (a0)     /* Combine two tests into */	or      t5, t5, v0                      /* one.  Refer to previous */	andi    t5, t5, EVENTS_SEND_ONCE        /* comments above. */	beq     t5, zero, semBGiveEvtOptionsDone	sw      zero, SEM_EVENTS_TASKID (a0)    /* Clear taskId */ semBGiveEvtOptionsDone:	SW      t3, FRAMER2(semBGive)(sp)       /* Save retVal to stack */	SW      t4, FRAMER1(semBGive)(sp)       /* Save errno to stack */ 	jal     windExit                        /* KERNEL EXIT */ 	LW      ra, FRAMERA(semBGive)(sp)       /* Restore return address */	LW      a0, FRAMER0(semBGive)(sp)       /* Restore semId */	LW      t4, FRAMER1(semBGive)(sp)       /* Restore errno */	LW      v0, FRAMER2(semBGive)(sp)       /* Restore return value */	addu    sp, FRAMESZ(semBGive)           /* Remove stack frame */	sw      t4, errno                       /* Update errno */ 	j       ra                              /* Return */	/* NEVER FALL THROUGH */semGiveReturn:        HAZARD_VR5400        mtc0    t0, C0_SR               /* UNLOCK INTS */        j       ra                      /* return, v0 still 0 for OK */	/* NEVER FALL THROUGH */semGiveNotBinary:        /* call semGive indirectly via semGiveTbl.  Note that the index could	 * equal zero after it is masked.  semBGive is the zeroeth element	 * of the table, but for it to function correctly in the optimized	 * version above, we must be certain not to clobber a0.  Note, also	 * that old semaphores will also call semBGive above.	 */	andi	v1, 0x7			/* mask v1 */	la	t1, semGiveTbl		/* get table address into t1 */	sll	v1, 2			/* make word indexed */	addu	t1, v1			/* point to give rtn */	lw	t2, 0(t1)		/* get right give rtn for this class */	j	t2			/* invoke give rtn, it will do rts */	.end	semGive/********************************************************************************* semIsInvalid - unlock interupts and call semInvalid ().*/semIsInvalidUnlock:	HAZARD_VR5400	mtc0	t0, C0_SR		/* UNLOCK INTS */semIsInvalid:	j	semInvalid		/* let C rtn do work and rts *//********************************************************************************* semNULLRestrict - set errno and return ERROR** The C routine for semInvalid does not work in the case where a semID is* NULL. It will attempt to ref the NULL semID. Instead, set errno manually & * return*/semNULLRestrict:	li	t0, S_objLib_OBJ_ID_ERROR	/* load error ID */	sw	t0, errno			/* set errno */	li	v0, ERROR			/* return ERROR */	j	ra/********************************************************************************* semTakeIntRestrict - call semIntRestrict ().*/semTakeIntRestrict:	j	semIntRestrict		/* let C rtn do work and rts *//********************************************************************************* semTake - take a semaphore**STATUS semTake (semId, timeout)*    SEM_ID semId;		/* semaphore id to give **    ULONG  timeout;		/* timeout in ticks **/	.ent	semTakesemTake:	beq	a0, zero, semNULLRestrict	/* dont allow NULL ref */	lw	t0, intCnt			/* read intCnt */	bne	zero, t0, semTakeIntRestrict	/* intCnt > 0, no isr use */	andi	t0, a0, 1			/* check if smObj id */	beq	t0, zero, 2f			/* t0==zero, local semaphore */	lw	t1, smObjPoolMinusOne		/* load local pool address */	SETFRAME(semTake,0)	subu	sp, FRAMESZ(semTake)		/* carve stack space */	addu	a0, a0, t1			/* convert id to local addr */	SW	ra, FRAMERA(semTake)(sp)	/* save return address */	/* shared semaphore types are stored in network order	 * we are only interested in the bottom byte so the	 * following works in both bigendian and littleendian configurations	 */	lbu	t2, SEM_SM_TYPE+3(a0)		/* get semaphore type in t2 */	andi	t2, 0x7				/* mask t2 */	la	t3, semTakeTbl			/* load semaphore give table */	sll	t2, 2				/* scale by size of (FUNCPTR) */	addu	t3, t2, t3			/* appropriate give table */	lw	t4, (t3)			/* get appropriate take table */	jal	t4				/* call take func */	LW	ra, FRAMERA(semTake)(sp)	/* get return address */	addu 	sp, FRAMESZ(semTake)		/* pop up stack */	j	ra2:#ifdef WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * semTake level 1 (object status event )	 */	lw	t0, evtAction		    /* is level 1 event collection on? */	beqz	t0, noSemTakeEvt        lw      t3, SEM_CLASS(a0)        la      t0, semClass                    /* check validity */        beq     t3, t0, objOkTake        la      t0, semInstClass                /* check validity */        bne     t3, t0, noSemTakeEvt            /* invalid semaphore */objOkTake:        /* we are checking         * if ((wvEvtClass&(WV_CLASS_3_ON)) != (WV_CLASS_3_ON))         * leave WV instrumentation and check triggering         */        lw      t0, wvEvtClass        li      t4, WV_CLASS_3_ON        and     t0, t0, t4        bne     t4, t0, trgCheckSemTake	/* is this semaphore object instrumented? */        lw      t0, SEM_INST_RTN(t3)            /* event routine attached? */	beqz	t0, noSemTakeEvt	/* log event for this object */        lhu     t2, SEM_RECURSE(a0)        WV_SETFRAME(semTakeInst,11)        subu    sp, WV_FRAMESZ(semTakeInst) /* create stack frame */        sw      ra, WV_FRAMERA(semTakeInst)(sp) /* save ra */        sw      a0, WV_FRAMEA0(semTakeInst)(sp)    /* and a0 */        sw      a1, WV_FRAMEA1(semTakeInst)(sp)    /* and a0 */        sw      t2, WV_FRAMER0(semTakeInst)(sp) /* pass t2, 5th arg to func */        sw      zero, WV_FRAMER1(semTakeInst)(sp) /* pass 0 to 6th arg */        sw      zero, WV_FRAMER2(semTakeInst)(sp) /* pass 0 to 7th arg */        /* now save the rest of the volatile register set.         * This is to ensure that when we come back from the C         * function callout, all the register are as they were         * before the call since we don't know what registers         * the C functions have trashed that the assembly files         * might rely on.         */        /*         * no need to save t0 & t4, gets trashed right after the         * function call anyways.         */        sw      v0, WV_FRAMER3(semTakeInst)(sp)         /* save v0 */        sw      t1, WV_FRAMER4(semTakeInst)(sp)         /* save t1 */        sw      t3, WV_FRAMER5(semTakeInst)(sp)         /* save t3 */        sw      t5, WV_FRAMER6(semTakeInst)(sp)         /* save t5 */        sw      t6, WV_FRAMER7(semTakeInst)(sp)         /* save t6 */        sw      t7, WV_FRAMER8(semTakeInst)(sp)         /* save t7 */        sw      t8, WV_FRAMER9(semTakeInst)(sp)        /* save t8 */        sw      t9, WV_FRAMER10(semTakeInst)(sp)        /* save t9 */        lw      a3, SEM_STATE(a0)        move    a2, a0                          /* a2 = semID */        li      a1, 3                           /* # of args passed to func */        li      a0, EVENT_SEMTAKE               /* event ID */        jal     t0                              /* call routine */        /* now restore all the stuff we have saved */        lw      t9, WV_FRAMER10(semTakeInst)(sp)        lw      t8, WV_FRAMER9(semTakeInst)(sp)        lw      t7, WV_FRAMER8(semTakeInst)(sp)        lw      t6, WV_FRAMER7(semTakeInst)(sp)        lw      t5, WV_FRAMER6(semTakeInst)(sp)        lw      t3, WV_FRAMER5(semTakeInst)(sp)        lw      t1, WV_FRAMER4(semTakeInst)(sp)        lw      v0, WV_FRAMER3(semTakeInst)(sp)        lw      t2, WV_FRAMER0(semTakeInst)(sp)        lw      a0, WV_FRAMEA0(semTakeInst)(sp)        lw      a1, WV_FRAMEA1(semTakeInst)(sp)        lw      ra, WV_FRAMERA(semTakeInst)(sp)        addu    sp, WV_FRAMESZ(semTakeInst)trgCheckSemTake:        lw      t0, trgEvtClass        li      t4, TRG_CLASS_3_ON        and     t0, t0, t4        bne     t4, t0, noSemTakeEvt        lhu     t2, SEM_RECURSE(a0)        lw      t1, SEM_STATE(a0)        WV_SETFRAME(semTakeTrg,11)        subu    sp, WV_FRAMESZ(semTakeTrg) /* create stack frame */        sw      ra, WV_FRAMERA(semTakeTrg)(sp) /* save ra */        sw      a0, WV_FRAMEA0(semTakeTrg)(sp)    /* and a0 */        sw      a1, WV_FRAMEA1(semTakeTrg)(sp)    /* and a0 */        sw      t1, WV_FRAMER0(semTakeTrg)(sp) /* save t1, 5th arg to func */        sw      t2, WV_FRAMER1(semTakeTrg)(sp) /* save t2, 6th arg to func */        /* now save the rest of the volatile register set.         * This is to ensure that when we come back from the C         * function callout, all the register are as they were         * before the call since we don't know what registers         * the C functions have trashed that the assembly files         * might rely on.         */        /* No need to save t0 & t4, since they are trashed above */        sw      zero, WV_FRAMER2(semTakeTrg)(sp)        /* 7th arg to func */        sw      zero, WV_FRAMER3(semTakeTrg)(sp)        /* 8th arg to func */        sw      v0, WV_FRAMER4(semTakeTrg)(sp)         /* save v0 */        sw      t3, WV_FRAMER5(semTakeTrg)(sp)         /* save t3 */        sw      t5, WV_FRAMER6(semTakeTrg)(sp)         /* save t5 */        sw      t6, WV_FRAMER7(semTakeTrg)(sp)         /* save t6 */        sw      t7, WV_FRAMER8(semTakeTrg)(sp)        /* save t7 */        sw      t8, WV_FRAMER9(semTakeTrg)(sp)        /* save t8 */        sw      t9, WV_FRAMER10(semTakeTrg)(sp)        /* save t9 */        lw      a3, SEM_STATE(a0)        move    a3, a0        move    a2, a0        li      a0, EVENT_SEMTAKE	li      a1, TRG_CLASS3_INDEX        lw      t1, _func_trgCheck        jal     t1                              /* call trgCheck routine */        /* Now restore */        lw      t9, WV_FRAMER10(semTakeTrg)(sp)        lw      t8, WV_FRAMER9(semTakeTrg)(sp)        lw      t7, WV_FRAMER8(semTakeTrg)(sp)        lw      t6, WV_FRAMER7(semTakeTrg)(sp)        lw      t5, WV_FRAMER6(semTakeTrg)(sp)        lw      t3, WV_FRAMER5(semTakeTrg)(sp)        lw      v0, WV_FRAMER4(semTakeTrg)(sp)        lw      t2, WV_FRAMER1(semTakeTrg)(sp)        lw      t1, WV_FRAMER0(semTakeTrg)(sp)        lw      a0, WV_FRAMEA0(semTakeTrg)(sp)        lw      a1, WV_FRAMEA1(semTakeTrg)(sp)        lw      ra, WV_FRAMERA(semTakeTrg)(sp)        addu    sp, WV_FRAMESZ(semTakeTrg)noSemTakeEvt:	/* windview instrumentation - END */#endif /* WV_INSTRUMENTATION */	lbu	v1, SEM_TYPE(a0)		/* get semaphore class						   into v1 */	bne	zero, v1, semTakeNotBinary	/* optimize binary						   semaphore v1 == 0 */		/* BINARY SEMAPHORE OPTIMIZATION */semBTake:					/* a0 = semId! */	.set	noreorder	HAZARD_VR5400	mfc0	t0, C0_SR	HAZARD_CP_READ	li	t1, ~SR_INT_ENABLE	and	t1, t1, t0	mtc0	t1, C0_SR			/* LOCK INTERRUPTS */	HAZARD_INTERRUPT	la	t3, semClass			/* get semClass address */	.set	reorder	lw	t2, SEM_CLASS(a0)		/* read semIdClass */	bne	t2, t3, semIsInvalidUnlock	/* valid semaphore? */1:	lw	v0, SEM_STATE(a0)		/* test for owner */	bne	zero, v0, semQPut		/* if sem is owned we block */	lw	t3, taskIdCurrent		/* get tidc */	sw	t3, SEM_STATE(a0)		/* now we own it */	HAZARD_VR5400	mtc0	t0, C0_SR			/* UNLOCK INTS */	HAZARD_INTERRUPT	j	ra				/* return, v0 still zero */semTakeNotBinary:	andi	v1, 0x7			/* mask v1 to sane value */	la	t1, semTakeTbl		/* get table address into t1 */	sll	v1, 2			/* make word indexed */

⌨️ 快捷键说明

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