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

📄 syslib.c

📁 VxWorkS下 MV2604的BSP源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    break;	case VME_AM_STD_SUP_PGM:	case VME_AM_STD_USR_PGM:	case VME_AM_STD_SUP_DATA:	case VME_AM_STD_USR_DATA:	    if ((VME_A24_MSTR_SIZE == 0) ||		((ULONG) busAdrs < VME_A24_MSTR_BUS) ||		((ULONG) busAdrs >= (VME_A24_MSTR_BUS + VME_A24_MSTR_SIZE)))		{		return (ERROR);		}	    *pLocalAdrs = (char *) busAdrs +			    (VME_A24_MSTR_LOCAL - VME_A24_MSTR_BUS);	    return (OK);	    break;        case VME_AM_SUP_SHORT_IO:        case VME_AM_USR_SHORT_IO:#	    if (VME_A16_MSTR_SIZE == 0)	        return (ERROR);#           else	    	    if(((ULONG) busAdrs < VME_A16_MSTR_BUS) ||	       ((ULONG) busAdrs >= (VME_A16_MSTR_BUS + VME_A16_MSTR_SIZE)))	       {		return (ERROR);	       }            *pLocalAdrs = (char *) busAdrs + 			    (VME_A16_MSTR_LOCAL - VME_A16_MSTR_BUS);            return (OK);#endif	default:	    return (ERROR);	}    }/********************************************************************************* sysBusTas - test and set a specified location** This routine performs a test-and-set (TAS) instruction on the specified* address.  To prevent deadlocks, interrupts are disabled during the* test-and-set operation.  The following table defines the method used to* insure an atomic operation.** .CS*		Master		Slave_1		Slave_2** VME Chip	Don't Care	U1		U1*		----------	----		----* Method	VOWN		VOWN		VOWN** VME Chip	Don't Care	U1		U2*		----------	----		----* Method	VOWN		VOWN		RMW** VME Chip	U1 or		U2		U2*		U2+*		----------	----		----* Method	VOWN+++		RMW		RMW** VME Chip	U2++		U2		U2* PCI Bridge	or Raven3*		----------	----		----* Method	lwarx/stwcx	RMW		RMW**  +   = Refer to target.txt file for explaination of older boards*	 with Universe II (U2).*  ++  = Refer to target.txt file for explaination of newer boards*	 with Universe II (U2).*  +++ = The master's hardware does not preserve the atomic RMW.* ++++ = If SM_OFF_BOARD == TRUE,  the method used will be the same*	 as if the master board is acting like a slave board; namely:*	 	RMW for UNIVERSE_II and VOWN for UNIVERSE_I* .CE** NOTE: Although the address passed-in to sysBusTas() is defined as* "char *", vxTas() operates on the address as a "void *".* For PowerPC, this implies that the location tested-and-set is* actually a 32-bit entity.* * RETURNS: TRUE if the value had not been set but is now, or* FALSE if the value was set already.** SEE ALSO: vxTas(), sysBusTasClear()*/BOOL sysBusTas    (    char * adrs          /* address to be tested and set */    )    {    /* Check for master node */    if (sysProcNumGet() == 0)	{#ifdef	ANY_BRDS_IN_CHASSIS_NOT_RMW	/*	 * A slave board in the chassis cannot generate a VMEbus RMW,	 * and/or the master board cannot translate an incoming VMEbus	 * RMW into an atomic operation, and/or the master board cannot	 * generate a VMEbus RMW; therefore, the master must set	 * VOWN before doing a TAS.	 */	return (sysVmeVownTas(adrs));#else#if	(SM_OFF_BOARD == FALSE)        BOOL state = FALSE;  /* semaphore state */        int  lockKey;        /* interrupt lock key */	/* 	 * All slave boards in the chassis are generating a VMEbus RMW, and	 * the master board can translate an incoming VMEbus RMW into an	 * atomic operation; therefore, the master can simply call vxTas()	 * (lwarx/stwcx sequence) because the write portion of the RMW will	 * be detected.	 */        /* lock interrupts so that vxTas() can execute without preemption */        lockKey = intLock ();	/* Perform TAS on local address */	state =  vxTas ((UINT *)adrs);	EIEIO_SYNC;        intUnlock (lockKey);        /* return TAS test result */        return (state);#else	/* The master board can generate a VMEbus RMW */	return (sysVmeRmwTas(adrs));#endif	/* SM_OFF_BOARD */#endif	/* ANY_BRDS_IN_CHASSIS_NOT_RMW */	}    else	/* Slave node */	{	if (pciToVmeDev == UNIVERSE_II)	    {	    /* A slave board with the UNIVERSE_II can generate a VMEbus RMW */	    return (sysVmeRmwTas(adrs));	        }	else	/* UNIVERSE_I */	    {	    /*	     * A slave board with the UNIVERSE_I cannot generate a VMEbus	     * RMW; therefore, it must set VOWN before doing a TAS.	     */	    return (sysVmeVownTas(adrs));	    }        }    }/******************************************************************************** sysBusTasClear - clear a location set by sysBusTas()** This routine clears the specified 32-bit location typically set* by sysBusTas().  The following table defines the method used to* insure an atomic operation.** .CS*		Master		Slave_1		Slave_2** VME Chip	Don't Care	U1		U1*		----------	----		----* Method	VOWN		VOWN		VOWN** VME Chip	Don't Care	U1		U2*		----------	----		----* Method	VOWN		VOWN		RMW** VME Chip	U1 or		U2		U2*		U2+*		----------	----		----* Method	VOWN+++		RMW		RMW** VME Chip	U2++		U2		U2* PCI Bridge	or Raven3*		------------	------------	------------* Method	simple clear	simple clear	simple clear***  +   = Refer to target.txt file for explaination of older boards*	 with Universe II (U2).*  ++  = Refer to target.txt file for explaination of newer boards*	 with Universe II (U2).*  +++ = The master's hardware does not preserve the atomic RMW.* ++++ = If SM_OFF_BOARD == TRUE,  no special/additional processing*	 is required.* .CE** RETURNS: N/A** SEE ALSO: sysBusTas()*/void sysBusTasClear    (    volatile char * adrs	/* Address of semaphore to be cleared */    )    {    BOOL state;    int  lockKey;        /* interrupt lock key */#ifdef	ANY_BRDS_IN_CHASSIS_NOT_RMW    /*     * A slave board in the chassis cannot generate a VMEbus RMW,     * and/or the master board cannot translate an incoming VMEbus     * RMW into an atomic operation; therefore, the master must set     * VOWN before clearing a local TAS location.     */    /* Check for master node or slave node with UNIVERSE_I */    if ((sysProcNumGet() == 0) ||	(pciToVmeDev == UNIVERSE_I))	{        /*         * Compute a 10 microsecond delay count         *         * NotTimeOut(loops) = timeout(usec)/clks/loop/CPU_SPEED(clks/usec)         */        int  NotTimeOut = ((MEMORY_BUS_SPEED/1000000) * UNLOCK_TIMEOUT)			    / CPU_CLOCKS_PER_LOOP;        /* do clearing with no interference */        lockKey = intLock ();        /* request ownership of the VMEbus */        *UNIVERSE_MAST_CTL |= LONGSWAP(MAST_CTL_VOWN);        EIEIO_SYNC;        /* wait for the VME controller to give you the BUS */        while (!VMEBUS_OWNER && NotTimeOut)	    {	    --NotTimeOut;	    }        /* clear the location */        *(UINT *)adrs = 0;        EIEIO_SYNC;        /* release the VME BUS */        *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN);        /* enable normal operation */        intUnlock (lockKey);        }    else	/* Slave node == UNIVERSE_II */	{        /* Lock interrupts so that setting up SCG and issuing RMW are atomic */        lockKey = intLock ();        /* Enable RMW cycle */        sysBusRmwEnable(VME_SCG_COMPARE_MASK,			VME_SCG_COMPARE_TO_CLEAR,			VME_SCG_SWAP_TO_CLEAR,			(char *)adrs);        /* perform RMW to clear TAS location */        state = *((UINT *)adrs);	EIEIO_SYNC;        /* Disable RMW cycle */        sysBusRmwDisable();        /* unlock the interrupt */        intUnlock (lockKey);        }#else#if	(SM_OFF_BOARD == FALSE)    /*     * All slave boards in the chassis can generate a VMEbus RMW, and     * the master board can translate an incoming VMEbus RMW into an     * atomic operation therefore, all boards can do a simple clear.     */    EIEIO_SYNC;		/* SPR 30848, sync before clearing */    *(UINT *)adrs = 0;#else	/* SM_OFF_BOARD == TRUE */    /* Check for master node or slave node with UNIVERSE_I */    if ((sysProcNumGet() == 0) ||	(pciToVmeDev == UNIVERSE_I))	{        /*         * Compute a 10 microsecond delay count         *         * NotTimeOut(loops) = timeout(usec)/clks/loop/CPU_SPEED(clks/usec)         */        int  NotTimeOut = ((MEMORY_BUS_SPEED/1000000) * UNLOCK_TIMEOUT)			    / CPU_CLOCKS_PER_LOOP;        /* do clearing with no interference */        lockKey = intLock ();        /* request ownership of the VMEbus */        *UNIVERSE_MAST_CTL |= LONGSWAP(MAST_CTL_VOWN);        EIEIO_SYNC;        /* wait for the VME controller to give you the BUS */        while (!VMEBUS_OWNER && NotTimeOut)	    {	    --NotTimeOut;	    }        /* clear the location */        *(UINT *)adrs = 0;        EIEIO_SYNC;        /* release the VME BUS */        *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN);        /* enable normal operation */        intUnlock (lockKey);        }    else	/* Slave node == UNIVERSE_II */	{        /* Lock interrupts so that setting up SCG and issuing RMW are atomic */        lockKey = intLock ();        /* Enable RMW cycle */        sysBusRmwEnable(VME_SCG_COMPARE_MASK,			VME_SCG_COMPARE_TO_CLEAR,			VME_SCG_SWAP_TO_CLEAR,			(char *)adrs);        /* perform RMW to clear TAS location */        state = *((UINT *)adrs);	EIEIO_SYNC;        /* Disable RMW cycle */        sysBusRmwDisable();        /* unlock the interrupt */        intUnlock (lockKey);        }#endif	/* SM_OFF_BOARD */#endif	/* ANY_BRDS_IN_CHASSIS_NOT_RMW */    }/********************************************************************************* sysVmeVownTas - test and set a location across the VMEbus** This routine performs a test-and-set (TAS) instruction on the specified* address.  To prevent deadlocks, interrupts are disabled and the VMEbus is* locked during the test-and-set operation.** NOTE: Although the address passed-in to sysBusTas() is defined as* "char *", vxTas() operates on the address as a "void *".* For PowerPC, this implies that the location tested-and-set is* actually a 32-bit entity.* * RETURNS: TRUE if the value had not been set but is now* FALSE if the VMEbus cannot be locked or the value was already set.** SEE ALSO: vxTas(), sysVmeVownTasClear()*/LOCAL BOOL sysVmeVownTas    (    char * adrs          /* address to be tested and set */    )    {    BOOL state = FALSE;  /* semaphore state */    int  lockKey;        /* interrupt lock key */    /*     * Compute a 10 microsecond delay count     *     * NotTimeOut(loops) = timeout(usec)/clks/loop/CPU_SPEED(clks/usec)     */    int  NotTimeOut = ((MEMORY_BUS_SPEED/1000000) * LOCK_TIMEOUT)			/ CPU_CLOCKS_PER_LOOP;    /* lock interrupts so there will be no TAS interference */    lockKey = intLock ();    /* Request ownership of the VMEbus */    *UNIVERSE_MAST_CTL |= LONGSWAP(MAST_CTL_VOWN);    EIEIO_SYNC;    /* Wait for the VME controller to give you the BUS */    while (!VMEBUS_OWNER && NotTimeOut)	{	--NotTimeOut;	}    /* perform the TAS */    if (VMEBUS_OWNER)	{	state =  vxTas ((UINT *)adrs);	EIEIO_SYNC;	}    /* release the VME BUS */        *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN);    /* unlock the interrupt */    intUnlock (lockKey);    /* return TAS test result */

⌨️ 快捷键说明

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