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

📄 ravenmpic.c

📁 WINDRIVER MCP750 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ravenMpic.c - Raven Interrupt Controller driver *//* Copyright 1984-1998 Wind River Systems, Inc. *//* Copyright 1996,1997,1998 Motorola, Inc., All Rights Reserved */#include "copyright_wrs.h"/*modification history--------------------01v,01nov01,mil  Cleaned up compiler warnings.01u,17nov98,srr  Correct phantom interrupt else if test and remove semicolon.01t,24aug98,cjtc windview 2.0 event logging is now single step and handled in                 the interrupt controller driver. Fixes a problem with out of                 sequence timestamps in the event log for this architechture.                 Method of initiating event logging is now via a macro                 (SPR 21868)01s,20aug98,scg  SPR 21961: fix sysIbcPhantomInt to correctly handle phantom                 interrupts on slave 8259.  Remove extra semicolons in		 sysIbcIntHandler()01q,21jul98,scb  #define name cleanup - removal of board name defines.01p,07jul98,scb  Initial support for MCPN750.01o,17apr98,pr   added windview 20 support01n,14apr98,ms_  merged Motorola mv2700 support01m,11apr98,scb  HW rework makes ISA IRQ's 14 & 15 edge (note level) sensitive.01l,22apr98,scb  added phantom IBC int handling for IRQ7 and IRQ1501k,13jan98,srr  updated copyright dates to 1998.01j,11dec97,srr  Updated comment in sysIbcInit to show support for VIA chip.01i,20jul97,srr  send end of interrupt acknowledge to master IBC first.01h,23oct97,dat, removed IACK loop from sysMpicIntHandler() (SPR 9389).            mas01g,20jul97,dat  implemented dave's second revision + some code cleanup01f,11jun97,dmw  MPIC handler cleanup. 01e,06may97,dat  added IBC updates from sl82565 controller.01d,30apr97,dat  added WindView instrumentation SPR 843401c,29apr97,dat  Fixed Motorola MR #62, moved MPIC_EOI01b,23apr97,mas  merged with sl82565IntrCtl.c (SPR 8170).01a,11nov96,rhk  created by Motorola.*//*DESCRIPTIONThis module implements the Raven Mpic and the Winbond W83C553 PCI-ISA Bridge(PIB) drivers.  (The W83C553 PIB was formerly known as the Motorola sl82565 ISABridge Controller (IBC).These merged drivers provide support for initializing their respective devicesand handling interrupts from them.*//* includes */#include "ravenMpic.h"#include "private/eventP.h"/* defines */#define	MPIC_EOI	sysPciWrite32(MPIC_ADDR(MPIC_CPU0_EOI_REG),0)#define IBC_INT_PENDING	0x80/* 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			sysIbcIntEnable (int);void			sysIbcIntDisable (int);void			sysIbcIntHandler (void);void			sysMpicIntHandler (void);IMPORT UINT		sysVectorIRQ0; 	/* vector for IRQ0 */INT_HANDLER_DESC * sysIntTbl [256];	/* system interrupt table */int tpr;/* forward declarations */LOCAL int       getMpicVecOffset (int);LOCAL STATUS	sysMpicIntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine,			       int parameter);LOCAL int	sysMpicIntEnable (int);LOCAL int	sysMpicIntDisable (int);LOCAL void	sysIbcMpicConnect (void);LOCAL BOOL 	sysIbcPhantomInt (UCHAR *intNum, int lvl7Int, int lvl15Int);LOCAL void	sysIbcEndOfInt (int);LOCAL void	sysIbcIntLevelSet (int);/* Mask values are the currently disabled sources */LOCAL UINT8	sysPicMask1 = 0xfb;	/* all levels disabled */LOCAL UINT8	sysPicMask2 = 0xff;/* Level values are the interrupt level masks */LOCAL UINT8	sysPicLevel1;LOCAL UINT8	sysPicLevel2;LOCAL UINT8	sysPicLevelCur;		/* current priority level, 0 to 16 *//* level values by real priority */LOCAL UCHAR sysPicPriMask1[17] = {0xFB,0xFA,0xF8,0xF8,0xF0,0xE0,0xC0,0x80,			     0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x0};LOCAL UCHAR sysPicPriMask2[17] = {0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,			     0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0};/* Hardware access methods */#ifndef IBC_BYTE_OUT#   define IBC_BYTE_OUT(reg,data) \	(sysOutByte (reg,data))#endif#ifndef IBC_BYTE_IN#   define IBC_BYTE_IN(reg,pData) \	(*pData = sysInByte(reg))#endif#ifndef CPU_INT_LOCK#   define CPU_INT_LOCK(x) \	(*x = intLock ())#endif#ifndef CPU_INT_UNLOCK#   define CPU_INT_UNLOCK(data) \	(intUnlock (data))#endif/********************************************************************************* sysMpicInit - initialize the MPIC in the Raven** This function initializes the Multi-Processor Interrupt Controller (MPIC)* contained in the Raven chip.** It first initializes the system vector table, connects the MPIC interrupt* handler to the PPC external interrupt and attaches the local MPIC routines* for interrupt connecting, enabling and disabling to the corresponding system* routine pointers.** It then initializes the MPIC registers, clears any pending MPIC interrupts,* enables interrupt handling by the MPIC and enables external ISA interrupts* (from the W83C553).** RETURNS: OK always*/STATUS sysMpicInit (void)    {    int			i;    UINT32		timerReg;    UINT32		ipiReg;    UINT32		destReg;    LOCAL_INT_DATA	init;    /* 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, sysMpicIntHandler);    /*     *  Set up the BSP specific routines     *  Attach the local routines to the vxWorks system calls     */    _func_intConnectRtn = sysMpicIntConnect;    _func_intEnableRtn = sysMpicIntEnable;    _func_intDisableRtn = sysMpicIntDisable;    /* Initialize the MPIC */    /* generate a PCI IACK to clear any pending interrupts */    sysPciRead32( MPIC_ADDR(MPIC_CPU0_IACK_REG), (UINT32 *) &init.temp );    /* inhibit the timer and IPI regs. and clear the counter regs. */    timerReg = MPIC_TIMER0_BASE_CT_REG;    ipiReg = MPIC_IPI0_VEC_PRI_REG;    for (i=0; i<4; i++)	{	sysPciWrite32( MPIC_ADDR(ipiReg), IPI_INHIBIT );	ipiReg += REG_OFFSET;	sysPciWrite32( MPIC_ADDR(timerReg), TIMER_INHIBIT );	timerReg += REG_OFFSET;	sysPciWrite32( MPIC_ADDR(timerReg), TIMER_INHIBIT );	timerReg += (REG_OFFSET * 3);	}    /* setup the external source vector/priority registers */    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC0_VEC_PRI_REG), INIT_EXT_SRC0 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC1_VEC_PRI_REG), INIT_EXT_SRC1 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC2_VEC_PRI_REG), INIT_EXT_SRC2 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC3_VEC_PRI_REG), INIT_EXT_SRC3 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC4_VEC_PRI_REG), INIT_EXT_SRC4 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC5_VEC_PRI_REG), INIT_EXT_SRC5 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC6_VEC_PRI_REG), INIT_EXT_SRC6 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC7_VEC_PRI_REG), INIT_EXT_SRC7 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC8_VEC_PRI_REG), INIT_EXT_SRC8 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC9_VEC_PRI_REG), INIT_EXT_SRC9 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC10_VEC_PRI_REG), INIT_EXT_SRC10 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC11_VEC_PRI_REG), INIT_EXT_SRC11 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC12_VEC_PRI_REG), INIT_EXT_SRC12 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC13_VEC_PRI_REG), INIT_EXT_SRC13 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC14_VEC_PRI_REG), INIT_EXT_SRC14 );    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC15_VEC_PRI_REG), INIT_EXT_SRC15 );    destReg = MPIC_EXT_SRC0_DEST_REG;    for (i=0; i<=15; i++)	{	sysPciWrite32( MPIC_ADDR(destReg), DESTINATION_CPU0 );	destReg += (REG_OFFSET*2);	}    /* setup the Ext source 0 reg (8259 input) for normal operation */    sysPciRead32( MPIC_ADDR(MPIC_EXT_SRC0_VEC_PRI_REG), &init.regVal );    init.regVal |= PIB_INT_VEC;    init.regVal &= (~INT_MASK_BIT);    sysPciWrite32( MPIC_ADDR(MPIC_EXT_SRC0_VEC_PRI_REG), init.regVal );    /* enable interrupts for this processor */    sysPciWrite32( MPIC_ADDR(MPIC_CPU0_CUR_TASK_PRI_REG), 1 );    /* setup the MPIC to process the 8259 interrupts ( mixed mode ) */    sysPciWrite32( MPIC_ADDR(MPIC_GLOBAL_CONFIG_REG), SET_MIXED_MODE );    return (OK);    }/******************************************************************************** sysMpicIntConnect - 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 sysMpicIntConnect    (     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;    LOCAL_INT_DATA     connect;    static BOOL	       firstTime = TRUE;    if (((int)vector < 0) || ((int)vector > 0xff))      /* Out of Range? */        return (ERROR);     if (firstTime)	{	/* connect the PIB to MPIC, before any other connections */	firstTime = FALSE;	sysIbcMpicConnect (); /* calls this rtn, recursively */	}    /* 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;        }    /*      * if the connect is for an MPIC interrupt,      * then store the vector into the appropriate MPIC vector register     */    connect.regAddr = getMpicVecOffset( (int)vector );    if ( connect.regAddr > 0 )        {        /* read the vector register */        sysPciRead32( MPIC_ADDR(connect.regAddr), &connect.regVal );        /* store the interrupt vector number */        connect.regVal |= (int)vector;        /* write the contents of the vector register back */        sysPciWrite32( MPIC_ADDR(connect.regAddr), connect.regVal );        }    return (OK);    } /********************************************************************************* sysMpicIntEnable - enable an Mpic interrupt level** This routine enables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysMpicIntEnable    (    int intLevel        /* interrupt level to enable */    )    {    LOCAL_INT_DATA	enable;    /*     * if the int. level is not for ISA or MPIC, then it is not supported.     * If not supported, just return.     */    if ((intLevel < 0) || (intLevel > ERR_INTERRUPT_BASE))        return (ERROR);    /* If ISA interrupt level,call the IBC driver enable routine, */    if ( intLevel < EXT_INTERRUPT_BASE )        sysIbcIntEnable( intLevel );    enable.regAddr = getMpicVecOffset( intLevel );    if ( enable.regAddr > 0 )        {        /* read the vector register */        sysPciRead32( MPIC_ADDR(enable.regAddr), &enable.regVal );        /* enable the interrupt */        enable.regVal &= (~INT_MASK_BIT);        /* write the contents of the vector register back */        sysPciWrite32( MPIC_ADDR(enable.regAddr), enable.regVal );        }    return (OK);    }/********************************************************************************* sysMpicIntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported*/ LOCAL int sysMpicIntDisable    (    int intLevel        /* interrupt level to disable */    )    {    LOCAL_INT_DATA      disable;     /*     * if the int. level is not for ISA or MPIC, then it is not supported.     * If not supported, just return.     */    if ((intLevel < 0) || (intLevel > ERR_INTERRUPT_BASE))        return (ERROR);    /* If ISA interrupt level, call the IBC driver disable routine, */    if ( intLevel < EXT_INTERRUPT_BASE )        sysIbcIntDisable( intLevel );     /* else, it is an MPIC interrupt level */    else        {        /* get the vector reg. offset value */        disable.regAddr = getMpicVecOffset( intLevel );         if ( disable.regAddr > 0 )            {            /* read the vector register */            sysPciRead32( MPIC_ADDR(disable.regAddr), &disable.regVal );            /* disable the interrupt */            disable.regVal |= INT_MASK_BIT;            /* write the contents of the vector register back */            sysPciWrite32( MPIC_ADDR(disable.regAddr), disable.regVal );            }        }    return (OK);    }/******************************************************************************** sysMpicIntHandler - handle an interrupt received at the Mpic* * This routine will process interrupts received from PCI or ISA devices as* these interrupts arrive via the MPIC.  This routine supports MPIC interrupt* nesting.** RETURNS: N/A*/void sysMpicIntHandler (void)    {    INT_HANDLER_DESC *  currHandler;    UINT32		vecNum;    int			dontCare;    /* get the vector from the MPIC IACK reg. */    sysPciRead32 (MPIC_ADDR (MPIC_CPU0_IACK_REG), &vecNum);    vecNum &= VECTOR_MASK;    /* Ignore spurious interrupts */    if (vecNum == 0xFF)        {        logMsg ("MPIC Spurious Interrupt!\n", 0,0,0,0,0,0);        return;        }     /*     * 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);#ifdef INCLUDE_WINDVIEW    WV_EVT_INT_ENT(vecNum)#endif    /* call the necessary interrupt handlers */    if ((currHandler = sysIntTbl [vecNum]) == NULL)        {        logMsg ("uninitialized MPIC 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 MPIC */    MPIC_EOI;    CPU_INT_LOCK (&dontCare);    return;

⌨️ 快捷键说明

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