📄 syslib_5100.c
字号:
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 /* ANY_BRDS_IN_CHASSIS_NOT_RMW */# 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 /* SM_OFF_BOARD */ /* 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 */ { /* A board with the UNIVERSE_II can generate a VMEbus RMW */ return (sysVmeRmwTas(adrs)); } }/******************************************************************************** sysBusTasClear - clear a location set by sysBusTas()** This routine clears the specified 32-bit location typically set* by sysBusTas(). ** RETURNS: N/A** SEE ALSO: sysBusTas()*/void sysBusTasClear ( volatile char * adrs /* Address of semaphore to be cleared */ ) { UINT32 ticksToWait; /* number of time base ticks to wait */ UINT32 startTick; /* starting timebase low tick value */ 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) { /* * convert LOCK_TIMEOUT to timebase ticks as follows: * * ticks/Usec = (bus frequency / decrementer pre-scaler) / 1000000 * * ticks to wait = LOCK_TIMEOUT (in Usecs) * ticks/USec. */ ticksToWait = LOCK_TIMEOUT * ((DEC_CLOCK_FREQ/DECREMENTER_PRESCALE)/USECS_PER_SECOND); /* do clearing with no interference */ lockKey = intLock (); /* request ownership of the VMEbus */ *UNIVERSE_MAST_CTL |= LONGSWAP(MAST_CTL_VOWN); EIEIO_SYNC; /* snapshot starting time base low value */ startTick = sysTimeBaseLGet (); /* Wait for the VME controller to give you the BUS or timeout */ while (!VMEBUS_OWNER && (sysTimeBaseLGet () - startTick) < ticksToWait); /* 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. */ *(UINT *)adrs = 0; EIEIO_SYNC;# else /* SM_OFF_BOARD == TRUE */ /* Check for master node or slave node with UNIVERSE_I */ if (sysProcNumGet() == 0) { /* * convert LOCK_TIMEOUT to timebase ticks as follows: * * ticks/Usec = (bus frequency / decrementer pre-scaler) / 1000000 * * ticks to wait = LOCK_TIMEOUT (in Usecs) * ticks/USec. */ ticksToWait = LOCK_TIMEOUT * ((DEC_CLOCK_FREQ/DECREMENTER_PRESCALE)/USECS_PER_SECOND); /* do clearing with no interference */ lockKey = intLock (); /* request ownership of the VMEbus */ *UNIVERSE_MAST_CTL |= LONGSWAP(MAST_CTL_VOWN); EIEIO_SYNC; /* snapshot starting time base low value */ startTick = sysTimeBaseLGet (); /* Wait for the VME controller to give you the BUS or timeout */ while (!VMEBUS_OWNER && (sysTimeBaseLGet () - startTick) < ticksToWait); /* 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 */ }#ifdef 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 */ UINT32 ticksToWait; /* number of time base ticks to wait */ UINT32 startTick; /* starting timebase low tick value */ /* * convert LOCK_TIMEOUT to timebase ticks as follows: * * ticks/Usec = (bus frequency / decrementer pre-scaler) / 1000000 * * ticks to wait = requested delay (in Usecs) * ticks/USec. */ ticksToWait = LOCK_TIMEOUT * ((DEC_CLOCK_FREQ/DECREMENTER_PRESCALE)/USECS_PER_SECOND); /* 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; /* snapshot starting time base low value */ startTick = sysTimeBaseLGet (); /* Wait for the VME controller to give you the BUS or timeout */ while (!VMEBUS_OWNER && (sysTimeBaseLGet () - startTick) < ticksToWait); /* 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 */ return (state); }#endif /* ANY_BRDS_IN_CHASSIS_NOT_RMW *//********************************************************************************* sysVmeRmwTas - test and set a location across the VMEbus utilizing RMW** 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()*/LOCAL BOOL sysVmeRmwTas ( char * adrs /* address to be tested and set */ ) { BOOL state = FALSE; /* semaphore state */ int lockKey; /* interrupt lock key */ /* A board with the UNIVERSE_II can generate a VMEbus RMW */ /* * 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_SET, VME_SCG_SWAP_TO_SET, (char *)adrs); /* perform RMW to try and set TAS location */ state = *((UINT *)adrs); EIEIO_SYNC; /* Disable RMW cycle */ sysBusRmwDisable(); /* unlock the interrupt */ intUnlock (lockKey); /* return TAS test result */ return (state ? FALSE : TRUE); }/******************************************************************************** sysSpuriousIntHandler - spurious interrupt handler** This is the entry point for spurious interrupts.** NOTE: This routine has no effect.** This routine catches all spurious interrupts. It does nothing at all.** RETURNS: N/A.** RETURNS: N/A** NOMANUAL*/void sysSpuriousIntHandler (void) { }/******************************************************************************** sysNvRead - read one byte from NVRAM** This routine reads a single byte from a specified offset in NVRAM.** RETURNS: The byte from the specified NVRAM offset.*/UCHAR sysNvRead ( ULONG offset /* NVRAM offset to read the byte from */ ) { sysOutByte (NV_RAM_LSB_REG, LSB(offset)); sysOutByte (NV_RAM_MSB_REG, MSB(offset));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -