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

📄 sysmpc107epic.c

📁 Vxworks的bsp软件开发包(基于wrPpmc74xx)
💻 C
字号:
/* sysMpc107Epic.c - Motorola MPC107 Interrupt Controller driver *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01b,17dec01,g_h  Add Wind View instrumentation.01a,12may01,g_h  written*//*DESCRIPTIONThis module implements the MPC107 EPIC interrupt controller driver.INCLUDES: sysMpc107Epic.h*//* includes */#include "sysMpc107Epic.h"#ifdef INCLUDE_WINDVIEW#include "private/eventP.h"#endif /* INCLUDE_WINDVIEW *//* defines */#define LEVEL_SENSE	EPIC_INT_SENSE#define EDGE_SENSE	0#define ACTIVE_HIGH	EPIC_INT_POLARITY#define ACTIVE_LOW	0/* 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		sysMpc107EpicIntHandler (void);IMPORT UINT	   sysVectorIRQ0; 	   /* vector for IRQ0 */INT_HANDLER_DESC * sysIntTbl [256]; /* system interrupt table */int tpr;int spurIntCnt;/* forward declarations */LOCAL STATUS sysMpc107EpicIntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine, int parameter);LOCAL int    sysMpc107EpicIntEnable (int);LOCAL int    sysMpc107EpicIntDisable (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/***************************************************************************** sysMpc107EpicInit - initialize the EPIC in the MPC107** This function initializes the Embedded Programmable * Interrupt Controller (EPIC) which is part of the MPC107.** 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** SEE ALSO: sysMpc107EpicIntConnect(), sysMpc107EpicIntEnable(), *           sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */STATUS sysMpc107EpicInit     (    void    )    {    int	i;    /* 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, sysMpc107EpicIntHandler);    /*     *  Set up the BSP specific routines     *  Attach the local routines to the vxWorks system calls     */    _func_intConnectRtn = sysMpc107EpicIntConnect;    _func_intEnableRtn  = sysMpc107EpicIntEnable;    _func_intDisableRtn = sysMpc107EpicIntDisable;    *EPIC_GCR = LONGSWAP(0xa0000000);		/* reset the EPIC */    for (i=0;i < 1024;i++);			/* wait for reset to complete */      *EPIC_GCR = LONGSWAP(0x20000000);		/* put the EPIC into mixed mode */    /* initialize all interrupt sources */    /* external interrupts */    *EPIC_EISVP0 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE  | ACTIVE_LOW |                            INT_VEC_IRQ0  | INT_PRI_IRQ0);    *EPIC_EISVP1 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW |			    INT_VEC_NONE  | INT_PRI_NONE);    *EPIC_EISVP2 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW |			    INT_VEC_NONE  | INT_PRI_NONE);    *EPIC_EISVP3 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_LOW |		            INT_VEC_NONE  | INT_PRI_NONE);    *EPIC_EISVP4 = LONGSWAP(EPIC_INT_MASK | LEVEL_SENSE | ACTIVE_HIGH |			    INT_VEC_IRQ4  | INT_PRI_IRQ4);    /* timer interrupts */    *EPIC_GTVR0 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR0 | INT_PRI_TMR0);    *EPIC_GTVR1 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR1 | INT_PRI_TMR1);    *EPIC_GTVR2 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR2 | INT_PRI_TMR2);    *EPIC_GTVR3 = LONGSWAP(EPIC_INT_MASK | INT_VEC_TMR3 | INT_PRI_TMR3);    /* DMA,I2C and I20 interrupts */    *EPIC_DMA0_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA0  | INT_PRI_DMA0);    *EPIC_DMA1_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_DMA1  | INT_PRI_DMA1);    *EPIC_I2C_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2C  | INT_PRI_I2C);    *EPIC_I2O_VR = LONGSWAP(EPIC_INT_MASK | INT_VEC_I2O  | INT_PRI_I2O);    /* set the current processor priority level */    *EPIC_PCTP  =  LONGSWAP(0x00);    /* clear out all possible pending interrupts */    while (*EPIC_PIACK != LONGSWAP(INT_VEC_SPURIOUS))        {	*EPIC_PEOI = 0;        }        return OK;    }/***************************************************************************** sysMpc107EpicIntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK/ERROR.** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntEnable(), *           sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */ LOCAL STATUS sysMpc107EpicIntConnect    (     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);    } /***************************************************************************** sysMpc107EpicIntEnable - enable an EPIC external interrupt level** This routine enables a specified EPIC interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), *           sysMpc107EpicIntDisable(), sysMpc107EpicIntHandler() */ LOCAL int sysMpc107EpicIntEnable    (    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     */    (EPIC_EISVP0)[intLevel*8] &= LONGSWAP(~EPIC_INT_MASK) ;     return (OK);    }/***************************************************************************** sysMpc107EpicIntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), *           sysMpc107EpicIntEnable(), sysMpc107EpicIntHandler() */ LOCAL int sysMpc107EpicIntDisable    (    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     */    (EPIC_EISVP0)[intLevel*8] |= LONGSWAP(EPIC_INT_MASK) ;     return (OK);    }/***************************************************************************** sysMpc107EpicIntHandler - handle an interrupt received at the Mpic* * This routine will process interrupts received EPIC interrupt sources.** RETURNS: N/A** SEE ALSO: sysMpc107EpicInit(), sysMpc107EpicIntConnect(), *           sysMpc107EpicIntEnable(), sysMpc107EpicIntDisable() */void sysMpc107EpicIntHandler     (    void    )    {     int                dontCare;     INT_HANDLER_DESC * currHandler;    UINT32	       vecNum;    /* get the vector from the EPIC IACK reg. */        vecNum = *EPIC_PIACK ; EIEIO ;    vecNum = LONGSWAP(vecNum) & VECTOR_MASK ; #ifdef INCLUDE_WINDVIEW    WV_EVT_INT_ENT (vecNum);#endif /* INCLUDE_WINDVIEW */    /* 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.         */        CPU_INT_UNLOCK(_PPC_MSR_EE);        /* call the necessary interrupt handlers */        if ((currHandler = sysIntTbl [vecNum]) == NULL)            {            logMsg ("uninitialized MPC107 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;                }            }	/* 	 * Disable External Interrupts	 * External Interrupts will be re-enabled in the kernel's wrapper	 * of this Interrupt.	 */	        CPU_INT_LOCK (&dontCare);        /* issue an end-of-interrupt to the EPIC */	*EPIC_PEOI = 0 ;  EIEIO ;        /* get the next vector from the EPIC IACK reg. */       	vecNum = *EPIC_PIACK ; EIEIO ;         vecNum = LONGSWAP(vecNum) & VECTOR_MASK ;          }    return;    }

⌨️ 快捷键说明

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