📄 sysgt64260intrctl.c
字号:
} else if ( level >= 4 && level <= 7 ) { GT64260_REG_RD(DMA_CH4_7_INT_MASK, &temp); temp |= (0x3f<<((level-4)*8)) ; GT64260_REG_WR(DMA_CH4_7_INT_MASK, temp); } else return ERROR ; } else if ( type == TMR_INT_TYPE ) { /* level: 0..7 */ if ( level >= 0 && level <= 3 ) { GT64260_REG_RD(TMR0_3_INT_MASK, &temp); temp |= (0x1<<level) ; GT64260_REG_WR(TMR0_3_INT_MASK, temp); } else if ( level >= 4 && level <= 7 ) { GT64260_REG_RD(TMR4_7_INT_MASK, &temp); temp |= (0x1<<(level-4)) ; GT64260_REG_WR(TMR4_7_INT_MASK, temp); } else return ERROR ; } else if ( type == GPP_INT_TYPE ) { /* level: 0..31 */ if ( level >= 0 && level <= 31 ) { GT64260_REG_RD(GPP_INT_MASK, &temp); temp |= (0x1<<level) ; GT64260_REG_WR(GPP_INT_MASK, temp); } else return ERROR ; } else return ERROR ; return OK ; }/***************************************************************************** sysGt64260MuxedIntDisable - disable interrupt at local mux register.*** RETURNS: OK/ERROR.**/STATUS sysGt64260MuxedIntDisable ( 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); } else if ( level >= 4 && level <= 7 ) { GT64260_REG_RD(DMA_CH4_7_INT_MASK, &temp); temp &= ~(0x3f<<((level-4)*8)) ; GT64260_REG_WR(DMA_CH4_7_INT_MASK, temp); } else return ERROR ; } else if ( type == TMR_INT_TYPE ) { /* level: 0..7 */ if ( level >= 0 && level <= 3 ) { GT64260_REG_RD(TMR0_3_INT_MASK, &temp); temp &= ~(0x1<<level) ; GT64260_REG_WR(TMR0_3_INT_MASK, temp); } else if ( level >= 4 && level <= 7 ) { GT64260_REG_RD(TMR4_7_INT_MASK, &temp); temp &= ~(0x1<<(level-4)) ; GT64260_REG_WR(TMR4_7_INT_MASK, temp); } else return ERROR ; } else if ( type == GPP_INT_TYPE ) { /* level: 0..31 */ if ( level >= 0 && level <= 31 ) { GT64260_REG_RD(GPP_INT_MASK, &temp); temp &= ~(0x1<<level) ; GT64260_REG_WR(GPP_INT_MASK, temp); } else return ERROR ; } else return ERROR ; return OK ; }/***************************************************************************** sysGt64260IntEnable - enable an EPIC external interrupt level** This routine enables a specified EPIC interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysGt64260IntrInit(), sysGt64260IntConnect(), * sysGt64260IntDisable(), sysGt64260IntHandler() */LOCAL int sysGt64260IntEnable ( int intLevel /* interrupt level to enable */ ) { int i ; UINT32 temp ; /* * if the int. level is not a valid IRQ * If not supported, just return. */ if ( (intLevel < INT_LVL_LOW) || (intLevel > INT_LVL_HIGH) ) return(ERROR); if ( intPrioTbl[intLevel].priority == intLevel ) i=intLevel ; else { for ( i=0;i<intPrioTblSz;i++ ) { if ( intPrioTbl[i].priority == intLevel ) { i=intLevel ; break; } } } if ( i == intPrioTblSz ) return ERROR ; /* set bit in cpu mask register for non-special cases */ if ( intPrioTbl[i].causeMaskBitHi != 0 ) { GT64260_REG_RD(CPU_INT_MASK_H, &temp); temp |= intPrioTbl[i].causeMaskBitHi ; GT64260_REG_WR(CPU_INT_MASK_H, temp); } else if ( intPrioTbl[i].causeMaskBitLo != 0 ) { GT64260_REG_RD(CPU_INT_MASK_L, &temp); temp |= intPrioTbl[i].causeMaskBitLo ; GT64260_REG_WR(CPU_INT_MASK_L, temp); } return(OK); }/***************************************************************************** sysGt64260IntDisable - disable an Mpic interrupt level** This routine disables a specified Mpic interrupt level.** RETURNS: OK or ERROR if interrupt level not supported** SEE ALSO: sysGt64260IntrInit(), sysGt64260IntConnect(), * sysGt64260IntEnable(), sysGt64260IntHandler() */LOCAL int sysGt64260IntDisable ( int intLevel /* interrupt level to disable */ ) { int i ; UINT32 temp ; /* * if the int. level is not a valid IRQ * If not supported, just return. */ if ( (intLevel < INT_LVL_LOW) || (intLevel > INT_LVL_HIGH) ) return(ERROR); if ( intPrioTbl[intLevel].priority == intLevel ) i=intLevel ; else { for ( i=0;i<intPrioTblSz;i++ ) { if ( intPrioTbl[i].priority == intLevel ) { i=intLevel ; break; } } } if ( i == intPrioTblSz ) return ERROR ; /* clear bit in cpu mask register for non-special cases */ if ( intPrioTbl[i].causeMaskBitHi != 0 ) { GT64260_REG_RD(CPU_INT_MASK_H, &temp); temp &= ~intPrioTbl[i].causeMaskBitHi ; GT64260_REG_WR(CPU_INT_MASK_H, temp); } else if ( intPrioTbl[i].causeMaskBitLo != 0 ) { GT64260_REG_RD(CPU_INT_MASK_L, &temp); temp &= ~intPrioTbl[i].causeMaskBitLo ; GT64260_REG_WR(CPU_INT_MASK_L, temp); } return(OK); }/***************************************************************************** sysGt64260IntHandler - handle an interrupt received at the Mpic* * This routine will process interrupts received from the GT64260 interrupt * controller. Note that this interrupt controller does not queue or* prioritize interrupts; thus, any such design must be carried out by* software. For this bsp we have elected to implement a simple ISR handler* which handles only one interrupt source at a time and then exits. Since* any interrrupt that is not cleared by the handler remains int the * interrupt cause register, this handler will be called until all interrupt* causes have been cleared. This one and out design was chosen (instead of* looping through all bits in the cause register) so that the decrementer* (timer) interrupt is not blocked unnecessarily.** As an upgrade, the following design is more elegant: implement a message* queue from an interrupt handler (the message queue will preserve order)* and submit these interrupt messages to a handler running at task level* as the tNetTask does to process network interrupts. Since message queues* can be created with priority, "prioritized" interrupts can be simulated* as well.** RETURNS: N/A** SEE ALSO: sysGt64260IntrInit(), sysGt64260IntConnect(), * sysGt64260IntEnable(), sysGt64260IntDisable() */int unkIntCnt = 0 ;void sysGt64260IntHandler ( void ) { INT_HANDLER_DESC * currHandler ; UINT32 vecNum ; int i,j ; UINT32 cause ; /* ints are disabled upon entry... */ GT64260_REG_RD(CPU_SEL_CAUSE, &cause); /* Can we decode interrupt and send work to task level using message queue so we don't lose interrupts? That int task would have to be started up fairly early... The problem here is that we don't have an interrupt controller that stores and prioritizes int events. A message queue would preserve order. We could use the priority feature of message queues to introduce priority. The other alternative is to decode quickly here. Also, we can't allow interrupts to interrupt this routine.... */ vecNum = -1 ; if ( !(cause&0x40000000) ) { /* process LO interrupts */ for ( i=0;i<28;i++ ) { if ( cause & intPrioTbl[i].causeMaskBitLo ) { vecNum = intPrioTbl[i].vector ; /* clear the interrupt cause */ GT64260_REG_WR(intPrioTbl[i].causeClearAdrs, ~intPrioTbl[i].causeClearBit) ; break; } } } else if ( cause&0x40000000 ) { /* process HI interrupts */ for ( j=28;j<(28+13+1);j++ ) { if ( cause & intPrioTbl[j].causeMaskBitHi ) { vecNum = intPrioTbl[j].vector ; /* clear the interrupt cause */ GT64260_REG_WR(intPrioTbl[j].causeClearAdrs, ~intPrioTbl[j].causeClearBit) ; break; } } }#ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT (vecNum);#endif /* INCLUDE_WINDVIEW */ if ( vecNum != -1 ) { /* call the necessary interrupt handlers */ if ( (currHandler = sysIntTbl [vecNum]) == NULL ) { logMsg ("uninitialized GT64260 interrupt %d\r\n", vecNum, 0,0,0,0,0); unkIntCnt++ ; } else { /* Call EACH respective chained interrupt handler */ while ( currHandler != NULL ) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } } /* while */ return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -