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

📄 mpc8240epic.c

📁 MPC8241:本程序是freescale的824*系列的BSP源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    int intLevel        /* interrupt level to enable */
    )
    {
    LOCAL_INT_DATA	enable;
	
	/*int mask;*/
    /* Validate vector.  */

    if (intLevel < 0)
        return (ERROR);

#if(0)
	/* add by xdg 00.10.13*/
	if(intLevel>=WBPIC_INTERRUPT_BASE && intLevel<WBPIC_INTERRUPT_BASE+0x10)
	{
		mask = sysPciIbcIntEnable (intLevel-WBPIC_INTERRUPT_BASE);

        if (mask == ERROR)
        {
            return (ERROR);
        }
		return( OK );
	}
#endif

    enable.regAddr = getEpicVecAddr(intLevel);

    if (enable.regAddr > 0)
        {
        /* read the vector register */

        enable.regVal = sysPciInLong((UINT32)(enable.regAddr));

        /* enable the interrupt */

        enable.regVal &= (~INT_MASK_BIT);

        /* write the contents of the vector register back */

        sysPciOutLong((UINT32)(enable.regAddr), enable.regVal);

        }

    return (OK);
    }


/******************************************************************************
*
* sysEpicIntDisable - disable an Epic interrupt level
*
* This routine disables a specified Epic interrupt level.
*
* RETURNS: OK or ERROR if interrupt level not supported
*/

LOCAL int sysEpicIntDisable
    (
    int intLevel        /* interrupt level to disable */
    )
    {
    LOCAL_INT_DATA      disable;
 	/*int mask;*/

    /* Validate vector.  */

    if (intLevel < 0)
        return (ERROR);

#if(0)  /*because no winbond*/
	/* add by xdg 00.10.13*/
	if(intLevel>=WBPIC_INTERRUPT_BASE && intLevel<WBPIC_INTERRUPT_BASE+0x10)
	{
		mask = sysPciIbcIntDisable (intLevel-WBPIC_INTERRUPT_BASE);

        if (mask == ERROR)
        {
            return (ERROR);
        }
		return( OK );
	}
#endif

    /* get the vector reg. offset value */

    disable.regAddr = getEpicVecAddr(intLevel);
 
    if (disable.regAddr > 0)
        {
        /* read the vector register */

        disable.regVal = sysPciInLong((UINT32)(disable.regAddr));

        /* disable the interrupt */

        disable.regVal |= INT_MASK_BIT;

        /* write the contents of the vector register back */

        sysPciOutLong((UINT32)(disable.regAddr), disable.regVal);
        }

    return (OK);
    }


/*******************************************************************************
*
* sysEpicIntHandlerExec  - execute the handlers for a given vector
* 
* This routine executes all the handlers chained to a given vector.
* If a vector has no handlers attached to it, a logMsg is generated.
*
* NOMANUAL
*
* RETURNS: N/A
* This functiong added by xdg, 00.10.13
*/

void sysEpicIntHandlerExec
    (
    UCHAR intVec
    )
	{    
    INT_HANDLER_DESC * pCurrHandler;

    /*  call each respective interrupt handler */	

    if ((pCurrHandler = sysIntTbl [intVec]) == NULL)
    {
		logMsg ("uninitalized PIC interrupt vector %x\r\n",
                intVec, 0,0,0,0,0);
    }
    else
    {

		/* call Each respective chained interrupt handler  */

		while (pCurrHandler != NULL)
    	{
  	    	(*pCurrHandler->vec) (pCurrHandler->arg);
	    	pCurrHandler = pCurrHandler->next;
    	}
    }
	}

/*add by zhu*/
#ifndef PPC_EIEIO_SYNC
#define PPC_EIEIO_SYNC	__asm__ volatile ("   eieio;  sync")	
#endif

void sysEUMBBARWrite
    (
    ULONG regNum,
    ULONG regVal
    )
    {
  
    *(ULONG *) (EPIC_EOI_REG + regNum) = LONGSWAP(regVal);
    PPC_EIEIO_SYNC;  
    return ;
    }


/******************************************************************************
*
* sysEpicIntHandler - handle an interrupt received at the Epic
* 
* This routine will process interrupts received from PCI or ISA devices as
* these interrupts arrive via the EPIC.  This routine supports EPIC interrupt
* nesting.
*
* RETURNS: N/A
*/

void sysEpicIntHandler 
    (
    void
    )
    {
    UINT32		vecNum;
    UINT32		vecRegAddr;
    int			dontCare;
    int			intPriority;

	int oldLevel;

    /* get the vector from the EPIC IACK reg. */

    vecNum = sysPciInLong((UINT32)EPIC_IACK_REG);

    vecNum &= VECTOR_MASK;

	/* add by xdg */

    /* Check for spurious interrupt. */

    if (vecNum == 0xFF)
    {
        /*logMsg ("EPIC Spurious Interrupt!\n", 0,0,0,0,0,0);*/
        return;
    }

#if(1)
	vecRegAddr = getEpicVecAddr(vecNum);
	intPriority = getEpicPrio(vecRegAddr);
	if ((oldLevel = epicCurTaskPrioSet (intPriority)) == EPIC_INV_PRIO_ERROR)
    {
		return;
    }
#endif
 
    /*
     * Allow maskable interrupts to the CPU.  EPIC will hold off
     * lower and equal interrupts until EPIC_EOI is performed.
     */

    CPU_INT_UNLOCK(_PPC_MSR_EE);

#ifdef INCLUDE_INSTRUMENTATION /*should not be defined */
    if (evtLogTIsOn)
      (* _func_evtLogT1_noTS) (EVENT_INT_ENT((int)vecNum),
			       evtTimeStamp);
#endif

	sysEpicIntHandlerExec( (UCHAR)vecNum );	
    
    /* Disable external interrupts. */

    CPU_INT_LOCK(&dontCare);

    /*
     * ERRATA FIX:
     *   sysDecDelay() is needed for Mpc8240(MPC8240) Revision 1.0/1.1
     *   Errata #2, EPIC Serial Mode Interrupt Twice from Single Source.
     *   See Mpc8240 Errata Sheet - Version 1.0.3
     */

 /*del by zhu , 6.11*/
/*    sysDecDelay(1);*/

    /* Issue an end-of-interrupt to the EPIC */
    sysPciOutLong((UINT32)EPIC_EOI_REG, 0);
	PPC_EIEIO_SYNC;

/* add by xdg */ 
#if(1)
	epicCurTaskPrioSet (oldLevel);
#endif

    return;
    }

/******************************************************************************
*
* getEpicVecAddr - get the vector address of an EPIC register 
*
* This routine returns the appropriate EPIC register address based on the
* specified EPIC interrupt level.
*
* RETURNS: EPIC register address or zero if not a supported level.
*/

LOCAL int getEpicVecAddr
    (
    int		intLevel	/* interrupt level to translate */
    ) 
    {
    int 	offset = 0;

    /* check for a timer interrupt level */

    if ((intLevel >= TIMER_INTERRUPT_BASE) && 
        (intLevel < EXTERNAL_INTERRUPT_BASE))
        {
        offset = intLevel - TIMER_INTERRUPT_BASE;
        offset = (int)EPIC_TIMER0_VEC_PRI_REG + (offset * REG_OFFSET * 4);
        }

	/* check for Internal interrupt level */
    if ((intLevel >= INTERNAL_INTERRUPT_BASE) && 
        (intLevel < SERIAL_INTERRUPT_BASE))
        {
        offset = intLevel - INTERNAL_INTERRUPT_BASE;
        offset = (int)EPIC_I2C_INTR_VEC_SRC + (offset * REG_OFFSET * 2);
        }
	
	
    /* check for external interrupt level */

    if ((intLevel >= EXTERNAL_INTERRUPT_BASE) && 
        (intLevel < INTERNAL_INTERRUPT_BASE))
        {
        offset = intLevel - EXTERNAL_INTERRUPT_BASE;
        offset = (int)EPIC_EXT_SRC0_VEC_PRI_REG + (offset * REG_OFFSET * 2);
        }
 
    /* check for a serial interrupt level */

    if (intLevel >= SERIAL_INTERRUPT_BASE)
        {
        offset = intLevel - SERIAL_INTERRUPT_BASE;
        offset = (int)EPIC_SER_SRC0_VEC_PRI_REG + (offset * REG_OFFSET * 2);
    	}
    
    /*check for Message Unit interrupt level, 8.21, by zhu*/
    if (intLevel == MSGUNIT_INT_LVL)
    	{
    	offset = (int)EPIC_MSG_UNIT_INTR_VEC_SRC;
    	}
    if ((intLevel >= DUART_INTERRUPT_BASE) && 
        (intLevel < DUART_INTERRUPT_BASE+2))  
        {
        offset = intLevel - DUART_INTERRUPT_BASE;
        offset = (int)EPIC_DUART_CHAN1_INTR_VEC_SRC + (offset * REG_OFFSET * 2);
    	} 
    return (offset);
    }


/***************************************************
* getEpicPrio(UINT32 vecRegAddr)
*
* added by xdg, 01.1.9
*/

LOCAL int getEpicPrio(UINT32 vecRegAddr)
{
	UINT32 temp;

	temp = sysPciInLong(vecRegAddr);
	return((temp&EPIC_SRC_PRI_MASK)>>16);
}

⌨️ 快捷键说明

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