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

📄 ixm1200intrctl.c

📁 vxworks的BSP开发配置文件
💻 C
字号:
/* ixm1200IntrCtl.c - Intel IXM1200 interrupt controller driver *//* Copyright 1984-1997, Wind River Systems, Inc.; Copyright 1999 Intel Corp. *//*modification history--------------------01d,30aug01,scm  adjust to reflect ixm1200...01c,07Mar00,jdg  Added support for B0 revision ixp120001b,13aug99,jdg  changed name from vbsa2100 to ixp1200eb01a,28apr99,jdg  created from 01a of sa1100IntrCtl.c.*//*This module implements the Intel IXM1200 interrupt controller driver.The IXM1200 does not have a true interrupt controller, so the interruptprocessing must be in non-preemptive mode. Effectively there is only one interrupt level, but there are 32 interrupt vectors. These are managedby the intArchLib.The number of interrupts supported by the software is IXM1200_INT_NUM_VECTORS.The actual registers referenced are:  IXM1200_IRQ  IXM1200_IRQSTATUSWe assume that config.h or <bsp>.h has defined the above addresses.This driver assumes that the chip is memory-mapped and does directmemory accesses to the registers which are assumed to be 32 bits wide.If a different access method is needed, the BSP can redefine the macrosIXM1200_INT_REG_READ(addr,result) and IXM1200_INT_REG_WRITE(addr,data).The BSP will initialize this driver in sysHwInit2(), after initializingthe main interrupt library, usually intLibInit().  The initializationroutine, ixm1200IntDevInit() will setup the interrupt service.All of the functions in this library are global.  This allows them tobe used by the BSP if it is necessary to create wrapper routines or toincorporate several drivers together as one.*/#include "vxWorks.h"#include "config.h"#include "intLib.h"/* hardware access methods */#ifndef IXM1200_REG_READ#define IXM1200_REG_READ(a,val) ((val) = *(volatile UINT32 *)(a))#endif	/*IXM1200_REG_READ*/#ifndef IXM1200_REG_WRITE#define IXM1200_REG_WRITE(a,val) (*(volatile UINT32 *)(a) = (val))#endif /*IXM1200_REG_WRITE*//* driver constants *//* lsbTab[256] returns the index of the lsb which is 1 */LOCAL constunsigned char lsbTab[0x100] =    {    255,0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    5,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    6,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    5,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    7,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    5,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    6,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    5,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0,    4,  0,  1,  0,  2,  0,  1,  0,    3,  0,  1,  0,  2,  0,  1,  0    };    /* Local data *//* forward declarations */STATUS	ixm1200IntLvlVecChk (int*, int*);STATUS  ixm1200IntLvlVecAck (int, int);int	ixm1200IntLvlChg (int);STATUS	ixm1200IntLvlEnable (int);STATUS	ixm1200IntLvlDisable (int);/********************************************************************************* ixm1200IntDevInit - initialize the interrupt controller** This routine will initialize the interrupt controller device,* disabling all interrupt sources.  It will also connect the device* driver specific routines into the architecture level hooks.  If the BSP* needs to create a wrapper routine around any of the arhitecture level* routines, it should install the pointer to the wrapper routine after* calling this routine.  * * RETURNS: N/A*/void ixm1200IntDevInit (void)    {    /* install the driver routines in the architecture hooks */    sysIntLvlVecChkRtn	= ixm1200IntLvlVecChk;    sysIntLvlVecAckRtn	= ixm1200IntLvlVecAck;    sysIntLvlChgRtn	= ixm1200IntLvlChg;    sysIntLvlEnableRtn	= ixm1200IntLvlEnable;    sysIntLvlDisableRtn	= ixm1200IntLvlDisable;    }/********************************************************************************* ixm1200IntLvlVecChk - check for and return any pending interrupts** This routine interrogates the hardware to determine the highest priority* interrupt pending.  It returns the vector associated with that interrupt, and* also the interrupt priority level prior to the interrupt (not the* level of the interrupt).  Since there is no notion of interrupt level,* this is a constant.** The return value ERROR indicates that no pending interrupt was found and* that the level and vector values were not returned.** RETURNS: OK or ERROR if no interrupt is pending.*/STATUS  ixm1200IntLvlVecChk    (    int* pLevel,  /* ptr to receive old interrupt level */    int* pVector  /* ptr to receive current interrupt vector */    )    {    UINT32 isr, isr2;    int vector;    /* Read IXM1200_IRQ register */    IXM1200_REG_READ(IXM1200_IRQ, isr);    /* If no interrupt is pending, return ERROR */    if (isr == 0)	return ERROR;    if (isr & (1 << 2))        {        /* if PCI bit is set */        IXM1200_REG_READ(IXM1200_IRQSTATUS, isr2);        isr2 |= (isr & ~(1<<2)) << 6;        if ((vector = (isr2 & 0xFF)))             {            vector = lsbTab[vector];            }        else if ((vector = ((isr2 >> 8) & 0xFF)))            {            vector = lsbTab[vector] + 8;            }        else if ((vector = ((isr2 >> 16) & 0xFF)))            {            vector = lsbTab[vector] + 16;            }        else if ((vector = ((isr2 >> 24) & 0xFF)))            {            vector = lsbTab[vector] + 24;            }        else            {            return ERROR;            }        }    else        {        /* PCI bit is not set */        vector = lsbTab[isr>>2] + 8;        }    /* fix up RTC/UART for Rev A chips */    if (sysCpuRev < 1) {        if (vector == INT_VEC_RTC)            vector = INT_VEC_UART;    }    *pVector = vector;    *pLevel = 0;    return OK;    }/********************************************************************************* ixm1200IntLvlVecAck - acknowledge the current interrupt** This is a no-op** Since ixm1200IntLvlVecChk doesn't change the state of the system,* there is nothing here that needs to be undone.** It is assumed that the interrupt service routine has cleared the * interrupt source itself.** RETURNS: OK or ERROR if a hardware fault is detected.* ARGSUSED*/STATUS  ixm1200IntLvlVecAck    (    int level,	/* old interrupt level to be restored */    int vector	/* current interrupt vector, if needed */    )    {    return OK;    }/********************************************************************************* ixm1200IntLvlChg - change the interrupt level value** This is a no-op since we effectively have one level.** RETURNS: Previous interrupt level.*/int  ixm1200IntLvlChg    (    int level	/* new interrupt level */    )    {    return 0;    }/********************************************************************************* ixm1200IntLvlEnable - enable a single interrupt level** Enable a single interrupt level. This only works on the PCI interrupts.** RETURNS: OK or ERROR if the specified level cannot be enabled.*/STATUS  ixm1200IntLvlEnable    (    int level  /* level to be enabled */    )    {    if (level < 0 ||	level > IXM1200_INT_NUM_VECTORS)	return ERROR;    level = 1 << level;    if ((level & IXM1200_INT_CTRL_MASK) == 0)        return ERROR;    IXM1200_PCI_REG_WRITE(IXM1200_IRQENABLE_SET, level);    return OK;    }/********************************************************************************* ixm1200IntLvlDisable - disable a single interrupt level** Disable a single interrupt level. This only works on the PCI interrupts** RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.*/STATUS  ixm1200IntLvlDisable    (    int level  /* level to be disabled */    )    {    if (level < 0 ||	level > IXM1200_INT_NUM_VECTORS)	return ERROR;    level = 1 << level;    if ((level & IXM1200_INT_CTRL_MASK) == 0)        return ERROR;    IXM1200_PCI_REG_WRITE(IXM1200_IRQENABLECLEAR, level);    return OK;    }

⌨️ 快捷键说明

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