📄 universe.c
字号:
/* universe.c - Tundra Universe chip VME-to-PCI bridge interface library *//* Copyright 1984-2002 Wind River Systems, Inc. *//* Copyright 1996,1997,1998,1999 Motorola, Inc. All Rights Reserved *//*modification history--------------------01e,16apr02,dat Removing warnings for T2.2 release01d,12may99,rhv Changed to new WRS PCI symbols (PCI2DRAM_BASE_ADRS changed to PCI_SLV_MEM_BUS).01c,24mar99,rhv Removed an un-used variable in sysBusIntGet.01b,02mar99,rhv Added auto-config support for Universe.01a,15dec98,mdp Written (from version 01u of 2304 bsp).*//*DESCRIPTIONThe routines addressed here include:Initialization of Universe chipBus interrupt functions:.IP "-"enable/disable VMEbus interrupt levels.IP "-"enable/disable additional VME interrupts.IP "-"install handlers for the additional VME interrupts.IP "-"generate bus interruptsMailbox/locations monitor functions:.IP "-"- enable mailbox/location monitor interruptsAll byte I/O is done via the macros UNIV_IN_BYTE and UNIV_OUT_BYTE which may beredefined by the BSP. By default, sysInByte() and sysOutByte() are used. Allother I/O (32-bit) is handled by the macros UNIV_IN_LONG and UNIV_OUT_LONGwhich may be redefined by the BSP. By default, sysPciRead32() andsysPciWrite32() are used.*//* includes */#include "vxWorks.h"#include "config.h"#include "vxLib.h"#ifdef INCLUDE_MPIC# include "hawkMpic.h"#else# include "sl82565IntrCtl.h"#endif /* INCLUDE_MPIC */#include "universe.h"/* defines */#ifndef UNIV_IN_BYTE# define UNIV_IN_BYTE(adr,pVal) \ *(volatile UCHAR *)(pVal)=sysInByte((volatile ULONG)(adr))#endif#ifndef UNIV_OUT_BYTE# define UNIV_OUT_BYTE(adr,val) \ sysOutByte((volatile ULONG)(adr),(volatile UCHAR)(val))#endif#ifndef UNIV_IN_LONG# define UNIV_IN_LONG(adr,pVal) \ sysPciRead32((UINT32)(adr),(UINT32 *)(pVal));#endif#ifndef UNIV_OUT_LONG# define UNIV_OUT_LONG(adr,val) \ sysPciWrite32((UINT32)(adr),(UINT32)(val));#endif# ifndef CPU_INT_LOCK# define CPU_INT_LOCK(pData) (*pData = intLock ())# endif# ifndef CPU_INT_UNLOCK# define CPU_INT_UNLOCK(data) (intUnlock (data))# endif/* forward declarations */LOCAL FUNCPTR sysMailboxRoutine = NULL;LOCAL int sysMailboxArg = 0;#ifdef INCLUDE_VME_DMALOCAL STATUS sysVmeDmaCopy(UCHAR *, UCHAR *, UINT32, UINT32);#endif /* INCLUDE_VME_DMA *//* extern declarations */IMPORT int intEnable (int);IMPORT int intDisable (int);IMPORT void sysOutByte (ULONG, UCHAR);IMPORT UCHAR sysInByte (ULONG);IMPORT void sysPciRead32 (UINT32, UINT32 *);IMPORT void sysPciWrite32 (UINT32, UINT32);IMPORT void sysUsDelay (UINT32);IMPORT INT_HANDLER_DESC * sysIntTbl [256];/* globals */int sysUnivIntsEnabled = 0; /* currently enabled Universe interrupts */int sysUnivIntLevel = 0; /* current level at which ints are disabled */UINT32 sysUnivVERRCnt = 0; /* #VME errors since power on */UINT32 univBaseAdrs;/* * Universe interrupt priority mapping table * * Interrupt priority level is equal to the index into the following array * where 0 is the lowest priority. The prioritization scheme used here * is arbitrary. If the scheme is changed, the interrupt masks (last column) * must be redefined accordingly. See universe.h and the Universe Manual for * bit assignments and further information. */static INT_LEVEL_MAP univIntTable[UNIV_NUM_INT + 1] = { /* Int Bit Mask Int Vector Int Level Mask */ /* ------------------------ ------------------------ -------------- */ {0, 0, 0x0000F7FF}, {UNIVERSE_VOWN_INT, UNIV_VOWN_INT_VEC, 0x0000F7FE}, {LVL1, -1, 0x0000F7FC}, {LVL2, -1, 0x0000F7F8}, {LVL3, -1, 0x0000F7F0}, {LVL4, -1, 0x0000F7E0}, {LVL5, -1, 0x0000F7C0}, {LVL6, -1, 0x0000F780}, {LVL7, -1, 0x0000F700}, {UNIVERSE_DMA_INT, UNIV_DMA_INT_VEC, 0x0000F600}, {UNIVERSE_VME_SW_IACK_INT, UNIV_VME_SW_IACK_INT_VEC, 0x0000E600}, {UNIVERSE_PCI_SW_INT, UNIV_PCI_SW_INT_VEC, 0x0000C600}, {UNIVERSE_LERR_INT, UNIV_LERR_INT_VEC, 0x0000C400}, {UNIVERSE_VERR_INT, UNIV_VERR_INT_VEC, 0x0000C000}, {UNIVERSE_SYSFAIL_INT, UNIV_SYSFAIL_INT_VEC, 0x00008000}, {UNIVERSE_ACFAIL_INT, UNIV_ACFAIL_INT_VEC, 0x00000000} };/* locals */#ifdef INCLUDE_VME_DMALOCAL BOOL sysVmeDmaReady = FALSE;#endif /* INCLUDE_VME_DMA *//********************************************************************************* sysUniverseReset - reset the Universe VME chip** This routine performs the reseting of the Universe chip. All functions* and VME mapping are disabled.** RETURNS: N/A*/void sysUniverseReset (void) { UINT32 reg; /* initialize registers with defaults and disable mapping */ UNIV_OUT_LONG(UNIVERSE_SCYC_CTL, 0); UNIV_OUT_LONG(UNIVERSE_SCYC_ADDR, 0); UNIV_OUT_LONG(UNIVERSE_SCYC_EN, 0); UNIV_OUT_LONG(UNIVERSE_LMISC, LMISC_CRT_128_USEC); UNIV_OUT_LONG(UNIVERSE_DCTL, 0); UNIV_OUT_LONG(UNIVERSE_DTBC, 0); UNIV_OUT_LONG(UNIVERSE_DLA, 0); UNIV_OUT_LONG(UNIVERSE_DVA, 0); UNIV_OUT_LONG(UNIVERSE_DCPP, 0); UNIV_OUT_LONG(UNIVERSE_LINT_EN, 0); UNIV_OUT_LONG(UNIVERSE_LINT_MAP0, 0); UNIV_OUT_LONG(UNIVERSE_LINT_MAP1, 0); UNIV_OUT_LONG(UNIVERSE_VINT_EN, 0); UNIV_OUT_LONG(UNIVERSE_VINT_MAP0, 0); UNIV_OUT_LONG(UNIVERSE_VINT_MAP1, 0); UNIV_OUT_LONG(UNIVERSE_VSI0_CTL, 0); UNIV_OUT_LONG(UNIVERSE_VSI1_CTL, 0); UNIV_OUT_LONG(UNIVERSE_VSI2_CTL, 0); UNIV_OUT_LONG(UNIVERSE_VSI3_CTL, 0); UNIV_OUT_LONG(UNIVERSE_LSI0_CTL, 0); UNIV_OUT_LONG(UNIVERSE_LSI1_CTL, 0); UNIV_OUT_LONG(UNIVERSE_LSI2_CTL, 0); UNIV_OUT_LONG(UNIVERSE_LSI3_CTL, 0); /* clear the SYSFAIL signal */ UNIV_OUT_LONG(UNIVERSE_VCSR_CLR, VCSR_CLR_SYSFAIL); /* clear any outstanding interrupts/error conditions */ UNIV_OUT_LONG(UNIVERSE_LINT_STAT, LINT_STAT_CLEAR); UNIV_OUT_LONG(UNIVERSE_VINT_STAT, VINT_STAT_CLEAR); UNIV_OUT_LONG(UNIVERSE_V_AMERR, V_AMERR_V_STAT); UNIV_IN_LONG(UNIVERSE_PCI_CSR, ®); reg |= PCI_CSR_D_PE | PCI_CSR_S_SERR | PCI_CSR_R_MA | PCI_CSR_R_TA | PCI_CSR_S_TA; UNIV_OUT_LONG(UNIVERSE_PCI_CSR, reg); UNIV_OUT_LONG(UNIVERSE_L_CMDERR, L_CMDERR_L_ENABLE); UNIV_OUT_LONG(UNIVERSE_DGCS, DGCS_STOP | DGCS_HALT | DGCS_DONE | DGCS_LERR | DGCS_VERR | DGCS_P_ERR); /* clear and disable the mailbox interrupts */ UNIV_OUT_BYTE(CPU_SIG_LM_CONTROL_REG, (SIG1_INTR_CLEAR | SIG0_INTR_CLEAR | LM1_INTR_CLEAR | LM0_INTR_CLEAR )); UNIV_OUT_BYTE(CPU_SIG_LM_STATUS_REG, ~(SIG1_INTR_ENABL | SIG0_INTR_ENABL | LM1_INTR_ENABL | LM0_INTR_ENABL )); sysUnivIntsEnabled = 0; sysUnivIntLevel = 0; }/********************************************************************************* sysUniverseInit - initialize registers of the Universe chip** This routine initializes registers of the Universe VME-to-PCI bridge and maps* access to the VMEbus memory space.** NOTE: The sysProcNumSet() routine maps the master node's local memory on the* VMEbus.** RETURNS: OK, always.*/STATUS sysUniverseInit (void) { UINT32 temp_data; /* Put vme chip into a power-up/reset state */ sysUniverseReset (); UNIV_OUT_LONG(UNIVERSE_MAST_CTL, (MAST_CTL_RTRY_FOREVER | MAST_CTL_PWON_4096 | MAST_CTL_VRL3 | MAST_CTL_VRM_FAIR | MAST_CTL_VREL_ROR | MAST_CTL_PABS_128 )); UNIV_IN_LONG(UNIVERSE_MISC_CTL, &temp_data); /* maintain power-up option bits */ temp_data &= ( MISC_CTL_SYSCON | MISC_CTL_V64AUTO ); temp_data |= ( MISC_CTL_VBTO_256USEC | MISC_CTL_VARB_RROBIN | MISC_CTL_VARBTO_256USEC | MISC_CTL_RESCIND ); UNIV_OUT_LONG(UNIVERSE_MISC_CTL, temp_data); UNIV_OUT_LONG(UNIVERSE_USER_AM, 0); UNIV_OUT_LONG(UNIVERSE_VRAI_CTL, 0); UNIV_OUT_LONG(UNIVERSE_VCSR_CTL, 0); /* clear the SYSFAIL signal */ UNIV_OUT_LONG(UNIVERSE_VCSR_CLR, VCSR_CLR_SYSFAIL); /* set the latency timer to max value */ UNIV_OUT_LONG(UNIVERSE_PCI_MISC0, PCI_MISC0_LATENCY_TIMER); /* Map to get to VMEbus using A32 */ UNIV_OUT_LONG(UNIVERSE_LSI1_BS, VAL_LSI1_BS); UNIV_OUT_LONG(UNIVERSE_LSI1_BD, VAL_LSI1_BD); UNIV_OUT_LONG(UNIVERSE_LSI1_TO, VAL_LSI1_TO); UNIV_OUT_LONG(UNIVERSE_LSI1_CTL, VAL_LSI1_CTL); /* Map to get to VMEbus using A24 */ UNIV_OUT_LONG(UNIVERSE_LSI2_BS, VAL_LSI2_BS); UNIV_OUT_LONG(UNIVERSE_LSI2_BD, VAL_LSI2_BD); UNIV_OUT_LONG(UNIVERSE_LSI2_TO, VAL_LSI2_TO); UNIV_OUT_LONG(UNIVERSE_LSI2_CTL, VAL_LSI2_CTL); /* Map to get to VMEbus using A16 */ UNIV_OUT_LONG(UNIVERSE_LSI3_BS, VAL_LSI3_BS); UNIV_OUT_LONG(UNIVERSE_LSI3_BD, VAL_LSI3_BD); UNIV_OUT_LONG(UNIVERSE_LSI3_TO, VAL_LSI3_TO); UNIV_OUT_LONG(UNIVERSE_LSI3_CTL, VAL_LSI3_CTL); /* Map to get to VMEbus LM/SIG Registers using A32 */ UNIV_OUT_LONG(UNIVERSE_LSI0_BS, VAL_LSI0_BS); UNIV_OUT_LONG(UNIVERSE_LSI0_BD, VAL_LSI0_BD); UNIV_OUT_LONG(UNIVERSE_LSI0_TO, VAL_LSI0_TO); UNIV_OUT_LONG(UNIVERSE_LSI0_CTL, VAL_LSI0_CTL); return (OK); }/********************************************************************************* sysUniverseInit2 - enable local memory accesses from the VMEbus** This routine enables local resources to be accessed from the VMEbus.* All target boards have an A32 window opened to access the VMEbus LM/SIG* registers. However, only the master node has an A32 and an A24* window open to its local memory space.** RETURNS: N/A** NOMANUAL*/void sysUniverseInit2 ( int procNum /* processor number */ ) {#ifndef DOC /* setup the VME LM/SIG/SEM registers address range */ UNIV_OUT_LONG(UNIVERSE_VSI0_BS, VAL_VSI0_BS); UNIV_OUT_LONG(UNIVERSE_VSI0_BD, VAL_VSI0_BD); UNIV_OUT_LONG(UNIVERSE_VSI0_TO, VAL_VSI0_TO); UNIV_OUT_LONG(UNIVERSE_VSI0_CTL, VAL_VSI0_CTL | VSI_CTL_PWEN); if (procNum == 0) { /* setup the A32 window */ UNIV_OUT_LONG(UNIVERSE_VSI1_BS, VAL_VSI1_BS); UNIV_OUT_LONG(UNIVERSE_VSI1_BD, VAL_VSI1_BD); UNIV_OUT_LONG(UNIVERSE_VSI1_TO, VAL_VSI1_TO); UNIV_OUT_LONG(UNIVERSE_VSI1_CTL, VAL_VSI1_CTL | VSI_CTL_PWEN);#if (SM_OFF_BOARD == FALSE)#ifndef ANY_BRDS_IN_CHASSIS_NOT_RMW /* * All slave boards in the chassis generate a VMEbus RMW, and * the master is capable of translating an incoming RMW into * an atomic operation. */ /* * The A32 access range is now divided into 3 separate windows. * The first window will allow normal access to the start of local * memory up to the Shared Memory Region. It is defined above * thru the use of a conditional #define VAL_VSI1_BD in mv2400.h. * The second window will allow Read-Modify-Write (RMW) access to * the Standard VxWorks and VxMP's Shared Memory Region. The * third window will allow normal access to the local memory * starting after the Shared Memory Region up to the end of * physical memory. */ /* setup the second A32 window */ UNIV_OUT_LONG(UNIVERSE_VSI4_BS, VAL_VSI4_BS); UNIV_OUT_LONG(UNIVERSE_VSI4_BD, VAL_VSI4_BD); UNIV_OUT_LONG(UNIVERSE_VSI4_TO, VAL_VSI4_TO); UNIV_OUT_LONG(UNIVERSE_VSI4_CTL, VAL_VSI4_CTL); /* setup the third A32 window */ UNIV_OUT_LONG(UNIVERSE_VSI5_BS, VAL_VSI5_BS); UNIV_OUT_LONG(UNIVERSE_VSI5_BD, VAL_VSI5_BD); UNIV_OUT_LONG(UNIVERSE_VSI5_TO, VAL_VSI5_TO); UNIV_OUT_LONG(UNIVERSE_VSI5_CTL, VAL_VSI5_CTL);#endif /* ANY_BRDS_IN_CHASSIS_NOT_RMW */#endif /* SM_OFF_BAORD */ }#endif }/********************************************************************************* sysIntDisable - disable a bus interrupt level** This routine disables reception of a specified VMEbus interrupt level.** NOTE: revision 1.0 Universe chips can fail and lockup if two or more interrupt* levels are enabled. For more details see Tundra Universe Errata sheet.** 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) */ ) { int mask; if (intLevel < 1 || intLevel > 7) return (ERROR); /* clear any pending intr. for this level */ mask = 1 << intLevel; UNIV_OUT_LONG(UNIVERSE_LINT_STAT, mask); /* disable the interrupt */ sysUnivIntsEnabled &= ~mask; UNIV_OUT_LONG(UNIVERSE_LINT_EN, sysUnivIntsEnabled); return (OK); }/********************************************************************************* sysIntEnable - enable a bus interrupt level** This routine enables reception of a specified VMEbus interrupt level.** NOTE: revision 1.0 Universe chips can fail and lockup if two or more interrupt* levels are enabled. For more details see Tundra Universe Errata sheet.** RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.** SEE ALSO: sysIntDisable()*/STATUS sysIntEnable ( int intLevel /* interrupt level to enable (1-7) */ ) { int mask; if (intLevel < 1 || intLevel > 7) return (ERROR); /* clear any pending intr. for this level */ mask = 1 << intLevel; UNIV_OUT_LONG(UNIVERSE_LINT_STAT, mask); /* enable the interrupt */ sysUnivIntsEnabled |= mask; UNIV_OUT_LONG(UNIVERSE_LINT_EN, sysUnivIntsEnabled); /* map the interrupt. Currently all VME ints are mapped to LINT#0 */ UNIV_OUT_LONG(UNIVERSE_LINT_MAP0, 0); return (OK); }/********************************************************************************* sysBusIntAck - acknowledge a bus interrupt** This routine acknowledges a specified VMEbus interrupt level.** NOTE: This routine is included for BSP compliance only. Since VMEbus* interrupts are re-enabled in the interrupt handler, and acknowledged* automatically by hardware, this routine is a no-op.** RETURNS: NULL.** SEE ALSO: sysBusIntGen()*/int sysBusIntAck ( int intLevel /* interrupt level to acknowledge */ ) { return (0); }/********************************************************************************* sysBusIntGen - generate a bus interrupt** This routine generates a VMEbus interrupt for a specified level with a* specified vector. Only one VME interrupt can be generated at a time and* none can be generated if a previously generated VME interrupt has not been* acknowledged, i.e., if no VME bus IACK cycle has completed.** RETURNS: OK, or ERROR if <level> or <vector> are out of range or if an* interrupt is already in progress.** SEE ALSO: sysBusIntAck()*/STATUS sysBusIntGen ( int level, /* interrupt level to generate */ int vector /* interrupt vector for interrupt */ ) { volatile ULONG enReg; volatile ULONG intReg; volatile ULONG statidReg; int lockKey; /* Validate interrupt level */ if (level < 1 || level > 7 || vector > 255 || vector < 2) return (ERROR); /* lock interrupts so there will be no interference */ CPU_INT_LOCK(&lockKey); /* Ensure bus interrupt is not already asserted */ UNIV_IN_LONG(UNIVERSE_VINT_STAT, &intReg); if (intReg & ((1 << level) << 24)) { CPU_INT_UNLOCK(lockKey); return (ERROR); } /* * Clear Software Interrupt bit before setting it * It needs a 0 to 1 transition to generate an interrupt */ UNIV_IN_LONG(UNIVERSE_VINT_EN, &enReg); enReg &= ~((1 << level) << 24); UNIV_OUT_LONG(UNIVERSE_VINT_EN, enReg); /* * store vector number, wiping out LSB of vector number * This implies that only even number vectors should be used * (Universe FEATURE ?) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -