📄 i80312intrctl.c
字号:
/* i80312Intr.c - interrupt controller driver for Yavapai(80312) *//* Copyright 2000-2001, Wind River Systems, Inc. *//*modification history--------------------01e,21jun02,scm add lock/unlock around reg access...01d,09nov01,scm remove IF_bitTest...01c,23apr01,scm remove warnings...01b,13apr01,scm debug pci...01a,02aug00,sut created*/#include "vxWorks.h"#include "config.h"#include "iq80310.h"#include "i80312IntrCtl.h"/* Imports *//* From architecture level header file */IMPORT FUNCPTR sysIntLvlVecChkRtn;IMPORT FUNCPTR sysIntLvlVecAckRtn;IMPORT FUNCPTR sysIntLvlChgRtn;IMPORT FUNCPTR sysIntLvlEnableRtn;IMPORT FUNCPTR sysIntLvlDisableRtn;IMPORT int sysICUReadINTSRC (void);/* defines */#ifdef INCLUDE_I80312_DEBUG_PORT#undef I80312INT_DEBUG#undef I80312INT_XINT3_DEBUG#endif#define I80312INT_HEART_BEAT/* Starting Vector Number */#define I80312INT_VEC_BASE (0x0)#define I80312INT_MASK_UPDATE (-1)/* Locals */UINT32 i80312XInt3LvlDisabled;/* Software Interrupt Enable Register for XINT0-2 */UINT32 i80312XInt0to2LvlEnable[3] = {0,0,0};UINT8 i80312XInt0to2LvlCurrent = 0;/* Current interrupt level setting (i80312IntLvlChg). *//* * In a normal system, it should be set to enable all the interrupt * levels. Without IMR and ISR for XINT6-7, it doesn't make sence to set the * level to highest*/LOCAL UINT32 i80312IntLvlCurrent = I80312INT_LVL_MAX_XINT3; /* 127 */#ifdef I80312INT_HEART_BEAT/* Watch Interrupts */LOCAL UINT32 IntMsb = L7SEG_Dot;LOCAL UINT32 IntLsb = L7SEG_ALL_OFF;LOCAL UINT32 IntCount = 0;#endif/* forward declarations */STATUS i80312IntLvlVecChk (int*, int*);STATUS i80312IntLvlVecAck (int, int);int i80312IntLvlChg (int);STATUS i80312IntLvlEnable (int);STATUS i80312IntLvlDisable (int);#ifdef I80312INT_DEBUGextern void serialStringOut (char *pMsg);extern void serialHexOut (UINT32 value);#endif/********************************************************************************* i80312IntDevInit - 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.**/void i80312IntDevInit (void) {#ifdef I80312INT_DEBUG serialStringOut ("\r\ni80312IntDevInit\r\n");#endif /* install the driver routines in the architecture hooks */ sysIntLvlVecChkRtn = i80312IntLvlVecChk; sysIntLvlVecAckRtn = i80312IntLvlVecAck; sysIntLvlChgRtn = i80312IntLvlChg; sysIntLvlEnableRtn = i80312IntLvlEnable; sysIntLvlDisableRtn = i80312IntLvlDisable; /* Disable (Mask) all XINT3 interrupts */ i80312XInt3LvlDisabled = 0xffffffff; /* Enable all levels */ i80312IntLvlChg (I80312INT_LVL_ALL_ENABLED); /* Clear out all the pending interrupts */ }/********************************************************************************* i80312IntLvlVecChk - 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). The current interrupt priority level is then* raised to the level of the current interrupt so that only higher priority* interrupts will be accepted until this interrupt is finished.** 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 i80312IntLvlVecChk ( int* pLevel, /* ptr to receive old interrupt level */ int* pVector /* ptr to receive current interrupt vector */ ) { register int newLevel; int localLevel; UINT32 isr; int key;#ifdef I80312INT_DEBUG UINT32 secondary_check;#endif static int preLevel = I80312INT_VEC_UART1; isr = sysICUReadINTSRC(); /* Check for pending interrupts */ if ((isr & I80200_INTSRC_MASK) == 0) { i80312XInt0to2LvlCurrent = 0; return ERROR; }/* * Since current version of yavapai doesn't support the Interrupt Status * Register, we have to go and check each and every source XINT6, XINT7 and * PAL interrupt status register. And there is no Interrupts Status Registers * for XINT0, XINT1, XINT2 and XINT3. So, we check XINT6, XINT7 and PAL-ISR, * is none of them has generated the interrupt we ASSUME that one of XINT0-3 * has generated the interrupts. In that case we return XINT0's level. So the * interrupt handler for the XINT0 should call ALL XINT0, XINT1, XINT2 and * XINT3 handlers */ /* First check the XINT7 sources */#if defined(I80312INT_DEBUG) && defined(I80312INT_XINT3_DEBUG) serialStringOut ("i80312IntLvlVecChk\r\n");#endif /* Mask all the interrupts */ key = intLock (); isr = *(volatile UINT32*)I80312_X7ISR; intUnlock (key); if (isr) { newLevel = I80312INT_LVL_BASE_XINT7;#ifdef I80312INT_DEBUG serialStringOut ("\r\nInterrupt XINT7 0x"); serialHexOut (isr); serialStringOut ("\r\n"); serialStringOut (">>> CPSR : 0x"); serialStringOut ("\r\n");#endif } else { /* check XINT6 sources */ /* Mask all the interrupts */ key = intLock (); isr = *(volatile UINT32*)I80312_X6ISR; intUnlock (key); if (isr) { newLevel = I80312INT_LVL_BASE_XINT6;#ifdef I80312INT_DEBUG serialStringOut ("\r\nInterrupt XINT6 0x"); serialHexOut (isr); serialStringOut ("\r\n"); serialStringOut (">>> CPSR : 0x"); serialStringOut ("\r\n");#endif } else { /* check PAL sources */ /* Mask all the interrupts */ key = intLock (); isr = I80310_PAL_XINT3_INT_ISR_RD(); intUnlock (key); if (isr) { newLevel = I80312INT_LVL_BASE_XINT3;#ifdef I80312INT_XINT3_DEBUG serialStringOut ("\r\nInterrupt XINT3 0x"); serialHexOut (isr); serialStringOut ("\r\n"); serialStringOut (">>> CPSR : 0x"); serialStringOut ("\r\n"); if (isr & IQ80310_PAL_INT_MASK_TIMER) serialStringOut ("INT: Timer\r\n"); if (isr & IQ80310_PAL_INT_MASK_ETHERNET) serialStringOut ("INT: Eithernet\r\n"); if (isr & IQ80310_PAL_INT_MASK_UART1) serialStringOut ("INT: UART1\r\n"); if (isr & IQ80310_PAL_INT_MASK_UART2) serialStringOut ("INT: UART2\r\n"); if (isr & IQ80310_PAL_INT_MASK_SPCID) serialStringOut ("*** INT: SPCID ***\r\n");#endif#ifdef I80312INT_DEBUG if (isr & IQ80310_PAL_INT_MASK_SPCID) { serialStringOut ("\r\n*** INT: SPCID *** 0x"); serialHexOut (isr); serialStringOut ("\r\n"); }#endif#ifdef I80312INT_HEART_BEAT IQ80310_SEVEN_SEG_WRITE_MSB(IntMsb); IQ80310_SEVEN_SEG_WRITE_LSB(IntLsb); if (IntMsb == L7SEG_ALL_OFF) { IntCount++; if(IntCount > 10) { IntMsb = L7SEG_Dot; IntLsb = L7SEG_ALL_OFF; IntCount = 0; } } else { IntCount++; if(IntCount > 10) { IntMsb = L7SEG_ALL_OFF; IntLsb = L7SEG_Dot; IntCount = 0; } }#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -