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

📄 ixqmgrqaccess.c

📁 Uboot源码,非常通用的bootloader.适用于各种平台的Linux系统引导.
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* underflow is available for lower queues only */    if (qId < IX_QMGR_MIN_QUEUPP_QID)    { /* the counter of queue entries is decremented. In happy     * day scenario there are many entries in the queue  * and the counter does not reach zero.  */     if (infoPtr->qReadCount-- == 0) {       /* There is maybe no entry in the queue      * qReadCount is now negative, but will be corrected before      * the function returns.         */     UINT32 qPtrs; /* queue internal pointers */     /* when a queue is empty, the hw guarantees to return        * a null value. If the value is not null, the queue is      * not empty.        */     if (entry == 0)     {       /* get the queue status */      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);           /* check the underflow status */        if (status & infoPtr->qUflowStatBitMask)        {           /* the queue is empty           *  clear the underflow status bit if it was set             */          IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,                    status & ~infoPtr->qUflowStatBitMask);         *entryPtr = 0;          infoPtr->qReadCount = 0;            return IX_QMGR_Q_UNDERFLOW;     }       }       /* store the result */      *entryPtr = entry;      /* No underflow occured : someone is filling the queue       * or the queue contains null entries.       * The current counter needs to be       * updated from the current number of entries in the queue       */     /* get snapshot of queue pointers */        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);       /* Mod subtraction of pointers to get number of words in Q. */      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;          if (qPtrs == 0)     {       /* no entry in the queue */     infoPtr->qReadCount = 0;        }       else        {       /* convert the number of words inside the queue      * to a number of entries        */     infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);        }       return IX_SUCCESS;  }    }    *entryPtr = entry;    return IX_SUCCESS;}PUBLIC IX_STATUSixQMgrQBurstRead (IxQMgrQId qId,          UINT32 numEntries,          UINT32 *entries){    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];    UINT32 nullCheckEntry;    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)    {    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;    /* the code is optimized to take care of data dependencies:  * Durig a read, there are a few cycles needed to get the    * read complete. During these cycles, it is poossible to    * do some CPU, e.g. increment pointers and decrement    * counters.     */ /* fetch a queue entry */   nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); /* iterate the specified number of queue entries */     while (--numEntries)    {       /* check the result of the previous read */     if (nullCheckEntry == 0)        {       /* if we read a NULL entry, stop. We have underflowed */        break;      }       else        {       /* write the entry */       *entries = nullCheckEntry;      /* fetch next entry */      nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);      /* increment the write address */       entries++;      }   }   /* write the pre-fetched entry */   *entries = nullCheckEntry;    }    else    {    IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;  /* read the specified number of queue entries */    nullCheckEntry = 0; while (numEntries--)    {       int i;      for (i = 0; i < entrySizeInWords; i++)      {       *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);       nullCheckEntry |= *entries++;       }       /* if we read a NULL entry, stop. We have underflowed */        if (nullCheckEntry == 0)        {       break;      }       nullCheckEntry = 0; }    }    /* reset the current read count : next access to the read function      * will force a underflow status check      */    infoPtr->qWriteCount = 0;    /* Check if underflow occurred on the read */    if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)    {  /* get the queue status */  UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);   if (status & infoPtr->qUflowStatBitMask)    {       /* clear the underflow status bit if it was set */      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,                status & ~infoPtr->qUflowStatBitMask);     return IX_QMGR_Q_UNDERFLOW; }    }    return IX_SUCCESS;}PUBLIC IX_STATUSixQMgrQWrite (IxQMgrQId qId,         UINT32 *entry){    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];    UINT32 entrySize;    /* write the entry */    IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);    entrySize = infoPtr->qEntrySizeInWords;    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)    {       /* process the remaining part of the entry */   volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;    while (--entrySize) {       ++entry;        IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);    }   entrySize = infoPtr->qEntrySizeInWords;    }    /* overflow is available for lower queues only */    if (qId < IX_QMGR_MIN_QUEUPP_QID)    {     UINT32 qSize = infoPtr->qSizeInEntries; /* increment the current number of entries in the queue  * and check for overflow    */ if (infoPtr->qWriteCount++ == qSize)    {       /* the queue may have overflow */       UINT32 qPtrs; /* queue internal pointers */         /* get the queue status */      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);       /* read the status twice because the status may          * not be immediately ready after the write operation        */     if ((status & infoPtr->qOflowStatBitMask) ||        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))         & infoPtr->qOflowStatBitMask))     {       /* the queue is full, clear the overflow status      *  bit if it was set        */     IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,                    status & ~infoPtr->qOflowStatBitMask);     infoPtr->qWriteCount = infoPtr->qSizeInEntries;     return IX_QMGR_Q_OVERFLOW;      }       /* No overflow occured : someone is draining the queue       * and the current counter needs to be       * updated from the current number of entries in the queue       */     /* get q pointer snapshot */        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);       /* Mod subtraction of pointers to get number of words in Q. */      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;      if (qPtrs == 0)     {       /* the queue may be full at the time of the          * snapshot. Next access will check          * the overflow status again.        */     infoPtr->qWriteCount = qSize;       }       else        {       /* convert the number of words to a number of entries */        if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)     {           infoPtr->qWriteCount = qPtrs & (qSize - 1);     }       else        {           infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);       }       }   }    }    return IX_SUCCESS;}PUBLIC IX_STATUSixQMgrQBurstWrite (IxQMgrQId qId,          unsigned numEntries,        UINT32 *entries){    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];    UINT32 status;    /* update the current write count */    infoPtr->qWriteCount += numEntries;    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)    {    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;    while (numEntries--)    {       IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);        entries++;  }    }    else    { IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;  int i;  /* write each queue entry */    while (numEntries--)    {       /* write the queueEntrySize number of words for each entry */       for (i = 0; i < entrySizeInWords; i++)      {       IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);     entries++;      }   }    }    /* check if the write count overflows */    if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)    {  /* reset the current write count */ infoPtr->qWriteCount = infoPtr->qSizeInEntries;    }    /* Check if overflow occurred on the write operation */    if (qId < IX_QMGR_MIN_QUEUPP_QID)    {   /* get the queue status */  status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);  /* read the status twice because the status may      * not be ready at the time of the write     */ if ((status & infoPtr->qOflowStatBitMask) ||        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))         & infoPtr->qOflowStatBitMask)) {       /* clear the underflow status bit if it was set */      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,                status & ~infoPtr->qOflowStatBitMask);     return IX_QMGR_Q_OVERFLOW;  }    }    return IX_SUCCESS;}PUBLIC IX_STATUSixQMgrQStatusGet (IxQMgrQId qId,          IxQMgrQStatus *qStatus){    /* read the status of a queue in the range 0-31 */    if (qId < IX_QMGR_MIN_QUEUPP_QID)    {  extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];   extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];    extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];   volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];   volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;  UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];    UINT32 lowStatBitsMask   = ixQMgrAqmIfQueLowStatBitsMask;   UINT32 underflowBitMask  = infoPtr->qUflowStatBitMask;  UINT32 overflowBitMask   = infoPtr->qOflowStatBitMask;  /* read the status register for this queue */   *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr); /* mask out the status bits relevant only to this queue */  *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;   /* Check if the queue has overflowed */ if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)  {       /* clear the overflow status bit if it was set */       IX_OSAL_WRITE_LONG(qUOStatRegAddr,                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &               ~overflowBitMask));       *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;   }   /* Check if the queue has underflowed */        if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask) {       /* clear the underflow status bit if it was set */      IX_OSAL_WRITE_LONG(qUOStatRegAddr,                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &               ~underflowBitMask));      *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;   }    }    else /* read status of a queue in the range 32-63 */    { extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;    extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;    extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];  extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];  volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;    volatile UINT32 *qFullStatRegAddr      = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;    int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;   UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];    UINT32 qFullStatBitMask      = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];    /* Reset the status bits */ *qStatus = 0;   /* Check if the queue is nearly empty */    if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask) {       *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;   }   /* Check if the queue is full */    if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)   {       *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;    }    }    return IX_SUCCESS;}#endif /* def NO_INLINE_APIS */

⌨️ 快捷键说明

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