📄 mot82xxpci.c
字号:
* pciDeviceIntEnable - enable PCI interrupt for a given vector** This function enables the specific PCI interrupt related to the vector. ** RETURNS: OK or ERROR** ERRNO*/ STATUS pciDeviceIntEnable ( int vector ) { if (vector>=MAX_NUM_VECTORS) return (ERROR);#ifdef PCI_DEBUG logMsg("PCI Interrupt Enable %x\n",(int)vector,0,0,0,0,0);#endif /* PCI_DEBUG */ (void)m8260IntDisable(INUM_IRQ2); *(UINT32*)PCI_INTERRUPT_MASK_REG &=pciSlotIntEnableMask[vector]; (void)m8260IntEnable(INUM_IRQ2); return (OK); }/************************************************************************** * pciDeviceIntDisable - disable PCI interrupt for a given vector ** This function disables the specific PCI interrupt related to the vector. ** RETURNS: OK or ERROR** ERRNO*/STATUS pciDeviceIntDisable ( int vector ) { if (vector>=MAX_NUM_VECTORS) return (ERROR);#ifdef PCI_DEBUG logMsg("PCI Interrupt disable %x\n",(int)vector,0,0,0,0,0);#endif /* PCI_DEBUG */ (void)m8260IntDisable(INUM_IRQ2); *(UINT32*)PCI_INTERRUPT_MASK_REG |= pciSlotIntDisableMask[vector]; (void)m8260IntEnable(INUM_IRQ2); return (OK); }/************************************************************************** * pciDeviceIntHandler - PCI interrupt dispatch routine** This is called from the 8260 interrupt controller and is linked to IRQ6. * It finds which vectors have the corresponding interrupt set and * calls the relevant interrupt handler. The priority based on * slot and the slot<->vector are the effectively the same. The vector* is based upon device number which for ADS board is :* 0x16 -> slot 0 -> vector 0* 0x17 -> slot 1 -> vector 1* 0x18 -> slot 2 -> vector 2* For a custom board this may need to be modified.** RETURNS: N/A** ERRNO */LOCAL void pciDeviceIntHandler(void) { volatile int vector; volatile UINT32 status; status = *(VUINT32*)PCI_INTERRUPT_STATUS_REG; for (vector=0;vector<MAX_NUM_VECTORS;vector++) { /* Check Interrupt routine available and interrupt vector is set */ if ( (pciDeviceIntTable[vector].vec!=NULL) &&(pciDeviceIntTable[vector].arg!=0) && ((status & pciSlotIntDisableMask[vector])!=0)) { /* Call Interrupt Handler for specific vector */ pciDeviceIntTable[vector].vec(pciDeviceIntTable[vector].arg); /* Clear the specific interrupt */ *(VUINT32*)PCI_INTERRUPT_STATUS_REG &=pciSlotIntClearMask[vector]; } }#ifdef PCI_DEBUG logMsg("PCI interrupt received %x\n",(int)status,0,0,0,0,0);#endif /* PCI_DEBUG */ }/***************************************************************** * pciErrorHandlingInit - initialize PCI error interrupts** This function sets up the error control and mask registers. * It also connects the INUM_PCI to the interrupt handler and * activates the interrupt.** RETURNS: N/A** ERRNO*/void pciErrorHandlingInit(void) { volatile int loop; /* Initialise ECR to include particular PCI Errors */ /* Not required as most useful errors already enabled on reset*/ /* Connect handler to INUM_PCI*/ (void)_func_intConnectRtn( (VOIDFUNCPTR *)INUM_PCI, (VOIDFUNCPTR)pciMultiInterruptHandler, 0); for (loop=0;loop<sizeof(pciErrorCount)/sizeof(UINT32);loop++) { *(UINT32*)((UINT32*)&pciErrorCount + loop) = 0; } /* Clear the Error Status register */ sysPciOutLong((UINT32*)PCI_ESR(INTERNAL_MEM_MAP_ADDR),0x0); /* Activate/Initialise Mask/Control Registers */ sysPciOutLong((UINT32*)PCI_EMR(INTERNAL_MEM_MAP_ADDR),0xeff); sysPciOutLong((UINT32*)PCI_ECR(INTERNAL_MEM_MAP_ADDR),0x0); /* Allow the interrupt handler to process the interrupt */ pciIntEnabled|=PCI_ERROR_INT_ENABLED; /* Enable Interrupts */ m8260IntEnable(INUM_PCI); #ifdef PCI_DEBUG logMsg("PCI Error Handling Initialised.\n",0,0,0,0,0,0); #endif /* PCI_DEBUG */ }#ifdef INCLUDE_PCI_DMA/***************************************************************** * pciDmaInit - initialize DMA interrupts** This function sets up the error control and mask registers. * It also connects the INUM_PCI to the interrupt handler and * activates the interrupt.** RETURNS: N/A** ERRNO*/void pciDmaInit(void) { (void)_func_intConnectRtn( (VOIDFUNCPTR *)INUM_PCI, (VOIDFUNCPTR)pciMultiInterruptHandler, 0); pciIntEnabled|=DMA_INT_ENABLED; /* Enable Interrupts */ m8260IntEnable(INUM_PCI); }/***************************************************************** * pciDmaTransfer - configure a DMA transfer** This function sets up a direct DMA transfer using the PCI * Bridge. ** RETURNS: OK or ERROR** ERRNO*/STATUS pciDmaTransfer ( char* source, char* destination, UINT32 bytes, UINT32 dmaRegNum ) { volatile UINT32 statusReg; if (((UINT32)source & PCI_DMA_SOURCE_MASK)!=(UINT32)source) { printf("Source address not 32 byte aligned\n"); return(ERROR); } if (((UINT32)destination & PCI_DMA_DEST_MASK)!=(UINT32)destination) { printf("Destination address not 32 byte aligned\n"); return(ERROR); } if(((UINT32)bytes & PCI_DMA_MAX_BYTE_COUNT_MASK)!=bytes) { printf("Byte Count too large\n"); return(ERROR); } taskLock(); statusReg = PCI_IN_LONG ((int)PCI_DMASR(immrVal,dmaRegNum)); while ((statusReg & DMASR_CB)==DMASR_CB) statusReg = PCI_IN_LONG ((int)PCI_DMASR(immrVal,dmaRegNum)); sysPciOutLong ( PCI_DMASAR (immrVal,dmaRegNum),( (UINT32)source & PCI_DMA_SOURCE_MASK ) ); sysPciOutLong ( PCI_DMADAR (immrVal,dmaRegNum),( (UINT32)destination & PCI_DMA_DEST_MASK ) ); sysPciOutLong ( PCI_DMABCR (immrVal,dmaRegNum),( bytes & PCI_DMA_MAX_BYTE_COUNT_MASK ) ); statusReg = PCI_IN_LONG ((int)PCI_DMAMR(immrVal,dmaRegNum)); sysPciOutLong ( PCI_DMAMR (immrVal,dmaRegNum),((statusReg & DMAMR_CS_MASK)|DMAMR_CTM_DIRECT)); sysPciOutLong ( PCI_DMAMR (immrVal,dmaRegNum),statusReg | DMAMR_EOTIE | DMAMR_CS | DMAMR_CTM_DIRECT); taskUnlock(); return(OK); }/***************************************************************************** * pciDmaHandler - DMA interrupt handler** This function is called from the pciMultiInterrupt handler and handles * the interrupts for the each DMA channel ** RETURNS: N/A** ERRNO*/LOCAL void pciDmaHandler(void) { volatile UINT32 loop; for (loop=0;loop<NO_OF_DMA_CHANNELS;loop++) { /* Check DMA channel status register */ if ( ( PCI_IN_LONG( (int)PCI_DMASR(immrVal,loop) ) & 0x83) !=0 ) /* Call DMA Handler */ {# ifdef PCI_DMA_DEBUG logMsg("PCI DMA %x\n",loop,0,0,0,0,0);# endif /* PCI_DMA_DEBUG */ if (_func_pciDmaUserHandler[loop]!=NULL) _func_pciDmaUserHandler[loop](); sysPciOutLong(PCI_DMASR(immrVal,loop),0x00000083); } } }#endif /* INCLUDE_PCI_DMA *//***************************************************************************** * pciMultiInterruptHandler - m8260IntrCtl interrupt dispatch** This function is called from the m8260IntrCtl and it calls the specific * interrupt handler for interrupt. ** RETURNS: N/A** ERRNO*/LOCAL void pciMultiInterruptHandler(void) { /* Check PCI Error/DMA/Message FIFO interrupt */ /* If to be handled go to handler, otherwise clear interrupt */ if ( (PCI_ESR_INT_SET != 0) && ( (pciIntEnabled | PCI_ERROR_INT_ENABLED ) != 0) ) /* Call PCI Error Handler */ pciErrorHandler();#ifdef INCLUDE_PCI_DMA if ( ( pciIntEnabled | DMA_INT_ENABLED ) != 0 ) pciDmaHandler();#endif /* INCLUDE_PCI_DMA */ /* TBD PCI MESSAGE HANDLING */ /* if ((MESSAGE_SR_INT_SET!=0) && (pciIntEnabled|MESSAGE_INT_ENABLED!=0)) */ /* Call Message FIFO Handler */ /* pciMessageHandler();*/ }/***************************************************************************** * pciErrorHandler - handle PCI error interrupts** This function is called from pciMultiInterrupt handler and handles the * interrupt for PCI Errors ** RETURNS: N/A** ERRNO*/LOCAL void pciErrorHandler(void) { volatile int esrRegVal; /* Check which Errors are set */ esrRegVal = PCI_IN_LONG( (int)PCI_ESR(INTERNAL_MEM_MAP_ADDR) ); if ( (esrRegVal & PCIERR_MSK_NMI)!=0) {# ifdef PCI_MULTI_DEBUG logMsg("PCI Error NMI\n",0,0,0,0,0,0);# endif /* PCI_MULTI_DEBUG */ pciErrorCount.nmi++; } if ( (esrRegVal & PCIERR_MSK_IRA) != 0) {# ifdef PCI_MULTI_DEBUG logMsg("PCI Error IRA\n",0,0,0,0,0,0);# endif /* PCI_MULTI_DEBUG */ pciErrorCount.ira++; } if ( (esrRegVal & PCIERR_MSK_I2O_IPQO) != 0) {# ifdef PCI_MULTI_DEBUG logMsg("PCI Error I2O_IPQO\n",0,0,0,0,0,0);# endif /* PCI_MULTI_DEBUG */ pciErrorCount.i2o_ipqo++; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -