⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 universe.c

📁 VxWorks下 MV2400的BSP源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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);    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 + -