📄 syslib.c
字号:
* 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 */ ) {#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. */ BOOL state; int lockKey; /* interrupt lock key */ /* 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); SYNC; /* wait for the VME controller to give you the BUS */ while (!VMEBUS_OWNER && NotTimeOut) { --NotTimeOut; } /* clear the location */ *(UINT *)adrs = 0; 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); 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; SYNC;#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); SYNC; /* wait for the VME controller to give you the BUS */ while (!VMEBUS_OWNER && NotTimeOut) { --NotTimeOut; } /* clear the location */ *(UINT *)adrs = 0; 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); 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); 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); SYNC; } /* release the VME BUS */ *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN); /* unlock the interrupt */ intUnlock (lockKey); /* return TAS test result */ return (state); }/********************************************************************************* 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); SYNC; /* Disable RMW cycle */ sysBusRmwDisable(); /* unlock the interrupt */ intUnlock (lockKey); /* return TAS test result */ if (state) { return (FALSE); } else { return (TRUE); } }/******************************************************************************** sysLanIntEnable - enable the LAN interrupt** This routine enables interrupts at a specified level for the on-board LAN* chip. The LANCE chip on this board is on the Peripheral Component* Interconnect (PCI) bus. The LANCE chip asserts PCI IRQ0 which is routed* to the EPIC Serial Interrupt #1.** RETURNS: OK, or ERROR if network support not included.** SEE ALSO: sysLanIntDisable()*/STATUS sysLanIntEnable ( int intLevel /* interrupt level to enable */ ) {#ifdef INCLUDE_NETWORK intEnable (intLevel); return (OK);#else return (ERROR);#endif /* INCLUDE_NETWORK */ }/******************************************************************************** sysLanIntDisable - disable the LAN interrupt** This routine disables interrupts for the on-board LAN chip. ** RETURNS: OK, or ERROR if network support not included.** SEE ALSO: sysLanIntEnable()*/STATUS sysLanIntDisable ( int intLevel /* interrupt level to enable */ ) {#ifdef INCLUDE_NETWORK /* * disable the Serial interrupt #1 for the MV2100 */ intDisable (intLevel); return (OK);#else return (ERROR);#endif /* INCLUDE_NETWORK */ }/******************************************************************************** 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 */ ) { return (sysInByte (NVRAM_BASE + offset)); }/******************************************************************************** sysNvWrite - write one byte to NVRAM** This routine writes a single byte to a specified offset in NVRAM.** RETURNS: N/A*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -