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

📄 m8240epic.c

📁 VxWorks下的PowerPC 824X系列CPU的bSP包!
💻 C
字号:
/* m8240Epic.c - Motorola MPC8240 Interrupt Controller driver *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01a,24may99,wfg  written*//*DESCRIPTIONThis module implements the MC8240 EPIC interrupt controller driver.*//* includes */#include "m8240Epic.h"/* defines *//* globals */IMPORT STATUS (*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);IMPORT int    (*_func_intEnableRtn) (int);IMPORT int    (*_func_intDisableRtn) (int);IMPORT void   sysOutByte (ULONG, UCHAR);IMPORT UCHAR  sysInByte (ULONG);IMPORT void   sysPciRead32 (UINT32, UINT32 *);IMPORT void   sysPciWrite32 (UINT32, UINT32);IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);void	      sysEpicIntHandler (void);IMPORT UINT        sysVectorIRQ0; 	/* vector for IRQ0 */INT_HANDLER_DESC * sysIntTbl [256];	/* system interrupt table */int                tpr;int                spurIntCnt;#ifdef INCLUDE_INSTRUMENTATIONIMPORT	int        evtTimeStamp;#endif/* forward declarations */LOCAL STATUS	sysEpicIntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine,   		                   int parameter);LOCAL int	sysEpicIntEnable (int);LOCAL int	sysEpicIntDisable (int);#ifndef CPU_INT_LOCK#   define CPU_INT_LOCK(x) \	(*x = intLock ())#endif#ifndef CPU_INT_UNLOCK#   define CPU_INT_UNLOCK(data) \	(intUnlock (data))#endif/************************************************************************* sysEpicInit - initialize the EPIC in the MC8240** This function initializes the Embedded Programmable *   Interrupt Controller (EPIC) which is part of the 8240.** It first initializes the system vector table, connects the EPIC interrupt* handler to the PPC external interrupt and attaches the local EPIC routines* for interrupt connecting, enabling and disabling to the corresponding system* routine pointers.** It then initializes the EPIC register and clears any pending EPIC interrupts.** RETURNS: OK always*/STATUS sysEpicInit     (    void    )    {    int	i;    int	j;    /* Initialize the interrupt table */    for (i = 0; i < 256; i++)        sysIntTbl[i] = NULL;     /* Connect the interrupt demultiplexer to the PowerPC external interrupt */    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysEpicIntHandler);    /*     *  Set up the BSP specific routines     *  Attach the local routines to the vxWorks system calls     */    _func_intConnectRtn = sysEpicIntConnect;    _func_intEnableRtn  = sysEpicIntEnable;    _func_intDisableRtn = sysEpicIntDisable;    /* Initialize the MPIC */    /* reset the EPIC */    *M8240_EPIC_GCR(EUMB) = 0x0a0 ;     for (i=0; i < 1024 ; i++);   /* wait for reset to complete */      /* put the EPIC into mixed mode */    *M8240_EPIC_GCR(EUMB) = 0x020 ;     /* initialize all interrupt sources */    /* external interrupts */    *M8240_EPIC_EISVP0(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_EXT_IRQ0 | INT_PRI_EXT_IRQ0) ;     *M8240_EPIC_EISVP1(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_EXT_IRQ1 | INT_PRI_EXT_IRQ1) ;     *M8240_EPIC_EISVP2(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_EXT_IRQ2 | INT_PRI_EXT_IRQ2) ;     *M8240_EPIC_EISVP3(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_EXT_IRQ3 | INT_PRI_EXT_IRQ3) ;     *M8240_EPIC_EISVP4(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_EXT_IRQ4 | INT_PRI_EXT_IRQ4) ;     /* timer interrupts */    *M8240_EPIC_GTVR0(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_TIMER0 | INT_PRI_TIMER0) ;     *M8240_EPIC_GTVR1(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_TIMER1 | INT_PRI_TIMER1) ;     *M8240_EPIC_GTVR2(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_TIMER2 | INT_PRI_TIMER2) ;     *M8240_EPIC_GTVR3(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_TIMER3 | INT_PRI_TIMER3) ;     /* DMA,I2C and I20 interrupts */    *M8240_EPIC_DMA0_VR(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA0  | INT_PRI_DMA0) ;     *M8240_EPIC_DMA1_VR(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA1  | INT_PRI_DMA1) ;     *M8240_EPIC_I2C_VR(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2C  | INT_PRI_I2C ) ;     *M8240_EPIC_I2O_VR(EUMB)        = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2O  | INT_PRI_I2O ) ;     /* set the current processor priority level */    *M8240_EPIC_PCTP(EUMB)  =  LONGSWAP (0x00) ;     /* clear out all possible pending interrupts */    for (i=0; i < 32 ; i++)         {         j = *M8240_EPIC_PIACK(EUMB) ; *M8240_EPIC_PEOI(EUMB) = 0 ;         }    return (OK);    }/************************************************************************* sysEpicIntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK/ERROR.*/ LOCAL STATUS sysEpicIntConnect    (    VOIDFUNCPTR * vector,         /* interrupt vector to attach */    VOIDFUNCPTR   routine,        /* routine to be called */    int           parameter       /* parameter to be passed to routine */    )    {    INT_HANDLER_DESC * newHandler;    INT_HANDLER_DESC * currHandler;    if (((int)vector < 0) || ((int)vector > 0xff))      /* Out of Range? */        return (ERROR);     /* create a new interrupt handler */    if ((newHandler = (INT_HANDLER_DESC *)calloc (1, sizeof (INT_HANDLER_DESC)))	 == NULL)        return (ERROR);     /* initialize the new handler */    newHandler->vec  = routine;    newHandler->arg  = parameter;    newHandler->next = NULL;    /* install the handler in the system interrupt table */    if (sysIntTbl[(int) vector] == NULL)        sysIntTbl [(int ) vector] = newHandler; /* single int. handler case */    else        {        currHandler = sysIntTbl[(int) vector]; /* multiple int. handler case */        while (currHandler->next != NULL)            {            currHandler = currHandler->next;            }        currHandler->next = newHandler;        }    return (OK);    } /************************************************************************* sysEpicIntEnable - enable an EPIC external interrupt level** This routine enables a specified EPIC interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysEpicIntEnable    (    int intLevel        /* interrupt level to enable */    )    {    /*     * if the int. level is not a valid IRQ      * If not supported, just return.     */    if ((intLevel < 0) || (intLevel > 4))        return (ERROR);    /* clear the interrupt mask bit          Note:              on pointer arithmetic subtlety below -             External Interrupt Vector Priority registers are 8 longwords apart     */    (M8240_EPIC_EISVP0(EUMB))[intLevel*8] &= LONGSWAP(~EPIC_INT_MASK) ;     return (OK);    }/************************************************************************* sysEpicIntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysEpicIntDisable    (    int intLevel        /* interrupt level to disable */    )    {    /*     * if the int. level is not a valid IRQ      * If not supported, just return.     */    if ((intLevel < 0) || (intLevel > 4))        return (ERROR);    /* set the interrupt mask bit          Note:              on pointer arithmetic subtlety below -             External Interrupt Vector Priority registers are 8 longwords apart     */    (M8240_EPIC_EISVP0(EUMB))[intLevel*8] |= LONGSWAP(EPIC_INT_MASK) ;     return (OK);    }/************************************************************************* sysEpicIntHandler - handle an interrupt received at the EPIC* * This routine will process interrupts received EPIC interrupt sources.** RETURNS: N/A*/void sysEpicIntHandler     (    void    )    {    INT_HANDLER_DESC *  currHandler;    UINT32		vecNum;    /* get the vector from the EPIC IACK reg. */    vecNum = *M8240_EPIC_PIACK(EUMB) ; EIEIO ;    vecNum = LONGSWAP(vecNum) & VECTOR_MASK ;     /* Ignore spurious interrupts */    if (vecNum == 0xFF) spurIntCnt++ ;    while (vecNum != 0xff)        {        /*         * Allow maskable interrupts to the CPU.  MPIC will hold off         * lower and equal interrupts until MPIC_EOI is performed.         */#ifdef INCLUDE_INSTRUMENTATION        if (evtLogTIsOn)            (* _func_evtLogT1_noTS) (EVENT_INT_ENT((int)vecNum), evtTimeStamp);#endif        /* call the necessary interrupt handlers */        if ((currHandler = sysIntTbl [vecNum]) == NULL)           {           logMsg ("uninitialized EPIC interrupt %d\r\n", vecNum, 0,0,0,0,0);           }       else           {           /* Call EACH respective chained interrupt handler */           while (currHandler != NULL)               {               currHandler->vec (currHandler->arg);               currHandler = currHandler->next;               }           }       /* issue an end-of-interrupt to the EPIC */       *M8240_EPIC_PEOI(EUMB) = 0 ;  EIEIO ;       /* get the next vector from the EPIC IACK reg. */       vecNum = *M8240_EPIC_PIACK(EUMB) ; EIEIO ;        vecNum = LONGSWAP(vecNum) & VECTOR_MASK ;         }    return;    }

⌨️ 快捷键说明

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