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

📄 mot82xxpci.c

📁 该源码为mpc8248处理器的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
    pciIntEnabled|=DMA_INT_ENABLED;    /* Enable Interrupts */    m8260IntEnable(INUM_PCI);    }/**************************************************************** *    * pciDmaTransfer - This function sets up a direct DMA transfer using  *                  the PCI Bridge.  * * STATUS pciDmaTransfer  *    (  *     char* source, *     char* destination, *     UINT32 bytes, *     UINT32 dmaRegNum  *    ) * * RETURNS : OK or ERROR * */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 - This function is called from the pciMultiInterrupt handler *                 and handles the interrupts for the each DMA channel  * * RETURNS : NONE */LOCAL void pciDmaHandler()    {    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 - This function is called from the m8260IntrCtl *                            and it calls the specific interrupt handler for *                            interrupt.  * * RETURNS : NONE */LOCAL void pciMultiInterruptHandler()    {    /* 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 - This function is called from pciMultiInterrupt handler *                   and handles the interrupt for PCI Errors   * * RETURNS : NONE */LOCAL void pciErrorHandler()    {    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++;        }    if ( (esrRegVal & PCIERR_MSK_I2O_OFQO ) != 0)       {#      ifdef PCI_MULTI_DEBUG       logMsg("PCI Error I2O_OFQO\n",0,0,0,0,0,0);#      endif /* PCI_MULTI_DEBUG */       pciErrorCount.i2o_ofqo++;       }    if ( ( esrRegVal & PCIERR_MSK_PERR_WR ) != 0)        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error Parity Error on write\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.perr_wr++;        }    if ( ( esrRegVal & PCIERR_MSK_PERR_RD )!=0)        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error Parity Error on read\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.perr_rd++;        }    if ( ( esrRegVal & PCIERR_MSK_SERR ) != 0)        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error SERR\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.serr++;        }    if ( ( esrRegVal & PCIERR_MSK_TAR_ABT ) != 0 )        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.tar_abt++;        }    if (( esrRegVal&PCIERR_MSK_NO_RSP)!=0)        { #       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error no response\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.no_rsp++;        }    if ( ( esrRegVal & PCIERR_MSK_DATA_PAR_RD ) != 0 )        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error data parity error on read\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.datapar_rd++;        }    if ( ( esrRegVal & PCIERR_MSK_DATA_PAR_WR ) != 0 )        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error data parity error on write\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.datapar_wr++;        }    if ( ( esrRegVal & PCIERR_MSK_ADDR_PAR ) != 0)        {#       ifdef PCI_MULTI_DEBUG        logMsg("PCI Error address parity error\n",0,0,0,0,0,0);#       endif /* PCI_MULTI_DEBUG */        pciErrorCount.addrpar++;        }       sysPciOutLong ( (UINT32*)PCI_ESR(INTERNAL_MEM_MAP_ADDR), 0xfff );    esrRegVal = PCI_IN_LONG ( (int)PCI_ESR( INTERNAL_MEM_MAP_ADDR ) );  }/**************************************************************************** *    * pciMessageHandler - This function is called from the pciMultiInterrupt  *                     handler and handles the interrupts for the messages. *                     It's not implemented at the momemt     * * RETURNS : NONE */void pciMessageHandler(){  /* Clear reg for now TBD */ }#ifdef INCLUDE_SHOW_ROUTINES/**************************************************************************** *    * pciErrorShow - This function can be called by the user and displays the  *                number and type of errors detected by the PCI bridge. * * RETURNS : NONE */void pciErrorShow ()    {    printf("PCI Error Statistics\n");    printf("--------------------\n");    printf("Number of NMI Errors %d\n",pciErrorCount.nmi);    printf("Number of IRA Errors %d\n",pciErrorCount.ira);    printf("Number of I2O_IPQO Errors %d\n",pciErrorCount.i2o_ipqo);    printf("Number of I2O_OFQO Errors %d\n",pciErrorCount.i2o_ofqo);    printf("Number of Parity Write Errors %d\n",pciErrorCount.perr_wr);    printf("Number of Parity Read  Errors %d\n",pciErrorCount.perr_rd);    printf("Number of SERR Errors %d\n",pciErrorCount.serr);    printf("Number of Target Abort Errors %d\n",pciErrorCount.tar_abt);    printf("Number of No Response Errors %d\n",pciErrorCount.no_rsp);    printf("Number of Data Parity Read Errors %d\n",pciErrorCount.datapar_rd);    printf("Number of Data Parity Write Errors %d\n",pciErrorCount.datapar_wr);    printf("Number of Address Parity Errors %d\n",pciErrorCount.addrpar);    }#endif /* INCLUDE_SHOW_ROUTINES */#ifdef PCI_BRIDGE_READ_ERRATA_WORKAROUND/************************************************************************** * * pciBridgeIdmaInit - This is called to initialize IDMA2 for the PCI  *                     errata fix. *                     It Initialises the IDMA. It can be called one time *                     only. For any IDMA transfer used in the code  *                     after this initialization only the source ptr *                     has to be changed. The dest ptr in this case  *                     is conveniently positioned in the DPRAM and not *                     in the external memory in order to reduce the *                     access latency */void pciBridgeIdmaInit()    {    char *pramBuf = (char *)m82xxDpramAlignedMalloc(0x100,0x100);    char *dpramBuf = (char *)m82xxDpramAlignedMalloc(0x40,0x40);    char *bdBuf = (char *)m82xxDpramAlignedMalloc(0x40,0x40);    /*     * init bds     */    idmaBd = (BD_DMA*)bdBuf;    idmaBd->dstptr = (UINT32)dpramBuf; /* Destination for the idma is a one empty word location is DPRAM */    /*     * init idma     */    *(VUINT16*)IDMA2_BASE =  (UINT16)((UINT32)pramBuf & 0xffff);     pIdmaParam = (IDMA_PARAM *)pramBuf;    pIdmaParam->ibase =   (UINT16)((UINT32)bdBuf & 0xffff);    pIdmaParam->ibdptr =  (UINT16)((UINT32)bdBuf & 0xffff);    pIdmaParam->dcm   = DCM_DUAL_ADDR | DCM_TRANS_BUF_128 |                         DCM_MEM_MEM | DCM_DINC | DCM_SINC;    pIdmaParam->dpr_buf = (UINT16)((UINT32)dpramBuf & 0xffff);   /* DPR_BUF=64x2(DMA_WRAP)-32  */    pIdmaParam->ss_max =  0x0060;   /*  Steady state value from peripheral to memory 96 bytes */    pIdmaParam->sts =     0x0060;   /*Transfers from peripheral is 96 bytes*/    pIdmaParam->dts =     0x0060;   /*Transfer to memory is 96 bytes (60x) bursts*/    }/************************************************************** * * pciBridgeRegisterReadLong - Reads from PCI Bridge using IDMA  * * UINT32 pciBridgeRegisterReadLong(int src) *   * IMPUT : location to read * RETURN : 32 bit value at location   * */UINT32 pciBridgeRegisterReadLong(int src)     {    volatile int key;    UINT32 value;    if ((src >= CPU_PCI_MEM_ADRS) && (src < CPU_PCI_IO_ADRS))        {        key = intLock();  /* Need to make sure only one access at a time */        /* Setup buffer descriptor */         idmaBd->srcptr = (UINT32)src;         idmaBd->length = 4; /* Need to set to prevent alignment issues */        /* This needs to be set each time for the valid bit */         idmaBd->cstatus = (IDMABD_INT_ENABLE | IDMABD_WRAP | IDMABD_LAST |	   		      IDMABD_DBO_BIG_ENDIAN | IDMABD_SBO_BIG_ENDIAN |			      IDMABD_VALID | IDMABD_DST_DONE |			      IDMABD_SRC_LOCAL);	        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        /* IDMA2 PAGE/CODE IDMA command start_idma */        *((VUINT32*)CPCR_REG) = IDMA2_PAGE_SUBBLOCK|CPCR_FLG|CPCR_START_IDMA;        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        while (!((*(VUINT8*)IDSR2) & 0x1)); /* Wait for completion of IDMA */         value = sysLong(idmaBd->dstptr); /* Byte Swap  */        /*Clear the IDSR2 status bit so each access waits for actual completion*/         *((VUINT8*)IDSR2) = 0x1;          intUnlock(key);  /* Allow access to idma */        }    else        {         value = sysLong((int)src); /* Byte Swap  */        }    return (value);    }/************************************************************** * * pciBridgeRegisterReadWord - Reads from PCI Bridge using IDMA  * * UINT16 pciBridgeRegisterReadWord(int src) *   * IMPUT : location to read * RETURN : 16 bit value at location   * */UINT16 pciBridgeRegisterReadWord(int src)     {    volatile int key;    UINT16 value;    if (((UINT32)src >= CPU_PCI_MEM_ADRS) && ((UINT32)src < CPU_PCI_IO_ADRS))        {        key = intLock();  /* Need to make sure only one access at a time */        /* Setup buffer descriptor */         idmaBd->srcptr = (UINT32)src;         idmaBd->length = 2; /* Need to set to prevent alignment issues  */        /* This needs to be set each time for the valid bit */         idmaBd->cstatus = (IDMABD_INT_ENABLE | IDMABD_WRAP | IDMABD_LAST |	   		      IDMABD_DBO_BIG_ENDIAN | IDMABD_SBO_BIG_ENDIAN |			      IDMABD_VALID | IDMABD_DST_DONE |			      IDMABD_SRC_LOCAL);	        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        /* IDMA2 PAGE/CODE IDMA command start_idma */        *((VUINT32*)CPCR_REG) = IDMA2_PAGE_SUBBLOCK|CPCR_FLG|CPCR_START_IDMA;        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        while (!((*(VUINT8*)IDSR2) & 0x1));  /* Wait for completion of IDMA */         value = sysWord(idmaBd->dstptr); /* Byte Swap  */        /*Clear the IDSR2 status bit so each access waits for actual completion*/         *((VUINT8*)IDSR2) = 0x1;          intUnlock(key);  /* Allow access to idma */        }    else        {         value = sysWord((int)src); /* Byte Swap  */        }    return (value);}/************************************************************** * * pciBridgeRegisterReadByte - Reads from PCI Bridge using IDMA  * * UINT8 pciBridgeRegisterReadByte(int src) *   * IMPUT : location to read * RETURN : 8 bit value at location   * */UINT8 pciBridgeRegisterReadByte(int src)     {    volatile int key;    UINT8 value;    if ((src >= CPU_PCI_MEM_ADRS) && (src < CPU_PCI_IO_ADRS))        {        key = intLock();  /* Need to make sure only one access at a time */        /* Setup buffer descriptor */         idmaBd->srcptr = (UINT32)src;         idmaBd->length = 1; /* Need to set to prevent alignment issues */        /* This needs to be set each time for the valid bit */         idmaBd->cstatus = (IDMABD_INT_ENABLE | IDMABD_WRAP | IDMABD_LAST |	   		      IDMABD_DBO_BIG_ENDIAN | IDMABD_SBO_BIG_ENDIAN |			      IDMABD_VALID | IDMABD_DST_DONE |			      IDMABD_SRC_LOCAL);	        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        /* IDMA2 PAGE/CODE IDMA command start_idma */        *((VUINT32*)CPCR_REG) = IDMA2_PAGE_SUBBLOCK|CPCR_FLG|CPCR_START_IDMA;        while (*((VUINT32*)CPCR_REG) & CPCR_FLG); /* Wait til CPCR available */        while (!((*(VUINT8*)IDSR2) & 0x1)); /* Wait for completion of IDMA */         value = sysByte(idmaBd->dstptr);        /*Clear the IDSR2 status bit so each access waits for actual completion*/         *((VUINT8*)IDSR2) = 0x1;          intUnlock(key);  /* Allow access to idma */        }    else        {         value = sysByte((int)src); /* Byte Swap  */        }    return (value);    }#endif /* PCI_BRIDGE_READ_ERRATA_WORKAROUND */

⌨️ 快捷键说明

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