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

📄 universe.c

📁 VxWorkS下 MV2604的BSP源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    return(ERROR);	}    /* install the handler in the vector table */    if (intConnect (INUM_TO_IVEC(univVecNum), routine, parameter) == ERROR)        return(ERROR);    return (OK);    }/********************************************************************************* sysMailboxInt - mailbox interrupt handler** This routine calls the installed mailbox routine, if it exists.*/LOCAL void sysMailboxInt (void)    {    unsigned char 	sigLmIntr;    sigLmIntr = *((unsigned char *)CPU_SIG_LM_STATUS_REG);    /* make sure the interrupt is a mailbox interrupt */    if ((sigLmIntr & SIG1_INTR_ENABL) && (sigLmIntr & SIG1_INTR_STATUS))	{        /* clear the mailbox intr */        UNIV_OUT_BYTE(CPU_SIG_LM_CONTROL_REG, SIG1_INTR_CLEAR);        if (sysMailboxRoutine != NULL)            sysMailboxRoutine (sysMailboxArg);        }    }/********************************************************************************* sysMailboxConnect - connect a routine to the mailbox interrupt** This routine specifies the interrupt service routine to be called at each* mailbox interrupt.** NOTE: The mailbox interrupt is SIG1.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), sysMailboxEnable()*/STATUS sysMailboxConnect    (    FUNCPTR routine,    /* routine called at each mailbox interrupt */    int arg             /* argument with which to call routine      */    )    {    static BOOL sysMailboxConnected = FALSE;    if (!sysMailboxConnected &&        intConnect (INUM_TO_IVEC (INT_VEC_IRQ0 + LM_SIG_INT_LVL),                        sysMailboxInt, 0) == ERROR)        {        return (ERROR);        }    sysMailboxConnected = TRUE;    sysMailboxRoutine   = routine;    sysMailboxArg       = arg;    /* clear the mailbox intr */    UNIV_OUT_BYTE(CPU_SIG_LM_CONTROL_REG, SIG1_INTR_CLEAR);    return (OK);    }/********************************************************************************* sysMailboxEnable - enable the mailbox interrupt** This routine enables the mailbox interrupt.** NOTE: The mailbox interrupt is SIG1.** RETURNS: OK, always.** SEE ALSO: sysMailboxConnect(), sysMailboxDisable()*/STATUS sysMailboxEnable    (    char *mailboxAdrs           /* address of mailbox (ignored) */    )    {    UCHAR status;    /* enable the SIG1 interrupt */    UNIV_IN_BYTE(CPU_SIG_LM_STATUS_REG, &status);    UNIV_OUT_BYTE(CPU_SIG_LM_STATUS_REG, SIG1_INTR_ENABL | (0xF0 & status));    intEnable (LM_SIG_INT_LVL);    return (OK);    }/********************************************************************************* sysMailboxDisable - disable the mailbox interrupt** This routine disables the mailbox interrupt.** NOTE: The mailbox interrupt is SIG1.** RETURNS: OK, always.** SEE ALSO: sysMailboxConnect(), sysMailboxEnable()*/STATUS sysMailboxDisable    (    char *mailboxAdrs           /* address of mailbox (ignored) */    )    {    /* clear and disable the mailbox interrupts */    UNIV_OUT_BYTE(CPU_SIG_LM_CONTROL_REG, SIG1_INTR_CLEAR);    UNIV_OUT_BYTE(CPU_SIG_LM_STATUS_REG, ~SIG1_INTR_ENABL);    intDisable (LM_SIG_INT_LVL);    return (OK);    }/********************************************************************************* sysUnivVERRClr - Universe VMEbus Error Clear routine** This is the VMEbus Error clear routine for the Tundra Universe PCI to VME* Bridge.  It counts the ocuurances at the specified counter and clears the* error condition in the three registers associated with VME Bus Errors:* LINT_STAT, VINT_STAT, and V_AMERR.** RETURNS: N/A*/void sysUnivVERRClr (void)    {    UINT32 status;    /* Count occurances */    ++sysUnivVERRCnt;    /* Get current address error status */    UNIV_IN_LONG(UNIVERSE_V_AMERR, &status);    /* Clear any error */    status &= V_AMERR_V_STAT;    UNIV_OUT_LONG(UNIVERSE_V_AMERR, status);    /* Get current VME error status */    UNIV_IN_LONG(UNIVERSE_VINT_STAT, &status);    /* Clear any error */    status &= VINT_STAT_VERR;    UNIV_OUT_LONG(UNIVERSE_VINT_STAT, status);    /* Get current PCI error status */    UNIV_IN_LONG(UNIVERSE_LINT_STAT, &status);    /* Clear any error */    status &= LINT_STAT_VERR;    UNIV_OUT_LONG(UNIVERSE_LINT_STAT, status);    /* Force write due to Write-Posting and get updated status */    UNIV_IN_LONG(UNIVERSE_PCI_CSR, &status);    }/********************************************************************************* sysUnivLevelDecode - decode highest pending priority Universe interrupt** This routine decodes the highest pending priority Universe interrupt from a* bit field of interrupts and returns the associated interrupt vector, priority* level and priority level bit mask.** RETURNS: highest pending interrupt priority level bit mask** SEE ALSO: register and bit field defs in universe.h*/int sysUnivLevelDecode    (    int   bitField,	/* one interrupt per bit, up to 15 bits */    int * vecNum,	/* where to return associated vector */    int * intLvl	/* where to return associated Universe int level */    )    {    int    bitLvlMsk;    int    i;    int    vector;    /* Compare bits in order of highest priority first */    for (i = UNIV_NUM_INT; i >= 0; --i)	{	if (bitField & univIntTable[i].bitMask)	    break;	}    /* Determine and return interrupt vector, priority level and level mask */    bitLvlMsk = univIntTable[i].bitMask;    if (univIntTable[i].vector != -1)        *vecNum = univIntTable[i].vector;    else	{	switch (bitLvlMsk)            {            case LVL7:                UNIV_IN_LONG(UNIVERSE_V7_STATID, &vector);                break;            case LVL6:                UNIV_IN_LONG(UNIVERSE_V6_STATID, &vector);                break;            case LVL5:                UNIV_IN_LONG(UNIVERSE_V5_STATID, &vector);                break;            case LVL4:                UNIV_IN_LONG(UNIVERSE_V4_STATID, &vector);                break;            case LVL3:                UNIV_IN_LONG(UNIVERSE_V3_STATID, &vector);                break;            case LVL2:                UNIV_IN_LONG(UNIVERSE_V2_STATID, &vector);                break;            case LVL1:                UNIV_IN_LONG(UNIVERSE_V1_STATID, &vector);                break;            }	/*	 * Check for errors	 *   At this point, if a VME bus error has occured, it must be	 * cleared by the sysUnivVERRClr() routine and the vector discarded.	 * The vector returned during a VME bus error is bogus.	 */	if ((vector & V1_STATID_ERR) != 0)            {	    /* Clear VME bus error */	    sysUnivVERRClr ();            /* Discard bad vector */            *vecNum = 0;            }        else            *vecNum = vector & 0xFF;  /* only eight bits of useful info */	}    *intLvl = i;    return (bitLvlMsk);    }/********************************************************************************* sysUnivVmeIntr - Raven VMEbus interrupt handler** This is the VMEbus interrupt handler for the Motorola Raven PCI Host* Bridge (PHB) and Multi-Processor Interrupt Controller (MPIC).  It is* connected to the single VMEbus interrupt from the Raven and examines the* Universe to chip to determine the interrupt level and vector of the* interrupt source.  Having obtained the vector number, this routine then* vectors into the system vector table to the specified interrupt handling* routine.** RETURNS: N/A*/void sysUnivVmeIntr (void)    {    int                 pendingIntr;    int                 highestIntr;    int			prevIntLvl;    int			univIntLvl;    int			vec_num = 0;    INT_HANDLER_DESC *  currHandler;    /* get pending interrupt level(s) */    UNIV_IN_LONG(UNIVERSE_LINT_STAT, &pendingIntr);    pendingIntr &= LINT_STAT_INT_MASK;    pendingIntr &= sysUnivIntsEnabled;    /*     * Handle pending interrupts in order of highest priority.     *     * For each interrupt, determine the level, get vector associated     * with the interrupt, set the appropriate interrupt level, clear the     * interrupt in the Universe, and dispatch to all associated ISRs.     */    if (pendingIntr != 0)	{	/* Determine highest interrupt priority level and vector */        highestIntr = sysUnivLevelDecode (pendingIntr, &vec_num, &univIntLvl);	/* Set intr level: mask out all ints at and below this level */        prevIntLvl = sysUnivIntLevelSet (univIntLvl);        vec_num   &= 0xff;        if (vec_num == 0)	    {	    logMsg ("bad vme interrupt %d\n", vec_num, 0,0,0,0,0);	    }        else if ((currHandler = sysIntTbl[vec_num]) == NULL)	    logMsg ("uninitialized vme interrupt %d\n", vec_num, 0,0,0,0,0);        else	    {	    while (currHandler != NULL)	        {	        currHandler->vec (currHandler->arg);	        currHandler = currHandler->next;	        }	    }        /* Clear interrupt request in Universe */	UNIV_OUT_LONG(UNIVERSE_LINT_STAT, highestIntr);	/* restore previous interrupt level */	(void)sysUnivIntLevelSet (prevIntLvl);        }    return;    }/******************************************************************************** sysBusRmwEnable - enable Read-Modify-Write (RMW) cycle on VMEbus** NOTE: These parameters are written to the SCG as Big-Endian values.* This is probably a bug because all other registers in the* Universe are Little-Endian.** RETURNS: N/A*/void sysBusRmwEnable    (    UINT swapCompareEnable,	/* Enabled bits involved in compare and swap */    UINT compareData,		/* Data to compare with read portion of RMW */    UINT swapData,		/* Data to write during write portion of RMW */    char *  rmwAddress		/* RMW address */    )    {    *UNIVERSE_SCYC_EN = swapCompareEnable;    *UNIVERSE_SCYC_CMP = compareData;    *UNIVERSE_SCYC_SWP = swapData;    /* Convert RMW address to a PCI address */#ifdef	EXTENDED_VME    UNIV_OUT_LONG(UNIVERSE_SCYC_ADDR,  (UINT)((UINT)rmwAddress +					(UINT)(CPU2PCI_OFFSET0_VAL << 16)));#else	/* psuedo-PReP Mapping */    UNIV_OUT_LONG(UNIVERSE_SCYC_ADDR,  (UINT)((UINT)rmwAddress +					(UINT)(CPU2PCI_OFFSET2_VAL << 16)));#endif	/* EXTENDED_VME */    /* Configure Special Cycle Generator to generate a RMW cycle */    UNIV_OUT_LONG(UNIVERSE_SCYC_CTL, SCYC_CTL_RMW);    }/******************************************************************************** sysBusRmwDisable - Disable Read-Modify-Write (RMW) cycle on the VMEbus.** Disable Read-Modify-Write (RMW) cycle on the VMEbus.** RETURNS: N/A*/void sysBusRmwDisable ()    {    UNIV_OUT_LONG(UNIVERSE_SCYC_CTL, SCYC_CTL_DISABLE);    }#ifdef	INCLUDE_VME_DMA/* * The following routines whose names start with "sysVmeDma" * comprise the DMA driver. *//******************************************************************************** sysVmeDmaInit - Inititalize the Universe's DMA engine** This routine will initialize the Universe's DMA engine.  This involves* using the following #defines listed in config.h as defaults to configure* the appropriate fields in the DMA's DCTL and DGCS registers.* .CS*	VME_DMA_XFER_TYPE*	VME_DMA_ADDR_SPACE*	VME_DMA_DATA_TYPE*	VME_DMA_USER_TYPE* .CE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -