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

📄 sysepic.c

📁 这是WINDRIVER公司所开发的针对freescale公司最新的powerpc系列MPC8560的针对vxworks的bsp。对做powerpc嵌入式的很有用了。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* sysEpic.c - Driver for Embedded Programmable Interrupt Controller *//* Copyright 1984-2003 Wind River Systems, Inc. *//*modification history--------------------01g,19oct04,dtr  SPR 102606.01f,06may04,mil  Removed compiler warnings.01e,13oct03,mil  Added options for polarity and sense.01d,12sep03,mil  Added support for critical interrupts.01c,08jan03,mil  Created based on Sandpoint MPC107.*//*DESCRIPTIONThis module implements the Embedded Programmable Interrupt Controller (EPIC)driver for the MPC8540.The EPIC is an integrated interrupt controller in the 8540 whichprovides following major capabilities:  Support for twelve external interrupt sources and thirty-two internal  interrupt sources  Support for connection of external interrupt controller device e.g. 8259  like as implemented on a WinBond chip       12 external interrupt sources  32 internal interrupt sources  16 programmable interrupt priority levels  Fully-nested interrupt delivery  Spurious vector generation  Route to critical interrupt destinations  Route to external pin  Configurable sense and polarity at initialization and runtimeThe current implementation of this EPIC controller does not supportthe following features or mode of operations:  PIC global timers  Inter-processor interrupts  Messaging interruptsEPIC features are customized by writing into general control registersor into interrupt level specific registers (IVPRs).This driver allows a basic interface to the EPIC such as intializing it,setting interrupt vectors, priorities, level/edge sense and interruptpolarities, as well as enabling and disabling specific interrupts.This driver implements a complete interrupt architecture system, completewith vector table.Since interrupt vectors can be shared, this driver does provide foroverloading of interrupt routines (i.e. there isa list of interrupt routines for each interrupt vector (level)).  To servicea vector requires that all connected interrupt routines be called in orderof their connection.The following diagram shows an example of how interrupts canbe configured in this system.    EPIC Vector table0  |-------|  <-- external INT0 starts   |-------|   |-------|------------------------------+    ....                                  |   |-------|                              |   |-------|                              |12 |-------| <-- internal INT0 starts     |   (EPIC_MAX_EXT_IRQS) = 12   |-------|                              |   |-------|                              |    ....                                  |   |-------|                              |   |-------|                              |44 |-------| <-- global timer INT0 starts |   (EPIC_MAX_EXT_IRQS + \   |-------|                              |    EPIC_MAX_IN_IRQS) = 44   |-------|                              |   |-------|                              |48 |-------| <-- message INT0 starts      |   (EPIC_MAX_EXT_IRQS + \   |-------|                              |    EPIC_MAX_IN_IRQS + \   |-------|                              |    EPIC_MAX_GT_IRQS) = 48   |-------|                              |52 |-------| <-- IPI INT0 starts          |   (EPIC_MAX_EXT_IRQS + \   |-------|                              |    EPIC_MAX_IN_IRQS + \   |-------|                              |    EPIC_MAX_GT_IRQS + \55 |-------|                              |    EPIC_MAX_MSG_IRQS) = 5256 |-------|<-----------------------------+   sysVectorIRQ0 = 56 \    ....         WinBond int handler      |   = 52 + EPIC_MAX_IPI_IRQS   |-------|                              +-------------+   |-------|                                            |   |-------|                                 PCI slot 3 int handler   |-------|   |-------|<----- Cascaded 8259s   |-------|   |-------|    ....   |-------|   |-------|   |-------|   |-------|256|-------|The driver is designed to put external interrupts at the beginning of thevector table.  As a result, devices that route their interrupt to the EPICon the MPC8540 does not need to translate the vector number.  Therefore,the macros IVEC_TO_INUM(x) and INUM_TO_IVEC(x) are not necessary.  Forsome existing drivers, it may be necessary to use the following defines:  #undef  INUM_TO_IVEC  #define INUM_TO_IVEC(x) (x)  #undef  IVEC_TO_INUM  #define IVEC_TO_INUM(x) (x)If there are other devices in the system capable of generating their ownvectors then we presume that an appropriate interrupt handler is createdand attached to the vector associated with the correct IRQ number.  Thatinterrupt handler would get a new vector directly from the device and thencall all of the handlers attached to that new vector.  Vector information isstored in a linked list of INT_HANDLER_DESC structures. The sysIntTbl arraycontains a pointer to the first entry for each vector..SH INITIALIZATIONThis driver is initialized from the BSP, usually as part of sysHwInit().The first routine to be called is sysEpicInit(). The routine resets theglobal configuration register and resets the epic registers to defaultvalues.The second routine to be called is sysEpicIntrInit().  This routine takes noarguments. This routine allocates the vector table and initializes thechips to a default state.  All individual interrupt sources are disabled.Each has to be individually enabled by intEnable() before it will beunmasked and allowed to generate an interrupt..SH CRITICAL INTERRUPTTo enable the EPIC to handle also critical interrupt, or if a normalinterrupt is to be rerouted to the critical input pin, INCLUDE_EPIC_CRT_INTRshould be defined.  e.g. Define the following in config.h:  #define INCLUDE_EPIC_CRT_INTR     /@ include critical interrupt support @/The critical interrupt handler uses information from the summary registersCISR0 and CISR1.  The EPIC does not manage critical interrupts and henceIack or EOI do not apply.  It was seen that the summary registers gothrough a transient state before settling on the result.  This causesspurious interrupts to be generated, and the vectors being called.A typical behavior is the printout of "uninitialized PIC interruptvector 0xXX".  This is observed only when at least one source has beenrouted to critical pin..SH CUSTOMIZING THIS DRIVERThe BSP can change the default polarity and sensitivity for the externalinterrupt and the internal interrupt independently.  They are:  EPIC_EX_DFT_SENSE	/@ default to EPIC_SENSE_LVL @/  EPIC_EX_DFT_POLAR     /@ default to EPIC_INT_ACT_HIGH @/  EPIC_IN_DFT_POLAR     /@ default to EPIC_INT_ACT_HIGH @/If any of the above is defined before the inclusion of sysEpic.h, such asin config.h, the default will be overridden.  The available options are:  EPIC_EX_DFT_SENSE     EPIC_SENSE_LVL, EPIC_SENSE_EDG  EPIC_xx_DFT_POLAR     EPIC_INT_ACT_LOW, EPIC_INT_ACT_HIGH /@if level-sense @/                        EPIC_INT_EDG_NEG, EPIC_INT_EDG_POS  /@if edge-sense @/The macros CPU_INT_LOCK() and CPU_INT_UNLOCK provide the accessto the CPU level interrupt lock/unlock routines.  We presume that thereis a single interrupt line to the CPU.  By default these macros callintLock() and intUnlock() respectively.*//* includes */#include "vxWorks.h"#include "config.h"#include "sysEpic.h"#include "sysLib.h"#include "stdio.h"#include "string.h"#ifdef INCLUDE_WINDVIEW#include "private/eventP.h"#endif/* defines */#ifndef CPU_INT_LOCK#   define CPU_INT_LOCK(pData) \	(*pData = intLock ())#endif#ifndef CPU_INT_UNLOCK#   define CPU_INT_UNLOCK(data) \	(intUnlock (data))#endif/* externs */IMPORT STATUS 	excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);IMPORT STATUS 	excIntCrtConnect (VOIDFUNCPTR *, VOIDFUNCPTR);#if FALSE#if defined(INCLUDE_WINDVIEW) || defined(INCLUDE_INSTRUMENTATION)IMPORT	int	evtTimeStamp;  /* Windview 1.0 only */#endif  /* WINDVIEW||INSTRUMENTATION */#endif  /* FALSE *//* get the interrupt hook routines  prototypes*/IMPORT STATUS	(*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);IMPORT int	(*_func_intEnableRtn)  (int);IMPORT int	(*_func_intdisableRtn) (int);/* globals */INT_HANDLER_DESC * sysIntTbl [INTERRUPT_TABLESIZE]; /* system interrupt tbl *//* locals *//* forward declarations */LOCAL int	epicIntEnable (ULONG srcAddr);LOCAL int	epicIntDisable (ULONG srcAddr);LOCAL int	epicVecOptionsSet (ULONG srcAddr, UINT32 mask, UINT32 options);LOCAL UINT32	epicVecOptionsGet (ULONG srcAddr);LOCAL void	sysEpicIntHandlerExec (int vector);LOCAL void 	sysEpicIntHandler (void);#ifdef INCLUDE_EPIC_CRT_INTRLOCAL void 	sysEpicCrtIntHandler (void);LOCAL int	epicCrtIntSet (ULONG srcAddr);LOCAL int	epicCrtIntUnset (ULONG srcAddr);LOCAL int	epicCrtIntGet (ULONG srcAddr);#endif  /* INCLUDE_EPIC_CRT_INTR */LOCAL int       epicSrcAddrCheck (ULONG srcAddr);/********************************************************************************* sysEpicInit - initialize the epic controller** This routine resets the global Configuration Register, thus it:*  -  disables all interrupts*  -  sets epic registers to reset values** It then sets the EPIC operation mode to Mixed Mode (vs. Pass Through* mode). At this point only mixed mode is supported which means the EPIC* is not configured for the pass through mode.** Only direct interrupt sources is supported by the PIC.  Serial * stype interrupt is not available.** NOMANUAL* * RETURNS: N/A*/    void sysEpicInit    (    void    )    {    ULONG 	gcrVal;    int 	irq;    gcrVal = sysEpicRegRead (EPIC_GLOBAL_REG);    gcrVal |= (EPIC_GCR_RESET);        sysEpicRegWrite (EPIC_GLOBAL_REG, gcrVal);    /* wait for the reset sequence to be completed */        while (sysEpicRegRead (EPIC_GLOBAL_REG) & EPIC_GCR_RESET)        {        ; /* do nothing */        }    gcrVal = sysEpicRegRead (EPIC_GLOBAL_REG);    gcrVal |= (EPIC_GCR_MODE_MIXED);	/* configure for mixed mode */        sysEpicRegWrite (EPIC_GLOBAL_REG, gcrVal);    /* Clear all pending interrupt */    while (((USHORT) epicIntAck()) != (USHORT) 0xffff)        {        /* do nothing */	}    /* init all EIVPRs to sense = 1, polarity = defined, vec = 0, prio = 0 */    for (irq = 0; irq < EPIC_MAX_EXT_IRQS; irq++)        {        epicIntDisable (EPIC_EX_VEC_REG(irq));        epicIntSourceSet (EPIC_EX_VEC_REG(irq),                          EPIC_EX_DFT_POLAR, EPIC_EX_DFT_SENSE, 0x0, 0x0);        }	    /* init all IIVPRs to polarity = defined, vec = 0, prio = 0 */    for (irq = 0; irq < EPIC_MAX_IN_IRQS; irq++)        {        epicIntDisable (EPIC_IN_VEC_REG(irq));        epicIntSourceSet (EPIC_IN_VEC_REG(irq),                          EPIC_IN_DFT_POLAR, 0x0, 0x0, 0x0);        }    /* init all GTVPRs to vec = 0, prio = 0 */    for (irq = 0; irq < EPIC_MAX_GT_IRQS; irq++)        {        epicIntDisable (EPIC_GT_VEC_REG(irq));        epicIntSourceSet (EPIC_GT_VEC_REG(irq),                          0x0, 0x0, 0x0, 0x0);        }    /* init all MIVPRs to vec = 0, prio = 0 */    for (irq = 0; irq < EPIC_MAX_MSG_IRQS; irq++)        {        epicIntDisable (EPIC_MSG_VEC_REG(irq));        epicIntSourceSet (EPIC_MSG_VEC_REG(irq),                          0x0, 0x0, 0x0, 0x0);        }    /* disable IPIs */    for (irq = 0; irq < EPIC_MAX_IPI_IRQS; irq++)        {        epicIntDisable (EPIC_IPI_VEC_REG(irq));        epicIntSourceSet (EPIC_IPI_VEC_REG(irq),                          0x0, 0x0, 0x0, 0x0);        }    epicCurTaskPrioSet (EPIC_PRIORITY_MAX); /* set it to highest priority */    }/********************************************************************************* sysEpicIntrInit - initialize the interrupt table** This function initializes the interrupt mechanism of the board.** RETURNS: OK, always.*/STATUS  sysEpicIntrInit (void)    {    int vector;    int rc;    /* initialize the interrupt table */    for (vector = 0; vector < INTERRUPT_TABLESIZE; vector++)        {	sysIntTbl [vector] = NULL;        }    /*     * connect the interrupt demultiplexer to the PowerPC external      * interrupt exception vector.     * i. e.  put the address of this interrupt handler in     * the PowerPC's only external interrupt exception vector     * which is  _EXC_OFF_INTR = 0x500     * Also connect critical input pin handler _EXC_OFF_CRTL = 0x100.     */    rc = excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysEpicIntHandler);#ifdef INCLUDE_EPIC_CRT_INTR    rc = excIntCrtConnect ((VOIDFUNCPTR *) _EXC_OFF_CRTL, sysEpicCrtIntHandler);#endif  /* INCLUDE_EPIC_CRT_INTR */    /*       * set up the BSP specific interrupt routines     * Attach the local routines to the VxWorks system calls     *     */    _func_intConnectRtn  =  sysEpicIntConnect;    _func_intEnableRtn   =  sysEpicIntEnable;    _func_intDisableRtn  =  sysEpicIntDisable;    epicCurTaskPrioSet (EPIC_PRIORITY_MIN); /* set it to lowest priority */        return (rc);    }/********************************************************************************* sysEpicIntEnable - enable a EPIC interrupt level** This routine enables a specified EPIC interrupt level.** NOMANUAL** RETURNS: OK, ERROR, or EPIC_INV_INTER_SOURCE.** NOTE: To allow compatibility, sysEpicIntEnable() can be used only for*       external and internal interrupts, and not GT, MSG, IPI.  It*       assumes there are more internal IRQs than external.  It also*       gives priority to external over internal given the same IRQ*       is valid for both external and internal.*/int sysEpicIntEnable    (    int vector    )    {    if ((vector < 0)  || (vector >= EPIC_MAX_ALL_IRQS))        return (ERROR);    /* enable interrupt on EPIC */    return epicIntEnable ( epicGetVecRegAdrs (vector) );    }/********************************************************************************* sysEpicIntDisable - disable a EPIC interrupt level** This routine disables a specified EPIC interrupt level.** NOMANUAL** RETURNS: OK, ERROR, or EPIC_INV_INTER_SOURCE.** NOTE: To allow compatibility, sysEpicIntDisable() can be used only for*       external and internal interrupts, and not GT, MSG, IPI.  It*       assumes there are more internal IRQs than external.  It also*       gives priority to external over internal given the same IRQ*       is valid for both external and internal.*/int  sysEpicIntDisable    (    int vector    )    {    if ((vector < 0) || (vector >= EPIC_MAX_ALL_IRQS))        return (ERROR);    /* disable interrupt on EPIC */    return epicIntDisable ( epicGetVecRegAdrs (vector) );    }/*******************************************************************************

⌨️ 快捷键说明

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