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

📄 hawkmpic.c

📁 VxWorks下 MV2400的BSP源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* hawkMpic.c - Hawk Interrupt Controller driver *//* Copyright 1984-2002 Wind River Systems, Inc. *//* Copyright 1996,1997,1998 Motorola, Inc., All Rights Reserved */#include "copyright_wrs.h"/*modification history--------------------01c,16apr02,dat  Removing warnings for T2.2 release01b,16jul99,rhv  Changing to new Windview support.01a,15dec98,mdp  Written (from version 01k of mv2304/ravenMpic.c*//*DESCRIPTIONThis module implements the Hawk 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 "hawkMpic.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 UCHAR 	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 Hawk** This function initializes the Multi-Processor Interrupt Controller (MPIC)* contained in the Hawk 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        {

⌨️ 快捷键说明

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