📄 sysgt64260intrctl.c
字号:
/* gt64260IntrCtl.c - Galileo Interrupt Controller driver *//* Copyright 1984-2002 Wind River Systems, Inc. *//*modification history--------------------01c,20apr02,gtf Modified for GT64260/GT64260A interrupt controller.01b,17dec01,g_h Add Wind View instrumentation.01a,12may01,g_h written*//*DESCRIPTIONThis module implements the Galileo interrupt controller driver.INCLUDES: gt64260IntrlCtl.h*//* includes */#include "vxWorks.h"#include "config.h"#include "sysGt64260IntrCtl.h"#include "excLib.h"#include "stdlib.h"#include "string.h"#include "intLib.h"#include "logLib.h"#include "sysLed.h"#ifdef INCLUDE_WINDVIEW#include "private/eventP.h"#endif /* INCLUDE_WINDVIEW *//* defines *//* globals */IMPORT STATUS (*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);IMPORT int (*_func_intEnableRtn) (int);IMPORT int (*_func_intDisableRtn) (int);IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);void sysGt64260IntHandler (void);INT_HANDLER_DESC * sysIntTbl [64]; /* system interrupt table */int tpr;int spurIntCnt;/* forward declarations */LOCAL STATUS sysGt64260IntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine, int parameter);LOCAL int sysGt64260IntEnable (int);LOCAL int sysGt64260IntDisable (int);#ifndef CPU_INT_LOCK#define CPU_INT_LOCK(x) (*x = intLock ())#endif#ifndef CPU_INT_UNLOCK#define CPU_INT_UNLOCK(data) (intUnlock (data))#endiftypedef struct { int priority ; int vector ; UINT32 causeMaskBitHi ; /* cause / mask bit */ UINT32 causeMaskBitLo ; /* cause / mask bit */ UINT32 causeClearAdrs ; /* register to clear */ UINT32 causeClearBit ; /* bit to set to clear int */ } INT_PRIO_ELEMENT ; /* This table should be ordered by priority; but it is not necessary; the driver will do so during initialization. INT_PRI_xxxx *must* be unique for each INT_PRIO_ELEMENT entry. Note that for an entry like INT_VEC_GPP7_0 up to 8 interrupt service routines can be hooked to this single vector. */INT_PRIO_ELEMENT intPrioTbl[] ={ /* low mask word bits */ { INT_PRI_DEV, INT_VEC_DEV, 0, INT_BIT_DEV,0,0}, { INT_PRI_DMA, INT_VEC_DMA, 0, INT_BIT_DMA,0,0}, { INT_PRI_CPU, INT_VEC_CPU, 0, INT_BIT_CPU,0,0}, { INT_PRI_IDMA0_1, INT_VEC_IDMA0_1, 0, INT_BIT_IDMA0_1, DMA_CH0_3_INT_CAUSE,0}, { INT_PRI_IDMA2_3, INT_VEC_IDMA2_3, 0, INT_BIT_IDMA2_3, DMA_CH0_3_INT_CAUSE,0}, { INT_PRI_IDMA4_5, INT_VEC_IDMA4_5, 0, INT_BIT_IDMA4_5, DMA_CH4_7_INT_CAUSE,0}, { INT_PRI_IDMA6_7, INT_VEC_IDMA6_7, 0, INT_BIT_IDMA6_7, DMA_CH4_7_INT_CAUSE,0}, /* See errata for timers, we have effectively 4 timers here for the GT64260. */ /* You have the option of cascading 0/1, 2/3, 4/5 and 6/7 to create 64-bit timers */ { INT_PRI_TMR0_1, INT_VEC_TMR0_1, 0, INT_BIT_TMR0_1, TMR0_3_INT_CAUSE,0x0000000f}, { INT_PRI_TMR2_3, INT_VEC_TMR2_3, 0, INT_BIT_TMR2_3, TMR0_3_INT_CAUSE,0x0000000f}, { INT_PRI_TMR4_5, INT_VEC_TMR4_5, 0, INT_BIT_TMR4_5, TMR4_7_INT_CAUSE,0x0000000f}, { INT_PRI_TMR6_7, INT_VEC_TMR6_7, 0, INT_BIT_TMR6_7, TMR4_7_INT_CAUSE,0x0000000f}, { INT_PRI_PCI0_0, INT_VEC_PCI0_0, 0, INT_BIT_PCI0_0,0,0}, { INT_PRI_PCI0_1, INT_VEC_PCI0_1, 0, INT_BIT_PCI0_1,0,0}, { INT_PRI_PCI0_2, INT_VEC_PCI0_2, 0, INT_BIT_PCI0_2,0,0}, { INT_PRI_PCI0_3, INT_VEC_PCI0_3, 0, INT_BIT_PCI0_3,0,0}, { INT_PRI_PCI1_0, INT_VEC_PCI1_0, 0, INT_BIT_PCI1_0,0,0}, { INT_PRI_ECC, INT_VEC_ECC, 0, INT_BIT_ECC,0,0}, { INT_PRI_PCI1_1, INT_VEC_PCI1_1, 0, INT_BIT_PCI1_1,0,0}, { INT_PRI_PCI1_2, INT_VEC_PCI1_2, 0, INT_BIT_PCI1_2,0,0}, { INT_PRI_PCI1_3, INT_VEC_PCI1_3, 0, INT_BIT_PCI1_3,0,0}, { INT_PRI_PCI0_OUTL, INT_VEC_PCI0_OUTL, 0, INT_BIT_PCI0_OUTL,0,0}, { INT_PRI_PCI0_OUTH, INT_VEC_PCI0_OUTH, 0, INT_BIT_PCI0_OUTH,0,0}, { INT_PRI_PCI1_OUTL, INT_VEC_PCI1_OUTL, 0, INT_BIT_PCI1_OUTL,0,0}, { INT_PRI_PCI1_OUTH, INT_VEC_PCI1_OUTH, 0, INT_BIT_PCI1_OUTH,0,0}, { INT_PRI_PCI0_INL, INT_VEC_PCI0_INL, 0, INT_BIT_PCI0_INL,0,0}, { INT_PRI_PCI0_INH, INT_VEC_PCI0_INH, 0, INT_BIT_PCI0_INH,0,0}, { INT_PRI_PCI1_INL, INT_VEC_PCI1_INL, 0, INT_BIT_PCI1_INL,0,0}, { INT_PRI_PCI1_INH, INT_VEC_PCI1_INH, 0, INT_BIT_PCI1_INH,0,0}, /* high mask word bits */ /* Note: ethernet interrupts in the ICR are cleared by the ISR for each device */ { INT_PRI_ETH0, INT_VEC_ETH0, INT_BIT_ETH0, 0,ETH0_ICR, 0x00000000}, { INT_PRI_ETH1, INT_VEC_ETH1, INT_BIT_ETH1, 0,ETH1_ICR, 0x00000000}, { INT_PRI_ETH2, INT_VEC_ETH2, INT_BIT_ETH2, 0,ETH2_ICR, 0x00000000}, { INT_PRI_SDMA, INT_VEC_SDMA, INT_BIT_SDMA, 0,0,0}, { INT_PRI_I2C, INT_VEC_I2C, INT_BIT_I2C, 0,0,0}, { INT_PRI_BRG, INT_VEC_BRG, INT_BIT_BRG, 0,0,0}, { INT_PRI_MPSC0, INT_VEC_MPSC0, INT_BIT_MPSC0, 0,0,0}, { INT_PRI_MPSC1, INT_VEC_MPSC1, INT_BIT_MPSC1, 0,0,0}, { INT_PRI_COMM, INT_VEC_COMM, INT_BIT_COMM, 0,0,0}, /* NOTE: In the GPP, there are 8 potential interrupting sources per vector */ /* These ISRs are chained at each vector. Each ISR needs to check for the */ /* specific interrupting condition. */ { INT_PRI_GPP7_0, INT_VEC_GPP7_0, INT_BIT_GPP7_0, 0, GPP_INT_CAUSE, 0x000000ff}, { INT_PRI_GPP15_8, INT_VEC_GPP15_8, INT_BIT_GPP15_8, 0, GPP_INT_CAUSE, 0x0000ff00}, { INT_PRI_GPP23_16, INT_VEC_GPP23_16, INT_BIT_GPP23_16, 0, GPP_INT_CAUSE, 0x00ff0000}, { INT_PRI_GPP31_24, INT_VEC_GPP31_24, INT_BIT_GPP31_24, 0, GPP_INT_CAUSE, 0xff000000},} ;int intPrioTblSz = NELEMENTS(intPrioTbl);/***************************************************************************** sysGt64260IntrInit - initialize the Galileo interrupt controller** This function initializes the Interrupt Controller which is part of the * GT64260.** It first initializes the system vector table, connects the EPIC interrupt* handler to the PPC external interrupt and attaches the local EPIC routines* for interrupt connecting, enabling and disabling to the corresponding system* routine pointers.** It then initializes the EPIC register and clears any pending EPIC interrupts.** RETURNS: OK always** SEE ALSO: sysGt64260IntConnect(), sysGt64260IntEnable(), * sysGt64260IntDisable(), sysGt64260IntHandler() */STATUS sysGt64260IntrInit(void) { int i,j ; UINT32 temp ; INT_PRIO_ELEMENT tIntPrioTbl[INT_PRI_HIGH+1] ; /* Initialize the interrupt table */ for ( i = 0; i < 64; i++ ) { sysIntTbl[i] = NULL; } /* Sort the intPrioTbl by priority and check */ memset(tIntPrioTbl,0xff,(intPrioTblSz*sizeof(INT_PRIO_ELEMENT))); for ( i=0 ; i < intPrioTblSz ; i++ ) { for ( j=0; ((intPrioTbl[j].priority != i) && (j < intPrioTblSz)); j++ ) ; if ( j == intPrioTblSz ) return ERROR ; /* no entries at this priority - this is an error */ tIntPrioTbl[i] = intPrioTbl[j] ; } memcpy(intPrioTbl, tIntPrioTbl, intPrioTblSz); /* Connect the interrupt demultiplexer to the PowerPC external interrupt */ excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, sysGt64260IntHandler); /* * Set up the BSP specific routines * Attach the local routines to the vxWorks system calls */ _func_intConnectRtn = sysGt64260IntConnect; _func_intEnableRtn = sysGt64260IntEnable; _func_intDisableRtn = sysGt64260IntDisable; /* Mask all interrupts; at powerup these are set to 0 but are not guaranteed upon software reset. */ GT64260_REG_WR(CPU_INT_MASK_L, 0) ; GT64260_REG_WR(CPU_INT_MASK_H, 0) ; GT64260_REG_WR(PCI0_INT_MASK_L, 0) ; GT64260_REG_WR(PCI0_INT_MASK_H, 0) ; GT64260_REG_WR(PCI1_INT_MASK_L, 0) ; GT64260_REG_WR(PCI1_INT_MASK_H, 0) ; GT64260_REG_WR(CPU_INT0_MASK, 0) ; GT64260_REG_WR(CPU_INT1_MASK, 0) ; GT64260_REG_WR(CPU_INT2_MASK, 0) ; GT64260_REG_WR(CPU_INT3_MASK, 0) ; GT64260_REG_WR(GPP_INT_MASK, 0) ; GT64260_REG_WR(CPU_ERR_MASK, 0) ; GT64260_REG_WR(DEVICE_INT_MASK, 0) ; GT64260_REG_WR(DMA_CH0_3_INT_MASK, 0) ; GT64260_REG_WR(DMA_CH4_7_INT_MASK, 0) ; GT64260_REG_WR(TMR0_3_INT_MASK, 0) ; GT64260_REG_WR(TMR4_7_INT_MASK, 0) ; GT64260_REG_WR(CU_INT_MASK, 0); GT64260_REG_WR(BRG_INT_MASK, 0) ; GT64260_REG_WR(MPSC0_INT_MASK, 0) ; GT64260_REG_WR(MPSC1_INT_MASK, 0) ; GT64260_REG_WR(SDMA_INT_MASK, 0) ; GT64260_REG_WR(PCI0_SERR_ERR_MASK, 0) ; GT64260_REG_WR(PCI1_SERR_ERR_MASK, 0) ; GT64260_REG_WR(PCI0_ERR_MASK, 0) ; GT64260_REG_WR(PCI1_ERR_MASK, 0) ; GT64260_REG_WR(ETH0_IMR, 0) ; GT64260_REG_WR(ETH1_IMR, 0) ; GT64260_REG_WR(ETH2_IMR, 0) ; /* Clear all interrupts */ GT64260_REG_WR(DEVICE_INT_CAUSE, 0) ; GT64260_REG_WR(PCI0_INT_CAUSE, 0) ; GT64260_REG_WR(PCI1_INT_CAUSE, 0) ; GT64260_REG_WR(GPP_INT_CAUSE, 0) ; GT64260_REG_WR(MU_IN_INT_CAUSE_PCI1, 0) ; GT64260_REG_WR(MU_IN_INT_CAUSE_PCI0, 0) ; GT64260_REG_WR(MU_OUT_INT_CAUSE_PCI1, 0) ; GT64260_REG_WR(MU_OUT_INT_CAUSE_PCI0, 0) ; GT64260_REG_WR(DMA_CH0_3_INT_CAUSE, 0) ; GT64260_REG_WR(DMA_CH4_7_INT_CAUSE, 0) ; GT64260_REG_WR(TMR0_3_INT_CAUSE, 0) ; GT64260_REG_WR(TMR4_7_INT_CAUSE, 0) ; GT64260_REG_WR(CU_INT_CAUSE, 0) ; GT64260_REG_WR(BRG_INT_CAUSE, 0) ; GT64260_REG_WR(MPSC0_INT_CAUSE, 0) ; GT64260_REG_WR(MPSC1_INT_CAUSE, 0) ; GT64260_REG_WR(ETH0_ICR, 0) ; GT64260_REG_WR(ETH0_ICR, 0) ; GT64260_REG_WR(ETH0_ICR, 0) ; /* This is a special case: allow all GPP interrupts at the CPU mask; they will be enabled/disabled at the GPP mask register */ GT64260_REG_RD(CPU_INT_MASK_H, &temp); temp |= (INT_BIT_GPP7_0 | INT_BIT_GPP15_8 | INT_BIT_GPP23_16 | INT_BIT_GPP31_24) ; GT64260_REG_WR(CPU_INT_MASK_H, temp); /* This is a special case: allow all timer and dma interrupts at the CPU mask; they will be enabled/disabled at the respective local mask registers */ GT64260_REG_RD(CPU_INT_MASK_L, &temp); temp |= (INT_BIT_TMR0_1 | INT_BIT_TMR2_3 | INT_BIT_TMR4_5 | INT_BIT_TMR6_7) ; temp |= (INT_BIT_IDMA0_1 | INT_BIT_IDMA2_3 | INT_BIT_IDMA4_5 | INT_BIT_IDMA6_7) ; GT64260_REG_WR(CPU_INT_MASK_L, temp); return OK; }/***************************************************************************** sysGt64260IntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK/ERROR.** SEE ALSO: sysGt64260IntrInit(), sysGt64260IntEnable(), * sysGt64260IntDisable(), sysGt64260IntHandler() */LOCAL STATUS sysGt64260IntConnect ( 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; if ( ((int)vector < INT_LVL_LOW) || ((int)vector > INT_LVL_HIGH) ) /* Out of Range? */ return(ERROR); /* 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; } return(OK); }/***************************************************************************** sysGt64260MuxedIntEnable - enable muxed interrupt at local mask register.*** RETURNS: OK/ERROR.**/STATUS sysGt64260MuxedIntEnable ( int type, int level ) { UINT32 temp ; /* Handle special case int masks here - timers, dma and gpp */ if ( type == IDMA_INT_TYPE ) { /* level: 0..7 */ if ( level >= 0 && level <= 3 ) { GT64260_REG_RD(DMA_CH0_3_INT_MASK, &temp); temp |= (0x3f<<(level*8)) ; GT64260_REG_WR(DMA_CH0_3_INT_MASK, temp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -