long K2DspLrtCommunicator::data_recv(Fifo* f){ if(f->ntoken){ Cppi_Desc *mono_pkt; int queueId = QUEUE_DATA_BASE+f->id; if(queueId < QUEUE_DATA_BASE || queueId > QUEUE_LAST ) throw "Error: request queue out of bound\n"; for(int i=0; i<f->ntoken; i++){ do{ mono_pkt = (Cppi_Desc*)Qmss_queuePop(queueId); }while(mono_pkt == 0); /* Get Packet info */ int mono_pkt_size = QMSS_DESC_SIZE(mono_pkt); mono_pkt = (Cppi_Desc*)QMSS_DESC_PTR (mono_pkt); // /* Clear Cache */ // Osal_qmssBeginMemAccess(mono_pkt, mono_pkt_size); // // /* Write back cache */ // Osal_qmssEndMemAccess(mono_pkt, mono_pkt_size); Qmss_queuePushDesc(QUEUE_FREE_DATA, mono_pkt); } } /* Invalidate cache */ Osal_qmssBeginMemAccess( Platform::get()->virt_to_phy((void*)(f->alloc)), f->size); return (long)Platform::get()->virt_to_phy((void*)(f->alloc)); }
/** * @b Description * @n * This function is used to obtain previously allocated descriptors. * The function opens a destination queue as specified in the input parameters * and pushes the requested number of descriptors if available onto it. * * @param[in] descCfg * Specifies the number of descriptors, memory region from where it should be allocated * and the destination queue to push to. * * @param[out] numAllocated * Number of descriptors actually allocated. * * @pre * Qmss_init function should be called before calling this function. * * @retval * Success - Destination queue handle on which the allocated descriptors are stored. * The queue must be closed by the caller using Qmss_queueClose() when done. * @retval * Failure - QMSS_NOT_INITIALIZED * @retval * Failure - QMSS_INVALID_PARAM * @retval * Failure - QMSS_MEMREGION_NOT_INITIALIZED * @retval * Failure - QMSS_QUEUE_OPEN_ERROR */ Qmss_QueueHnd Qmss_initDescriptor (Qmss_DescCfg *descCfg, uint32_t *numAllocated) { uint32_t count; uint32_t *descPtr; uint8_t isAllocated; int32_t srcQueNum, srcQueHnd, destQueHnd; /* Get the descriptor from the source queue */ if (qmssLObjIsValid == 0) { return QMSS_NOT_INITIALIZED; } if (descCfg == NULL) { return QMSS_INVALID_PARAM; } /* Find the source queue given the memory region */ if ((srcQueNum = Qmss_getMemRegQueueHandle (descCfg->memRegion)) < 0) { return QMSS_MEMREGION_NOT_INITIALIZED; } /* Find the descriptor size in the given the memory region */ if ((Qmss_getMemRegDescSize (descCfg->memRegion)) == 0) { return QMSS_MEMREGION_NOT_INITIALIZED; } /* Open destination queue specified in the configuration */ if ((destQueHnd = Qmss_queueOpen (descCfg->queueType, descCfg->destQueueNum, &isAllocated)) < 0) { return QMSS_QUEUE_OPEN_ERROR; } /* Open general purpose queue on which descriptors are stored */ srcQueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, srcQueNum, &isAllocated); *numAllocated = 0; for (count = 0; count < descCfg->descNum; count++) { /* Pop descriptor from source queue */ if ((descPtr = Qmss_queuePop (srcQueHnd)) == NULL) { break; } /* Push descriptor to the specified destination queue */ /* TODO QueueProxy is not working add this later * Qmss_queuePushDesc (destQueHnd, descPtr, descSize); */ Qmss_queuePushDesc (destQueHnd, descPtr); *numAllocated += 1; } return destQueHnd; }
void K2ArmSpiderCommunicator::trace_end_recv(){ if(cur_mono_trace_in){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_trace_in, cur_mono_trace_in_size); Qmss_queuePushDesc(QUEUE_FREE_TRACE, cur_mono_trace_in); cur_mono_trace_in = 0; cur_mono_trace_in_size = 0; }else throw "SpiderCommunicator: Try to send a free'd message"; }
void K2ArmSpiderCommunicator::trace_end_send(int size){ if(cur_mono_trace_out){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_trace_out, cur_mono_trace_out_size); Qmss_queuePushDesc(QUEUE_TRACE, cur_mono_trace_out); cur_mono_trace_out = 0; cur_mono_trace_out_size = 0; }else throw "SpiderCommunicator: Try to send a free'd message"; }
void K2ArmSpiderCommunicator::ctrl_end_recv(int lrtIx){ if(cur_mono_pkt_in[lrtIx]){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_pkt_in[lrtIx], cur_mono_pkt_in_size[lrtIx]); Qmss_queuePushDesc(QUEUE_FREE_CTRL, cur_mono_pkt_in[lrtIx]); cur_mono_pkt_in[lrtIx] = 0; cur_mono_pkt_in_size[lrtIx] = 0; }else throw "SpiderCommunicator: Try to send a free'd message"; }
void K2ArmSpiderCommunicator::ctrl_end_send(int lrtIx, int size){ if(cur_mono_pkt_out[lrtIx]){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_pkt_out[lrtIx], cur_mono_pkt_out_size[lrtIx]); Qmss_queuePushDesc(CTRL_SPIDER_TO_LRT(lrtIx), (void*)cur_mono_pkt_out[lrtIx]); cur_mono_pkt_out[lrtIx] = 0; cur_mono_pkt_out_size[lrtIx] = 0; }else throw "SpiderCommunicator: Try to send a free'd message"; }
void K2DspLrtCommunicator::ctrl_end_recv(){ if(cur_mono_pkt_in){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_pkt_in, cur_mono_pkt_in_size); Qmss_queuePushDesc(QUEUE_FREE_CTRL, cur_mono_pkt_in); cur_mono_pkt_in = 0; cur_mono_pkt_in_size = 0; }else throw "LrtCommunicator: Try to send a free'd message"; }
void K2DspLrtCommunicator::ctrl_end_send(int size){ if(cur_mono_pkt_out){ /* Send the descriptor */ Osal_qmssEndMemAccess(cur_mono_pkt_out, cur_mono_pkt_out_size); Qmss_queuePushDesc(CTRL_LRT_TO_SPIDER, (void*)cur_mono_pkt_out); cur_mono_pkt_out = 0; cur_mono_pkt_out_size = 0; }else throw "LrtCommunicator: Try to send a free'd message"; }
/** * @b Description * @n * This function is used to configure memory region at runtime. * The function configures specified memory region with descriptor base address, * descriptor size and the number of descriptors. * * @param[out] memRegCfg * Pointer to the memory region configuration structure allocated by caller. * Descriptor memory address should be a global address * * @pre * Qmss_init function should be called before calling this function. * Memory Region specified should not have been configured before. * * @retval * Success - Inserted Memory region index. Range is 0 to 19. * @retval * Failure - QMSS_INVALID_PARAM * @retval * Failure - QMSS_NOT_INITIALIZED * @retval * Failure - QMSS_MEMREGION_ALREADY_INITIALIZED * @retval * Failure - QMSS_MEMREGION_INVALID_PARAM * @retval * Failure - QMSS_MAX_DESCRIPTORS_CONFIGURED * @retval * Failure - QMSS_MEMREGION_INVALID_INDEX * @retval * Failure - QMSS_MEMREGION_OVERLAP * @retval * Failure - QMSS_QUEUE_OPEN_ERROR */ Qmss_Result Qmss_insertMemoryRegion (Qmss_MemRegInfo *memRegCfg) { uint32_t count, powRegSize, reg = 0; uint32_t i, startIndex, nextIndex; uint8_t *descPtr, isAllocated; int32_t queueHnd, index = -1, prevIndex; void *key; if (memRegCfg == NULL) return QMSS_INVALID_PARAM; if (qmssLObjIsValid == 0) return QMSS_NOT_INITIALIZED; /* Descriptor size should be a multiple of 16 */ if ((memRegCfg->descSize < 16) || ((memRegCfg->descSize % 16) != 0)) { return QMSS_INVALID_PARAM; } /* Number of descriptors should be a function 2^(5 + reg_size) */ if (memRegCfg->descNum < 32) { return QMSS_INVALID_PARAM; } for (i = 5; i < 20; i++) { uint32_t temp; temp = memRegCfg->descNum >> i; if (temp & 0x1) { if (temp != 1) return QMSS_INVALID_PARAM; break; } } /* Begin Critical Section before accessing shared resources. */ key = Qmss_osalCsEnter (); /* Invalidate Global Object */ Qmss_osalBeginMemAccess ((void *) &qmssGObj, sizeof (Qmss_GlobalObj)); /* If specified memory region is already configured don't overwrite that configuration */ if ((memRegCfg->memRegion >= 0) && (qmssGObj.memRegInfo[memRegCfg->memRegion].descNum != 0)) { Qmss_osalCsExit (key); return QMSS_MEMREGION_ALREADY_INITIALIZED; } /* Check if maximum descriptors already configured */ if (qmssGObj.currDescCnt + memRegCfg->descNum > qmssGObj.initCfg.maxDescNum) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MAX_DESCRIPTORS_CONFIGURED; } /* Memory region to configure is not specified. Find the next available one */ if (memRegCfg->memRegion == Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED) { for (i = 0; i < QMSS_MAX_MEM_REGIONS; i++) { if (qmssGObj.memRegInfo[i].descNum == 0) { index = i; break; } } } else { index = memRegCfg->memRegion; startIndex = memRegCfg->startIndex; } if (index < 0 || index == QMSS_MAX_MEM_REGIONS) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_INVALID_INDEX; } if (memRegCfg->memRegion == Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED) { if (index == 0) startIndex = 0; else startIndex = qmssGObj.memRegInfo[index - 1].descNum + qmssGObj.memRegInfo[index - 1].startIndex; } /* startIndex should be a multiple of 32 */ if (startIndex != 0 && startIndex < 32) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_INVALID_PARAM; } else if ((startIndex >= 32) && ((startIndex % 32) != 0)) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_INVALID_PARAM; } /* Check for overlapping configuration */ for (prevIndex = index-1; (prevIndex > 0 && (qmssGObj.memRegInfo[prevIndex].descNum == 0)); prevIndex--); for (nextIndex = index+1; (nextIndex < (QMSS_MAX_MEM_REGIONS-1) && (qmssGObj.memRegInfo[nextIndex].descNum == 0)); nextIndex++); if (index != 0) { if ((qmssGObj.memRegInfo[prevIndex].startIndex != 0) && (qmssGObj.memRegInfo[prevIndex].startIndex + qmssGObj.memRegInfo[prevIndex].descNum > startIndex)) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } if (memRegCfg->descBase <= qmssGObj.memRegInfo[prevIndex].descBase) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } } if (index != (QMSS_MAX_MEM_REGIONS - 1)) { if ((qmssGObj.memRegInfo[nextIndex].startIndex != 0) && (memRegCfg->descNum > qmssGObj.memRegInfo[nextIndex].startIndex)) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } if ((qmssGObj.memRegInfo[nextIndex].startIndex != 0) && ((startIndex + memRegCfg->descNum) > qmssGObj.memRegInfo[nextIndex].startIndex)) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } if ((qmssGObj.memRegInfo[nextIndex].startIndex != 0) && (memRegCfg->descBase >= qmssGObj.memRegInfo[nextIndex].descBase)) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } } if ((qmssGObj.initCfg.linkingRAM1Base == 0) && ((startIndex + memRegCfg->descNum) > (qmssGObj.initCfg.linkingRAM0Size + 1))) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_MEMREGION_OVERLAP; } /* Configure the QMSS memory regions */ qmssLObj.qmDescReg->MEMORY_REGION_BASE_ADDRESS_GROUP[index].MEMORY_REGION_BASE_ADDRESS_REG = (uint32_t) memRegCfg->descBase; CSL_FINS (qmssLObj.qmDescReg->MEMORY_REGION_BASE_ADDRESS_GROUP[index].MEMORY_REGION_START_INDEX_REG, QM_DESCRIPTOR_REGION_CONFIG_MEMORY_REGION_START_INDEX_REG_START_INDEX, startIndex); CSL_FINS (reg, QM_DESCRIPTOR_REGION_CONFIG_MEMORY_REGION_DESCRIPTOR_SETUP_REG_DESC_SIZE, ((memRegCfg->descSize / 16) - 1)); for (powRegSize = 0; (32UL << powRegSize) < memRegCfg->descNum; powRegSize++); CSL_FINS (reg, QM_DESCRIPTOR_REGION_CONFIG_MEMORY_REGION_DESCRIPTOR_SETUP_REG_REG_SIZE, powRegSize); qmssLObj.qmDescReg->MEMORY_REGION_BASE_ADDRESS_GROUP[index].MEMORY_REGION_DESCRIPTOR_SETUP_REG = reg; /* Check if LLD is supposed to manage the descriptors, if so slice up the * descriptors and push to queues. else do nothing the caller will manage * the descriptors in memory region */ if (memRegCfg->manageDescFlag) { /* Split and push to general purpose queues */ /* Open general purpose queue */ queueHnd = Qmss_internalQueueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED, &isAllocated); if (queueHnd < 0) { /* End Critical Section */ Qmss_osalCsExit (key); return QMSS_QUEUE_OPEN_ERROR; } /* Store the handle */ qmssGObj.descQueue[index] = queueHnd; descPtr = (uint8_t *) memRegCfg->descBase; for (count = 0; count < memRegCfg->descNum; count ++) { /* TODO QueueProxy is not working add this later * Qmss_queuePushDesc (queueHnd, (uint32_t *)descPtr, initCfgPtr->memRegionInfo[index].descSize); */ Qmss_queuePushDesc (queueHnd, (uint32_t *) descPtr); descPtr = descPtr + memRegCfg->descSize; } } /* Store in internal data structures */ qmssGObj.memRegInfo[index].descBase = memRegCfg->descBase; qmssGObj.memRegInfo[index].descSize = memRegCfg->descSize; qmssGObj.memRegInfo[index].descNum = memRegCfg->descNum; qmssGObj.memRegInfo[index].startIndex = startIndex; qmssGObj.memRegInfo[index].manageDescFlag = memRegCfg->manageDescFlag; qmssGObj.memRegInfo[index].memRegion = (Qmss_MemRegion) index; qmssGObj.currDescCnt += memRegCfg->descNum; /* Writeback Global Object */ Qmss_osalEndMemAccess ((void *) &qmssGObj, sizeof (Qmss_GlobalObj)); /* End Critical Section */ Qmss_osalCsExit (key); return index; }