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

📄 ppc555intr.c

📁 操作系统vxworks平台下中断控制器设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
字号:
/* ppc555Intr.c - PowerPC 555 interrupt driver *//* Copyright 1984-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01b,12apr99,zl   lock interrupts before restoring mask01a,16mar99,zl   written based on ppc860Intr.c.*//*DESCRIPTIONThe PowerPC 555 CPU series is divided in several units: PowerPC core, SystemInterface Unit (SIU), and on-chip periferal units. The PowerPC core accepts only one external interrupt exception (vector 0x500). The SIU provides an interrupt controller which provides 32 levels but only 16 are used. The Interrupt controller is connected to the PowerPC core external interrupt. This library provides the routines to manage this interrupt controller.ppc555IntrInit() connects the default demultiplexer, ppc555IntrDemux, to the external interrupt vector and initializes a table containing a function pointerand an associated parameter for each interrupt source. ppc555IntrInit() is called by sysHwInit() from sysLib.c.The default demultimplexer, ppc555IntrDeMux() detects which peripheral or controller has raised an interrupt and calls the associated routine with its parameter. Note: at this time only one interrupt source can be connected to a given level.This gives only 16 different sources, of which 8 are external. To relieve thisrestriction, interrupt handlers sharing the same level should be stored in a linked list and should be called one by one. It would be the ISRs responsabilityto determine if it is really an interrupt condition. If not then simply return.INCLUDE FILES: drv/intrCtl/ppc555Intr.h, drv/multi/ppc555Siu.h*//* includes */#include "intLib.h"#include "iv.h"#include "drv/intrCtl/ppc555Intr.h"#include "drv/multi/ppc555Siu.h"#ifdef  INCLUDE_WINDVIEW#include "private/funcBindP.h"#include "private/eventP.h"#endif /* INCLUDE_WINDVIEW */IMPORT UINT32 vxImemBaseGet();/* local */LOCAL INTR_HANDLER	intrVecTable[NUM_VEC_MAX];	/*  Intr vector table *//* forward declarations */LOCAL void	ppc555IntrDemux (void);LOCAL STATUS	ppc555IntConnect (VOIDFUNCPTR *, VOIDFUNCPTR, int);LOCAL int	ppc555IntEnable (int);LOCAL int	ppc555IntDisable (int);/********************************************************************************* ppc555IntrInit - initialize the interrupt manager for the PowerPC 500 series** This routine connects the default demultiplexers, ppc555IntHandler() to * the external interrupt vector and associates all interrupt sources with * the default interrupt handler.  This routine is called by sysHwInit() * in sysLib.c.** RETURN : OK*/STATUS ppc555IntrInit     (    )    {    VOIDFUNCPTR defaultVec;     	/* default vector */    int		vector;    /* Get the default vector connected to the External Interrupt (0x500) */    defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_INTR);    /* Connect the interrupt demultiplexer to External Interrupt (0x500) */    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, ppc555IntrDemux);    /* Install the driver routines in the architecture hooks */    if (_func_intConnectRtn == NULL)        _func_intConnectRtn = ppc555IntConnect;    if (_func_intEnableRtn == NULL)        _func_intEnableRtn = ppc555IntEnable;    if (_func_intDisableRtn == NULL)        _func_intDisableRtn = ppc555IntDisable;    /* Set all vectors to default handler */    for (vector = 0; vector < NUM_VEC_MAX; vector++)	intConnect (INUM_TO_IVEC(vector), defaultVec, 0);    return (OK);    }/********************************************************************************* ppc555IntConnect - connect a routine to an interrupt ** This routine connects any C or assembly routine to one of the multiple * sources of interrupts.** The connected routine can be any normal C code, except that it must not * invoke certain operating system functions that may block or perform I/O* operations.** <vector> types are defined in h/drv/intrClt/ppc555Intr.h.** RETURNS: OK, or ERROR if <vector> is unknown.** SEE ALSO: ppc555Intr.h*/LOCAL STATUS ppc555IntConnect    (    VOIDFUNCPTR *	vector,		/* interrupt vector to attach to */    VOIDFUNCPTR		routine,	/* routine to be called */    int 		parameter	/* parameter to be passed to routine */    )    {    /* test the vector */    if (IVEC_TO_INUM(vector) >= NUM_VEC_MAX)	return (ERROR);    intrVecTable[IVEC_TO_INUM(vector)].vec = routine;    intrVecTable[IVEC_TO_INUM(vector)].arg = parameter;    return (OK);    }/********************************************************************************* ppc555IntHandler - SIU interrupt demultiplexer ** This routine must be bound to external interrupt exception (vector 0x500). * It is used to call the appropriate handler with its argument when an* interrupt occurs. ** NOTE: when this function is called the interrupts are still locked. It's* this function responsability to unlock the interrupt.** RETURNS: N/A*/void ppc555IntrDemux (void)    {    UINT8 	intVec;			/* interrupt vector */    UINT32	imemBase;		/* internal memory Base Address */    UINT32	intMask;		/* current interrupt mask */    imemBase = vxImemBaseGet();		/* Internal memory base address */    /* read the interrupt vector register */    intVec = (* SIVEC(imemBase)) >> 26;#ifdef  INCLUDE_WINDVIEW    WV_EVT_INT_ENT(intVec)#endif /* INCLUDE_WINDVIEW */    /* save the current interrupt mask */     intMask = * SIMASK(imemBase);    /* lock all levels inferior to the interrupt detected */    * SIMASK(imemBase) &= (0xffffffff << (32 - intVec));    /* unlock the interrupt */    intUnlock (_PPC_MSR_EE);    /* call the Interrupt Handler */    intrVecTable[intVec].vec (intrVecTable[intVec].arg);    /* lock interrupts */    intLock ();    /* restore the interrupt mask */    * SIMASK(imemBase) = intMask;    return;    }/********************************************************************************* ppc555IntEnable - enable one of the Level or IRQ interrupts into the SIU** This routine will unmask the bit in the SIMASK register corresponding to* the requested interrupt level.  The interrupt level must be in the range* of 0 - 31.* * RETURNS: 0, always.*/LOCAL int ppc555IntEnable    (    int intNum		/* interrupt level to enable (0 - 31) */    )    {    UINT32 imemBase;    imemBase = vxImemBaseGet();    if ((intNum >= 0) && (intNum < 32))	* SIMASK(imemBase) |= (1 << (31 - intNum));    return 0;    }/********************************************************************************* ppc555IntDisable - Disable one of the Level or IRQ interrupts into the SIU** This routine will mask the bit in the SIMASK register corresponding to* the requested interrupt level.  The interrupt level must be in the range* of 0 - 31.* * RETURNS: 0, always.*/LOCAL int ppc555IntDisable    (    int intNum          /* interrupt level to disable (0 - 31) */    )    {    UINT32 imemBase;        imemBase = vxImemBaseGet();    if ((intNum >= 0) && (intNum < 32))        * SIMASK(imemBase) &= ~(1 << (31 - intNum));    return 0;    }

⌨️ 快捷键说明

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