This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

QMSS initialization config for Ethernet and FFTC simultaneously

Hi,

I'am working with existing project that already using QMSS and initialize it for Ethernet purpose. 

My task to add the FFTC to the project. After some browsing the examples and docs I have noticed that Qmss_init() and Qmss_start (); functions should be called only once in the application. The initialization of FFTC performed after initialization of the Ethernet.

I need to add free descriptors for my FFTC, and as I understand I should do that in the QMSS initialization funcion. So the code if following:

#pragma DATA_ALIGN (gHostDesc, 16)
u_int8 gHostDesc[SIZE_HOST_DESC * NUM_HOST_DESC];

#pragma DATA_ALIGN (hostDesc, 16)
u_int8 hostDesc[FFTC_TEST_SIZE_HOST_DESC * FFTC_TEST_NUM_HOST_DESC];

int init_qmss (void)
{
int32 result;
Qmss_MemRegInfo memCfg;
Qmss_InitCfg qmssInitConfig;
Cppi_DescCfg cppiDescCfg;
u_int32 numAllocated;

// Initialize QMSS
memset (&qmssInitConfig, 0, sizeof (Qmss_InitCfg));

// Set up QMSS configuration

// Use internal linking RAM
qmssInitConfig.linkingRAM0Base = 0;
qmssInitConfig.linkingRAM0Size = 0;
qmssInitConfig.linkingRAM1Base = 0x0;
qmssInitConfig.maxDescNum = NUM_HOST_DESC + FFTC_TEST_NUM_HOST_DESC;

qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_le;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);

// Initialize the Queue Manager
result = Qmss_init (&qmssInitConfig, qmssGblCfgParams);
if(result != QMSS_SOK) {
#if DEBUG_ERRORS
System_printf("Error initializing Queue Manager SubSystem, Error code : %d\n", result);
#endif // DEBUG_ERRORS
return -1;
}

// Start Queue manager on this core
Qmss_start ();

/* Setup the descriptor memory regions.
*
* The Descriptor base addresses MUST be global addresses and
* all memory regions MUST be setup in ascending order of the
* descriptor base addresses.
*/

// Initialize and setup CPSW Host Descriptors
memset (gHostDesc, 0, SIZE_HOST_DESC * NUM_HOST_DESC);
memCfg.descBase = (u_int32 *) Convert_CoreLocal2GlobalAddr ((u_int32) gHostDesc);
memCfg.descSize = SIZE_HOST_DESC;
memCfg.descNum = NUM_HOST_DESC;
memCfg.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0;
memCfg.startIndex = 0;

// Insert Host Descriptor memory region
result = Qmss_insertMemoryRegion(&memCfg);
if(result == QMSS_MEMREGION_ALREADY_INITIALIZED) {
#if DEBUG_ERRORS
System_printf("Memory Region %d already Initialized \n", memCfg.memRegion);
#endif // DEBUG_ERRORS
} else if(result < QMSS_SOK) {
#if DEBUG_ERRORS
System_printf("Error: Inserting memory region %d, Error code : %d\n", memCfg.memRegion, result);
#endif // DEBUG_ERRORS
return -1;
}

memset (hostDesc, 0, FFTC_TEST_SIZE_HOST_DESC * FFTC_TEST_NUM_HOST_DESC);
memCfg.descBase = (UInt32 *) Convert_CoreLocal2GlobalAddr ((UInt32) hostDesc);
memCfg.descSize = FFTC_TEST_SIZE_HOST_DESC;
memCfg.descNum = FFTC_TEST_NUM_HOST_DESC;
memCfg.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memCfg.memRegion = Qmss_MemRegion_MEMORY_REGION1;
memCfg.startIndex = 0;

/* Insert Host Descriptor memory region */
result = Qmss_insertMemoryRegion(&memCfg);
if (result == QMSS_MEMREGION_ALREADY_INITIALIZED)
{
Fftc_osalLog ("[Core 0]: Memory Region %d already Initialized \n", memCfg.memRegion);
}
else if (result < QMSS_SOK)
{
Fftc_osalLog ("[Core 0]: Error! Inserting memory region %d, Error code : %d\n", memCfg.memRegion, result);
return -1;
}

/* Initialize all the descriptors we just allocated on the
* memory region above. Setup the descriptors with some well
* known values before we use them for data transfers.
*/
memset (&cppiDescCfg, 0, sizeof (cppiDescCfg));
cppiDescCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0;
cppiDescCfg.descNum = NUM_HOST_DESC;
cppiDescCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
cppiDescCfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
cppiDescCfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR;
cppiDescCfg.descType = Cppi_DescType_HOST;

/* By default:
* (1) Return descriptors to tail of queue
* (2) Always return entire packet to this free queue
* (3) Set that PS Data is always present in start of SOP buffer
* (4) Configure free q num < 4K, hence qMgr = 0
* (5) Recycle back to the same Free queue by default.
*/
cppiDescCfg.returnPushPolicy = Qmss_Location_TAIL;
cppiDescCfg.cfg.host.returnPolicy = Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET;
cppiDescCfg.cfg.host.psLocation = Cppi_PSLoc_PS_IN_DESC;
cppiDescCfg.returnQueue.qMgr = 0;
cppiDescCfg.returnQueue.qNum = QMSS_PARAM_NOT_SPECIFIED;
cppiDescCfg.epibPresent = Cppi_EPIB_EPIB_PRESENT;

// Initialize the descriptors, create a free queue and push descriptors to a global free queue
if((gGlobalFreeQHnd = Cppi_initDescriptor (&cppiDescCfg, &numAllocated)) <= 0) {
#if DEBUG_ERRORS
System_printf("Error Initializing Free Descriptors, Error: %d \n", gGlobalFreeQHnd);
#endif // DEBUG_ERRORS
return -1;
}

// Queue Manager Initialization Done
return 0;
}

 With the bold text I highlighted the code that I have add to the function. But during debug I get this error massage in the console. 

[Core 0]: Error! Inserting memory region 1, Error code : -137
QMSS init failed

It says that QMSS memory region overlap, but I don't get why?

Regards, Pavlo!

  • Hi,

    Thanks for your post.

    For Keystone 1 devices, there are restriction applied in setting the memory region base addresses. Yes, memory region base addresses should be set in ascending address order, i.e. region 0 should be at a lower address than region 1, region 1 should be at a lower address than region 2 and so on which would require extra planning when configuring regions in LL2, MSMC and DDR.

    Make sure that the address of the memory region is in order and for more details, read the multicore navigator user guide for keystone devices. That is, the global address of the first memory region which is inserted, MUST be lower than the global address of the second memory region and the second must be lower than the third and so on.

    http://www.ti.com/lit/ug/sprugr9g/sprugr9g.pdf

    Please see section 6.2.1 QMSS initialization example code and appendix A for example code utility functions, appendix C for example code keystone I addresses from the above user guide.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question

    -------------------------------------------------------------------------------------------------------

  • Dear Sivaraj,
    Thank you for your answer and tips. I have looked this UG before, thought I made everything right, but I will check once again. The issue can be solved if for second descriptor in memCfg.memRegion specify not Qmss_MemRegion_MEMORY_REGION1, but Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED. But I don't know why :)
    Regards, Pavlo!