📄 universe_dy4.c
字号:
int adrsSpace, /* bus address space where busAdrs resides */ char * busAdrs, /* bus address to convert */ char ** pLocalAdrs /* where to return local address */ ){ int image, vmeTop,regOffset; switch (adrsSpace) { /* No distinction on SUP/USR and PGM/DATA AM codes */ case VME_AM_EXT_SUP_PGM: case VME_AM_EXT_USR_PGM: case VME_AM_EXT_SUP_DATA: case VME_AM_EXT_USR_DATA: /* Check if the passed busAdrs exsists in the Reg Access Window*/ if (((UINT32)busAdrs >= DEFAULT_VRAI_BS) && ((UINT32)busAdrs<(DEFAULT_VRAI_BS + 0x1000))) { /*This busAdrs is a valid A32 VME Reg access address and the local address is the Universe IO base address */ regOffset = (UINT32)busAdrs - DEFAULT_VRAI_BS; *pLocalAdrs = (char*) (sysGetUniverseIoBaseAdrs() + regOffset); return OK; } /* search in all enabled images */ for (image=0; image<UNIVERSE_SLAVE_IMAGES; image++) { if (sysPciSlaveDesc[image].enabled) { vmeTop = (UINT32)sysPciSlaveDesc[image].vmeBase + sysPciSlaveDesc[image].size; if (((UINT32)busAdrs>= (UINT32)sysPciSlaveDesc[image].vmeBase) && ((UINT32)busAdrs<= vmeTop)) { if (((UINT32)busAdrs>= vmeA32Base)&& ((UINT32)busAdrs<(vmeA32Base+vmeA32Size))) { /*This A32 VME address is local to the current card*/ *pLocalAdrs = (char*)((UINT32)VME_A32_SLV_LOCAL + (UINT32)busAdrs - vmeA32Base); return OK; } else { /* found window for given bus address */ *pLocalAdrs = (char*) ((UINT32)VME_A32_SLV_LOCAL + (UINT32)sysPciSlaveDesc[image].localAdrs + (UINT32)busAdrs - ((UINT32)sysPciSlaveDesc[image].vmeBase)); return OK; } } } } return ERROR; break; /* No distinction on SUP/USR and PGM/DATA AM codes */ case VME_AM_STD_SUP_PGM: case VME_AM_STD_USR_PGM: case VME_AM_STD_SUP_DATA: case VME_AM_STD_USR_DATA: /* Upper 64K is used for A16 in Special PCI slave image */ if ((UINT32)busAdrs > 0x00ff0000) return ERROR; if (((UINT32)busAdrs >= vmeA24Base) && ((UINT32)busAdrs < (vmeA24Size + vmeA24Base))) { /*This A24 VME address is local to the current card*/ *pLocalAdrs = (UINT32)VME_A24_SLV_LOCAL + (char *) busAdrs - vmeA24Base; return OK; } else { /* Use image 0 of Special Slave image */ *pLocalAdrs = (UINT32)VME_A24_SLV_LOCAL + (char *) busAdrs + VME_A24_MSTR_LOCAL; return OK; } /* No distinction on SUP/USR AM codes */ case VME_AM_SUP_SHORT_IO: case VME_AM_USR_SHORT_IO: if (busAdrs > (char *)0x0000ffff) return (ERROR); *pLocalAdrs = (char *) ((UINT32)busAdrs + VME_A16_MSTR_LOCAL); return (OK); default: return (ERROR); }}#ifndef INCLUDE_UNIVERSE_HW_BUSTAS /* Use UNIVERSE I software test-and-set *//********************************************************************************* sysBusTas - test and set a location across the bus** 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: This routine is dependent upon, not equivalent to, vxTas().** RETURNS: TRUE if the value had not been set but is now, or FALSE if the* VMEbus cannot be locked or the value was set already.** SEE ALSO: vxTas(), sysBusTasClear()*/BOOL sysBusTas ( char * adrs /* address to be tested and set */ ){ BOOL state = FALSE; /* semaphore state */ int lockKey; /* interrupt lock key */ /* 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); IO_SYNC; /* Wait for the VME controller to give you the BUS */ while (!VMEBUS_OWNER && NotTimeOut) { --NotTimeOut; } /* perform the TAS */ if (VMEBUS_OWNER) { state = vxTas (adrs); IO_SYNC; } /* release the VME BUS */ *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN); /* unlock the interrupt */ intUnlock (lockKey); /* return TAS test result */ return (state);}#else /* Use UNIVERSE II hardware test-and-set *//************************************************************************** sysBusTas - test and set a VME bus location*** RETURNS: TRUE if the previous value had been zero, or FALSE if the* value was set already.**/BOOL sysBusTas ( INT8 *addr /* address to be tested and set */ ){ UINT8 data; int lockKey; lockKey = intLock (); /* Set up control registers */ *(UINT32 *)VME_SPECIAL_CYCLE_PCI_ADDR = (UINT32)addr; *(UINT32 *)VME_SPECIAL_CYCLE_MASK = VME_SPEC_CYC_VALUE; *(UINT32 *)VME_SPECIAL_CYCLE_CMP_DATA = 0x0; *(UINT32 *)VME_SPECIAL_CYCLE_SWP_DATA = VME_SPEC_CYC_VALUE; *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = VME_SPEC_CYC_RMW; IO_SYNC; /* Use read access initiate RMW VME Bus cycle */ data = (UINT8) *addr; /* Clear RMW cycle */ *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = VME_SPEC_CYC_DISABLE; IO_SYNC; if ((data & 0x80) == 0x0) { intUnlock (lockKey); return (TRUE); } else { intUnlock (lockKey); return (FALSE); }}#endif/******************************************************************************** sysBusTasClear - clear a location set by sysBusTas()** This routine clears the specified location if it has been set by a* call to sysBusTas(). It attempts to own the VMEbus and waits to do so* up to 10 milliseconds. If the bus can be owned, the location is cleared.* If, after 10 milliseconds, the bus is not owned, the location is cleared* anyway.** To prevent deadlocks, interrupts are disabled and the VMEbus is* locked during the clear operation.** RETURNS: N/A** SEE ALSO: sysBusTas()*/void sysBusTasClear ( volatile char * adrs /* address to be tested-and-cleared */ ){ int lockKey; /* interrupt lock key */ /* 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); IO_SYNC; /* wait for the VME controller to give you the BUS */ while (!VMEBUS_OWNER && NotTimeOut) { --NotTimeOut; } /* clear the location */ if (VMEBUS_OWNER) { *adrs = 0; IO_SYNC; } /* release the VME BUS */ *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN); /* enable normal operation */ intUnlock (lockKey);}/********************************************************************************* sysUniverseHwInit2 - enable local memory accesses from the VMEbus** This routine enables local resources to be accessed from the VMEbus.* The VME A24/A32 slave windows are also enabled.** RETURNS: N/A** NOMANUAL*/void sysUniverseHwInit2 (void){ UINT8 intEnReg; char * local; /* Setting VMEbus Register Access Image */ *UNIVERSE_VRAI_CTL = LONGSWAP(VRAI_CTL_EN | VRAI_CTL_AM_DATA | VRAI_CTL_AM_PGM | VRAI_CTL_AM_SUPER | VRAI_CTL_AM_USER | VRAI_CTL_VAS_A32); *UNIVERSE_VRAI_BS = LONGSWAP(DEFAULT_VRAI_BS); /* Setting up VME A24/A32 slave windows. No A16 access */ sysUniverseSlaveImageSet(UNIVERSE_VSI0, VAL_VSI0_CTL, VAL_VSI0_BS, VAL_VSI0_BD, VAL_VSI0_TO); sysUniverseSlaveImageSet(UNIVERSE_VSI1, VAL_VSI1_CTL, VAL_VSI1_BS, VAL_VSI1_BD, VAL_VSI1_TO); sysUniverseSlaveImageSet(UNIVERSE_VSI2, VAL_VSI2_CTL, VAL_VSI2_BS, VAL_VSI2_BD, VAL_VSI2_TO); /* Setting up Special PCI Slave image for A16/A24 VME access */ *UNIVERSE_SLSI = LONGSWAP( DEFAULT_SLSI_EN | DEFAULT_SLSI_WP | DEFAULT_SLSI_VDW | DEFAULT_SLSI_PGM | DEFAULT_SLSI_SUPER | DEFAULT_SLSI_BS | DEFAULT_SLSI_LAS); /* install interrupt handlers for mailboxes */ intConnect (INUM_TO_IVEC (SYS_MAILBOX_INT_VEC), sysMailboxInt, SYS_MAILBOX0); intConnect (INUM_TO_IVEC (UNIV_MBOX1_INT_VEC), sysMailboxInt, SYS_MAILBOX1); intConnect (INUM_TO_IVEC (UNIV_MBOX2_INT_VEC), sysMailboxInt, SYS_MAILBOX2); intConnect (INUM_TO_IVEC (UNIV_MBOX3_INT_VEC), sysMailboxInt, SYS_MAILBOX3); /* Enable Location Monitor Image */ /* We will not enable location monitor as this is not supported in the * BSP. Use Mailbox instead! * *UNIVERSE_LM_CTL = LONGSWAP(LM_CTL_EN | LM_CTL_PGM | LM_CTL_DATA | LM_CTL_USR | LM_CTL_SUP | LM_CTL_VAS_A32); *UNIVERSE_LM_BS = LONGSWAP(VME_A32_SLV_BUS - LM_IMAGE_SIZE); * */#if defined(INCLUDE_VME_DMA) /* Initialize the DMA machine only if this is included. */ sysVmeDmaInit();#endif /* connect Vme to PCI interrupt INTB */ (void)intConnect (INUM_TO_IVEC(INT_VEC_VME), sysUniverseIntr, 0); /* interrupts can only be turned on ultimately by the PIC int ctrlr */ intEnable (INT_SRC_VME); intEnReg = sysInByte ((UINT32) FPGA_VME_INTEN); sysOutByte ((UINT32) FPGA_VME_INTEN, intEnReg | FPGA_VME_INTEN_CA0);/* intEnReg = sysInByte ((UINT32) FPGA_SD_INTEN); */ sysGt64260MuxedIntEnable(GPP_INT_TYPE, 23); /* pin 23 */ sysVmeA32MstrSet(UNIVERSE_LSI0,(char*)VME_A32_MSTR_BUS, VME_A32_MSTR_SIZE, VME_A32_MSTR_CTL, (char**)&local);}/********************************************************************************* sysIntDisable - disable a bus interrupt level** This routine disables a specified VMEbus interrupt level.** RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.** SEE ALSO: sysIntEnable()*/STATUS sysIntDisable ( int intLevel /* interrupt level to disable (1-7) */ ){ if (intLevel < 1 || intLevel > 7) return (ERROR); /* clear any pending intr. for this level */ *UNIVERSE_LINT_STAT = LONGSWAP( (1 << intLevel ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -