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

📄 universe.c

📁 VxWorks下 MV2400的BSP源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    UNIV_IN_LONG(UNIVERSE_STATID, &statidReg);    vector >>= 1;    statidReg = (statidReg & STATID_MASK) | (vector << 25);    UNIV_OUT_LONG(UNIVERSE_STATID, statidReg);    /* Generate a SW interrupt on the VMEbus at the requested level */    UNIV_IN_LONG(UNIVERSE_VINT_EN, &enReg);    enReg |= ((1 << level) << 24);    UNIV_OUT_LONG(UNIVERSE_VINT_EN, enReg);    /* unlock the interrupt */    CPU_INT_UNLOCK(lockKey);    return (OK);    }/********************************************************************************* sysUnivIntEnable - enable Universe-supported interrupt(s)** This routine enables the specified type(s) of interrupt supported by the* Universe VME-to-PCI bridge.** RETURNS: OK, or ERROR if invalid interrupt type(s).** SEE ALSO: sysUnivIntDisable()**/STATUS sysUnivIntEnable    (    int univIntType	/* interrupt type */    )    {    /* make sure the interrupt type is valid */    if ((univIntType & UNIVERSE_INT_MASK)     == 0 ||	(univIntType & UNIVERSE_RESERVED_INT) != 0   )	return(ERROR);    /* clear any pending intr. for the type */    UNIV_OUT_LONG(UNIVERSE_LINT_STAT, univIntType);    /* enable the interrupt */    sysUnivIntsEnabled |= univIntType;    UNIV_OUT_LONG(UNIVERSE_LINT_EN, sysUnivIntsEnabled);    /* map the interrupt.  Currently all VME ints are mapped to LINT#0 */    UNIV_OUT_LONG(UNIVERSE_LINT_MAP1, 0);    return (OK);    }/********************************************************************************* sysUnivIntDisable - disable Universe-supported interrupt(s)** This routine disables the specified type(s) of interrupt supported by the * Universe VME-to-PCI bridge.** RETURNS: OK, or ERROR if invalid interrupt type(s).** SEE ALSO: sysUnivIntEnable()**/STATUS sysUnivIntDisable    (    int univIntType /* interrupt type */    )    {    /* make sure the interrupt type is valid */    if ((univIntType & UNIVERSE_INT_MASK)     == 0 ||	(univIntType & UNIVERSE_RESERVED_INT) != 0   )        return (ERROR);    /* disable the interrupt */    sysUnivIntsEnabled &= ~univIntType;    UNIV_OUT_LONG(UNIVERSE_LINT_EN, sysUnivIntsEnabled);    /* clear any pending intr. for the type */    UNIV_OUT_LONG(UNIVERSE_LINT_STAT, univIntType);    return (OK);    }/********************************************************************************* sysUnivIntLevelSet - set a Universe-supported interrupt level** This routine disables all interrupts supported by the Universe at and below* the specified level.  The lowest level is 0, the highest is 15.  The* priority mapping is:* .CS*    0		no interrupts masked*    1		UNIVERSE_VOWN_INT*    2		VMEBUS_LVL1*    3		VMEBUS_LVL2*    4		VMEBUS_LVL3*    5		VMEBUS_LVL4*    6		VMEBUS_LVL5*    7		VMEBUS_LVL6*    8		VMEBUS_LVL7*    9		UNIVERSE_DMA_INT*    10		UNIVERSE_LERR_INT*    11		UNIVERSE_VERR_INT*    12		UNIVERSE_VME_SW_IACK_INT*    13		UNIVERSE_PCI_SW_INT*    14		UNIVERSE_SYSFAIL_INT*    15		UNIVERSE_ACFAIL_INT* .CE** If the level specified is -1, the level is not changed, just the current* level is returned.** RETURNS: previous interrupt level.** SEE ALSO: sysUnivIntDisable(), sysUnivIntEnable()*/int sysUnivIntLevelSet    (    int  univIntLvl	/* Universe interrupt level */    )    {    int  intLvl;    int  key;    /* Just return current level if so requested */    if (univIntLvl == -1)	return (sysUnivIntLevel);    /* Lock out interrupts during level change */    CPU_INT_LOCK(&key);    /* disable the interrupt levels at and below the current level */    intLvl = univIntTable[univIntLvl].intMask;    intLvl &= sysUnivIntsEnabled;    UNIV_OUT_LONG(UNIVERSE_LINT_EN, intLvl);    /* save current level for return */    intLvl = sysUnivIntLevel;    /* set new mask */    sysUnivIntLevel = univIntLvl;    /* Unlock interrupts */    CPU_INT_UNLOCK(key);    /* return previous mask */    return (intLvl);    }/******************************************************************************** sysUnivIntConnect - connect an interrupt handler for an interrupt type** This routine connects an interrupt handler for a specified interrupt type * to the system vector table of the Universe VME-to-PCI bridge.** RETURNS: OK, or ERROR if any argument is invalid or memory cannot be* allocated.*/STATUS sysUnivIntConnect    (    int		univIntType,  /* the interrupt type to connect with */    VOIDFUNCPTR	routine,      /* routine to be called */    int		parameter     /* parameter to be passed to routine */    )    {    int			univVecNum = 0;    /* make sure the interrupt type is valid */    if ((univIntType & UNIVERSE_INT_MASK) == 0)        return (ERROR);    /* determine the vector number for the interrupt */    switch(univIntType)	{	case UNIVERSE_DMA_INT:	    univVecNum = UNIV_DMA_INT_VEC;	    break;	case UNIVERSE_LERR_INT:	    univVecNum = UNIV_LERR_INT_VEC;	    break;	case UNIVERSE_VERR_INT:	    univVecNum = UNIV_VERR_INT_VEC;	    break;	case UNIVERSE_SYSFAIL_INT:	    univVecNum = UNIV_SYSFAIL_INT_VEC;	    break;	case UNIVERSE_ACFAIL_INT:	    univVecNum = UNIV_ACFAIL_INT_VEC;	    break;	case UNIVERSE_PCI_SW_INT:	    univVecNum = UNIV_PCI_SW_INT_VEC;	    break;	case UNIVERSE_VME_SW_IACK_INT:	    univVecNum = UNIV_VME_SW_IACK_INT_VEC;	    break;	case UNIVERSE_VOWN_INT:	    univVecNum = UNIV_VOWN_INT_VEC;	    break;	default:	    /* doesn't match one of the intr. types, so return an error */	    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 - Hawk VMEbus interrupt handler** This is the VMEbus interrupt handler for the Motorola Hawk PCI Host* Bridge (PHB) and Multi-Processor Interrupt Controller (MPIC).  It is* connected to the single VMEbus interrupt from the Hawk 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 */

⌨️ 快捷键说明

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