📄 universe_dy4.c
字号:
if (vmeFindLocalAdrs(mask,value,busAdrs,pLocalAdrs)==OK) { return (OK); } mask = (VME_SPE_CTL_SUP); value = (VME_SPE_CTL_SUP); return (vmeFindLocalAdrsSpecial(VME_SPE_A16,mask,value,busAdrs,pLocalAdrs)); break; default: } *pLocalAdrs=(char*)NULL; return (ERROR); }/********************************************************************************* vxNonCacheTas - test and set a location without using PPC lwarx** This routine performs a test-and-set (TAS) instruction on the specified* address.** NOTE: This routine is similar to vxTas().** RETURNS: TRUE if the value is set (and had not been set) * FALSE if the value was set already.** SEE ALSO: vxTas(), sysBusTas, sysBusTasClear()*/BOOL vxNonCacheTas ( char *adrs ) { WRS_ASM("lis 4,0x8000"); WRS_ASM("sync"); WRS_ASM("lwzx 5,0,3"); WRS_ASM("cmpwi 5,0"); WRS_ASM("bne vxNonCacheTasEnd"); WRS_ASM("stwx 4,0,3"); WRS_ASM("sync"); WRS_ASM("li 3,1"); WRS_ASM("blr"); WRS_ASM("vxNonCacheTasEnd:"); WRS_ASM("li 3,0"); WRS_ASM("blr"); return(TRUE); }/********************************************************************************* sysVmeVownTas - 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 sysVmeVownTas ( 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) {/* CR1848: vxTas causes exceptions on un-cached memory */#ifdef BUS_SNOOP_ENABLE state = vxTas (adrs);#else state = vxNonCacheTas (adrs);#endif IO_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 VME bus location** Does a TAS using the RMW generator on the UniverseII.** RETURNS: TRUE if the previous value had been zero, or FALSE if the* value was set already.**/BOOL sysVmeRmwTas ( char *addr /* address to be tested and set */ ) { volatile UINT8 data; int lockKey; volatile UINT32 regData; lockKey = intLock (); /* Set up control registers */ *(UINT32 *)VME_SPECIAL_CYCLE_PCI_ADDR = LONGSWAP((UINT32)addr); *(UINT32 *)VME_SPECIAL_CYCLE_MASK = LONGSWAP(VME_SPEC_CYC_VALUE); *(UINT32 *)VME_SPECIAL_CYCLE_CMP_DATA = 0x0; *(UINT32 *)VME_SPECIAL_CYCLE_SWP_DATA = LONGSWAP(VME_SPEC_CYC_VALUE);IO_SYNC; regData = *(UINT32 *)VME_SPECIAL_CYCLE_CNTL; *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = LONGSWAP(VME_SPEC_CYC_RMW | (vmeData->pciVmeMemSpace ? 0 : 0x04));IO_SYNC; /* Use read access initiate RMW VME Bus cycle */ data = (UINT8) *addr; /* Clear RMW cycle */ *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = LONGSWAP(VME_SPEC_CYC_DISABLE);IO_SYNC; if ((data & 0x80) == 0x0) { intUnlock (lockKey); return (TRUE); } else { intUnlock (lockKey); return (FALSE); } }/******************************************************************************** sysVmeVownTasClear - 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 sysVmeVownTasClear ( 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 */ *adrs = 0; IO_SYNC; /* read back the adrs */ *(volatile char *)adrs; /* release the VME BUS */ *UNIVERSE_MAST_CTL &= LONGSWAP(~MAST_CTL_VOWN); /* enable normal operation */ intUnlock (lockKey); }/******************************************************************************** sysVmeRmwTasClear - 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 execute a Universe RMW with 0 for* data.** To prevent deadlocks, interrupts are disabled and the VMEbus is* locked during the clear operation.** RETURNS: N/A** SEE ALSO: sysBusTas()*/void sysVmeRmwTasClear ( volatile char * addr /* address to be tested-and-cleared */ ) { volatile UINT8 data; int lockKey; volatile UINT32 regData; lockKey = intLock (); /* Set up control registers */ *(UINT32 *)VME_SPECIAL_CYCLE_PCI_ADDR = LONGSWAP((UINT32)addr); *(UINT32 *)VME_SPECIAL_CYCLE_MASK = LONGSWAP(VME_SPEC_CYC_VALUE); *(UINT32 *)VME_SPECIAL_CYCLE_CMP_DATA = LONGSWAP(VME_SPEC_CYC_VALUE); *(UINT32 *)VME_SPECIAL_CYCLE_SWP_DATA = 0x0;IO_SYNC; regData = *(UINT32 *)VME_SPECIAL_CYCLE_CNTL; *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = LONGSWAP(VME_SPEC_CYC_RMW| (vmeData->pciVmeMemSpace ? 0 : 0x04));IO_SYNC; /* Use read access initiate RMW VME Bus cycle */ data = (UINT8) *addr; /* Clear RMW cycle */ *(UINT32 *)VME_SPECIAL_CYCLE_CNTL = LONGSWAP(VME_SPEC_CYC_DISABLE);IO_SYNC; if ((data & 0x80) != 0x80) { logMsg("sysVmeRmwBusTasClear() failed! = 0x%x\n",data,0,0,0,0,0); } 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) {#ifndef CPU0_IMAGE return;#else UINT32 image; UINT32 option; volatile UINT32 dctl = 0x0; UINT32 vmeMstrMemTop[]= { CPU_PCI_MEM_VME_TOP_0, CPU_PCI_MEM_VME_TOP_1, CPU_PCI_MEM_VME_TOP_2 }; /* The following initialization code is required for both warm and cold boots.*/ /* Initialise the VME Universe Interrupt tables */ sysVmeInitIntrTables(); /* set the latency timer to max value */ *UNIVERSE_PCI_MISC0 = LONGSWAP( PCI_MISC0_LATENCY_TIMER ); /* * Read DCTL register */ dctl = LONGSWAP( *UNIVERSE_DCTL ); dctl |=DCTL_LD64EN; /* enable 64-bit PCI bus transaction */ /* * Write the result of above manipluations back DCTL registers. */ *UNIVERSE_DCTL = LONGSWAP( dctl ); dctl = LONGSWAP( *UNIVERSE_DCTL ); /* read back */ /* connect VME to PCI interrupt INTB */ (void)intConnect (INUM_TO_IVEC(INT_SRC_VME), sysUniverseIntr, 0); /* interrupts can only be turned on ultimately by the PIC int ctrlr */ intEnable (INT_SRC_VME);#if defined(INCLUDE_VME_DMA) /* Initialize the DMA machine only if this is included. */ sysVmeDmaInit();#endif /* * Warm boot specific initialization code */ /* if this is a warm boot the signature will still be there and the data valid */ if (vmeData->signature == VME_SHARED_DATA_SIG) { /* VME should already be initialised return immediatly */ return; } /* Get FFW CBM VME PCI mapping option */ option = cssXGetVmeMapOption(); /* Make sure option is within limits */ if (option > VME_MEM_OPTION2) option = VME_MEM_OPTION0; /* set default MASTER window top of PCI space */ vmeData->pciVmeMstrMemTop = vmeMstrMemTop[option]; /* Mem space is used for option 0, IO for option 1 and 2 */ vmeData->pciVmeMemSpace = (option == VME_MEM_OPTION0); /* Initialise the data structure used to manage the VME slave and master images */ for (image=0; image<UNIVERSE_PCI_SLAVE_IMAGES;image++) { switch (image) { case UNIVERSE_LSI0 : vmeData->sysPciSlaveDesc[image].ctl = UNIVERSE_LSI0_CTL; vmeData->sysPciSlaveDesc[image].bs = UNIVERSE_LSI0_BS; vmeData->sysPciSlaveDesc[image].bd = UNIVERSE_LSI0_BD; vmeData->sysPciSlaveDesc[image].to = UNIVERSE_LSI0_TO; break; case UNIVERSE_LSI1 : vmeData->sysPciSlaveDesc[image].ctl = UNIVERSE_LSI1_CTL; vmeData->sysPciSlaveDesc[image].bs = UNIVERSE_LSI1_BS; vmeData->sysPciSlaveDesc[image].bd = UNIVERSE_LSI1_BD; vmeData->sysPciSlaveDesc[image].to = UNIVERSE_LSI1_TO; break; case UNIVERSE_LSI2 : vmeData->sysPciSlaveDesc[image].ctl = UNIVERSE_LSI2_CTL; vmeData->sysPciSlaveDesc[image].bs = UNIVERSE_LSI2_BS; vmeData->sysPciSlaveDesc[image].bd = UNIVERSE_LSI2_BD; vmeData->sysPciSlaveDesc[image].to = UNIVERSE_LSI2_TO; break; case UNIVERSE_LSI3 : vmeData->sysPciSlaveDesc[image].ctl = UNIVERSE_LSI3_CTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -