Part Number:TMS320C6678
Tool/software:TI-RTOS
Hi
I spent a lot of time for integrating NDK and SRIO but I couldn't integrate the modules finally. I am so sad, Please help me to solve the problem.
My tools:
OS: win7
CCS: 7
The sequense of calling my functions(in the main()) are as below:
1) Qmss_Cppi_PA_Init();
2) SRIO (enable_srio();, SrioDevice_init();, Srio_init(); and clearSrioStatusErrors(); )
3) GPIO_INIT();
4) setupSRIOAppConfig((Qmss_MemRegion)Qmss_MemRegion_MEMORY_REGION1); .
In stage one I declared and init Qmss, Cppi, and PA as below:
![]()
void Qmss_Cppi_PA_Init(){
Qmss_MemRegInfo memRegInfo;
int32_t result;
int i,coreNum;
QMSS_CFG_T qmss_cfg;
CPPI_CFG_T cppi_cfg;
/* Get information about the platform so we can use it in various places */
memset( (void *) &gPlatformInfo, 0, sizeof(platform_info));
(void) platform_get_info(&gPlatformInfo);
(void) platform_uart_init();
(void) platform_uart_set_baudrate(115200);
(void) platform_write_configure(PLATFORM_WRITE_ALL);
/* Clear the state of the User LEDs to OFF */
for (i=0; i < gPlatformInfo.led[PLATFORM_USER_LED_CLASS].count; i++) {
(void) platform_led(i, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
}
coreNum =CSL_chipReadReg (CSL_CHIP_DNUM);
/* Initialize the components required to run this application:
* (1) QMSS
* (2) CPPI
* (3) Packet Accelerator
*/
/* Initialize QMSS */
if (coreNum == 0)
{
qmss_cfg.master_core = 1;
}
else
{
qmss_cfg.master_core = 0;
}
qmss_cfg.max_num_desc = MAX_NUM_DESC+ NUM_HOST_DESC; //256
qmss_cfg.desc_size = MAX_DESC_SIZE; //128
qmss_cfg.mem_region = Qmss_MemRegion_MEMORY_REGION0;
if (res_mgr_init_qmss (&qmss_cfg) != 0)
{
System_printf ("Failed to initialize the QMSS subsystem \n");
}
else
{
System_printf ("QMSS successfully initialized \n");
}
/* Initialize CPPI */
if (coreNum == 0)
{
cppi_cfg.master_core = 1;
}
else
{
cppi_cfg.master_core = 0;
}
cppi_cfg.dma_num = Cppi_CpDma_PASS_CPDMA;
cppi_cfg.num_tx_queues = NUM_PA_TX_QUEUES;
cppi_cfg.num_rx_channels = NUM_PA_RX_CHANNELS;
if (res_mgr_init_cppi (&cppi_cfg) != 0)
{
System_printf ("Failed to initialize CPPI subsystem \n");
}
else
{
System_printf ("CPPI successfully initialized \n");
}
if (res_mgr_init_pass()!= 0) {
System_printf ("Failed to initialize the Packet Accelerator \n");
}
else
{
System_printf ("PA successfully initialized \n");
}
}
I only modyfied " res_mgr_init_qmss() " fanction as below and other functions were without any changes:
int32_t
res_mgr_init_qmss
(
QMSS_CFG_T *p_qmss_cfg
)
{
Qmss_MemRegInfo memRegInfo; //M.A
int32_t result;
Qmss_MemRegInfo memCfg;
Qmss_InitCfg qmssInitConfig;
Cppi_DescCfg cppiDescCfg;
uint32_t numAllocated;
if (p_qmss_cfg->master_core)
{
/* 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 = p_qmss_cfg->max_num_desc;
qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
#ifdef _LITTLE_ENDIAN
qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_le;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
#else
qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_be;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
#endif
/* Initialize the Queue Manager */
#if defined(DEVICE_K2H) || defined(DEVICE_K2K)
result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams);
#else
result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams[0]);
#endif
if (result != QMSS_SOK)
{
platform_write ("Error initializing Queue Manager SubSystem, Error code : %d\n", result);
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 required for example */
memset (Ethernet_region, 0, /*128*128*/MAX_DESC_SIZE_ETH * NUM_DESC_ETH);
memCfg.descBase = (uint32_t *) Convert_CoreLocal2GlobalAddr ((uint32_t) Ethernet_region);
memCfg.descSize = MAX_DESC_SIZE_ETH;//128;//64;//
memCfg.descNum = NUM_DESC_ETH;//128;//
memCfg.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memCfg.memRegion = p_qmss_cfg->mem_region;
memCfg.startIndex = 0;
/* Insert Host Descriptor memory region */
result = Qmss_insertMemoryRegion(&memCfg);
if (result == QMSS_MEMREGION_ALREADY_INITIALIZED)
{
platform_write ("Memory Region %d already Initialized \n", memCfg.memRegion);
}
else if (result < QMSS_SOK)
{
platform_write ("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 = p_qmss_cfg->mem_region;
cppiDescCfg.descNum = NUM_DESC_ETH;//128;//
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)
{
platform_write ("Error Initializing Free Descriptors, Error: %d \n", gGlobalFreeQHnd);
return -1;
}
if (numAllocated != cppiDescCfg.descNum) {
platform_write ("function Init_Qmss: expected %d descriptors to be initialized, only %d are initialized\n", cppiDescCfg.descNum, numAllocated);
//return (-1);
}
/* Initialize the Host Region. */
memset ((void *)&SRIO_region, 0, sizeof(SRIO_region));
/* Memory Region Configuration */
memRegInfo.descBase = (uint32_t *)Convert_CoreLocal2GlobalAddr((uint32_t)SRIO_region);
memRegInfo.descSize = MAX_DESC_SIZE_SRIO;/*p_qmss_cfg->desc_size*/;//SIZE_HOST_DESC;
memRegInfo.descNum = NUM_DESC_SRIO;//p_qmss_cfg->max_num_desc;//NUM_HOST_DESC;
memRegInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memRegInfo.memRegion = Qmss_MemRegion_MEMORY_REGION1;
memRegInfo.startIndex = 128;//0;//
/* Initialize and inset the memory region. */
result = Qmss_insertMemoryRegion (&memRegInfo);
if (result < QMSS_SOK)
{
platform_write ("Error inserting memory region: %d\n", result);
return;
}
/* Queue Manager Initialization Done */
return 0;
}
In stage two I only modify " SrioDevice_init() " function that I can communicate to FPGA.
In stage three I init GPIO that I think it didn't have the effect on the problem.
In stage four I called " setupSRIOAppConfig() ". I called this function with a separate memory region " Qmss_MemRegion_MEMORY_REGION1" from Ethernet memory region "Qmss_MemRegion_MEMORY_REGION0".
static int32_t setupSRIOAppConfig (Qmss_MemRegion memRegion)
{
Qmss_QueueHnd myRxFreeQueueHnd;
Qmss_QueueHnd myRxCompletionQueueHnd;
Qmss_QueueHnd tmpQueueHnd;
UInt32 numAllocated;
int32_t eventId;
UInt8 isAllocated;
Cppi_DescCfg descCfg;
UInt16 index;
Cppi_HostDesc* ptrHostDesc;
UInt8* ptrRxData;
UInt32 numRxBuffers;
Srio_DrvConfig drvCfg;
Srio_DrvHandle drvHandle;
CSL_SrioHandle hSrioCSL;
// char buffer[MAX_MESSAGE_SIZE];
Error_Block errorBlock; //M.A
/* Initialize the SRIO Driver Configuration. */
memset ((Void *)&drvCfg, 0, sizeof(Srio_DrvConfig));
/* Initialize the OSAL
* Gets 30 buffers of mtu size. 30 is hard coded in the OSAL.
* */
if (Osal_dataBufferInitMemory(SRIO_MAX_MTU) < 0)
{
return NULL;
}
/********************************************************************************
* The SRIO Driver Instance is going to be created with the following properties:
* - Application Managed
* - Receive Completion Queue is Application specified; which implies that there
* is no interrupt support. Applications will hence need to poll the queue to
* check if there is data available or not.
* - The Receive Free Descriptor Queues along with the Size thresholds are
* managed and created by the application.
********************************************************************************/
/* Create the application receive free queue. */
myRxFreeQueueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED,&isAllocated);
if (myRxFreeQueueHnd < 0)
{
return NULL;
}
/* Create the application receive completion queue. */
myRxCompletionQueueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED,&isAllocated);
if (myRxCompletionQueueHnd < 0)
{
return NULL;
}
/* We are going to be using 4 receive buffers in this example. */
numRxBuffers = 4;
/* Application created queue which stores all the receive buffers. */ //M.A
descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION1;//Qmss_MemRegion_MEMORY_REGION0; // aligns to Host region that was set in init, it was not specified which means it will be zero.
descCfg.descNum = numRxBuffers;
descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED;
descCfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE;
descCfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR;
descCfg.descType = Cppi_DescType_HOST;
descCfg.returnQueue = Qmss_getQueueNumber(myRxFreeQueueHnd);
descCfg.epibPresent = Cppi_EPIB_NO_EPIB_PRESENT;
descCfg.returnPushPolicy = Qmss_Location_HEAD;
descCfg.cfg.host.returnPolicy = Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET;
descCfg.cfg.host.psLocation = Cppi_PSLoc_PS_IN_DESC;
tmpQueueHnd = Cppi_initDescriptor (&descCfg, &numAllocated);
if (tmpQueueHnd < 0 || numAllocated < 1)
{
return NULL;
}
/* Initialize the application receive buffers. */
for (index = 0; index < descCfg.descNum; index++)
{
/* Pop off a descriptor */
ptrHostDesc = (Cppi_HostDesc *)Qmss_queuePop(tmpQueueHnd);
if (ptrHostDesc == NULL)
{
return NULL;
}
/* Allocate the receive buffer where the data will be received into by the SRIO CPDMA. */
/* Make sure to adjust the RX buffer size to work around the SRIO CPDMA issue. */
ptrRxData = (uint8_t*)Memory_alloc (NULL, (MESSAGE_MAX_DATA_SIZE+RX_BUFFER_BYTES_ADJUSTMENT), 0, &errorBlock);
if (ptrRxData == NULL)
return -1;
/* Convert the address to a global address. */
ptrRxData = (uint8_t*)l2_global_address((uint32_t)ptrRxData);
/* Allocate the receive buffer where the data will be received into by the SRIO CPDMA.
* osal_srio grabs one of the 30 buffers allocated by the init function. */
// ptrRxData = (UInt8*)Osal_srioDataBufferMalloc(SRIO_MAX_MTU);
// if (ptrRxData == NULL)
// {
// return NULL;
// }
/* Set the DATA and ORIGNAL DATA in the buffer descriptor. */
Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc*)ptrHostDesc, (UInt8*)ptrRxData, SRIO_MAX_MTU);
Cppi_setOriginalBufInfo (Cppi_DescType_HOST, (Cppi_Desc*)ptrHostDesc, (UInt8*)ptrRxData, SRIO_MAX_MTU);
/* Add the packet descriptor to the Application Receive Free Queue. */
Qmss_queuePushDescSize (myRxFreeQueueHnd, (UInt32*)ptrHostDesc, SIZE_HOST_DESC);
}
/* Close the temporary queue. */
Qmss_queueClose (tmpQueueHnd);
/********************************************************************************
* The SRIO Driver Instance is going to be created with the following properties:
* - Driver Managed
* - Interrupt Support (Pass the Rx Completion Queue as NULL)
********************************************************************************/
/* Setup the SRIO Driver Managed Configuration. */
drvCfg.bAppManagedConfig = FALSE;
/* Driver Managed: Receive Configuration */
drvCfg.u.drvManagedCfg.bIsRxCfgValid = 1;
drvCfg.u.drvManagedCfg.rxCfg.rxMemRegion = Qmss_MemRegion_MEMORY_REGION1; //Qmss_MemRegion_MEMORY_REGION0; //M.A
drvCfg.u.drvManagedCfg.rxCfg.numRxBuffers = 4;
drvCfg.u.drvManagedCfg.rxCfg.rxMTU = SRIO_MAX_MTU;
/* Accumulator Configuration. */
int32_t coreToQueueSelector[4];
/* This is the table which maps the core to a specific receive queue. */
//These were chosen based on using event 49 instead of 48. NDK uses 48
coreToQueueSelector[0] = 712;
coreToQueueSelector[1] = 713;
coreToQueueSelector[2] = 714;
coreToQueueSelector[3] = 715;
/* Since we are programming the accumulator we want this queue to be a HIGH PRIORITY Queue */
drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue = Qmss_queueOpen (Qmss_QueueType_HIGH_PRIORITY_QUEUE,coreToQueueSelector[0/*CORE_NUM*/], &isAllocated);
if (drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue < 0)
{
return NULL;
}
/* Accumulator Configuration is VALID. */
drvCfg.u.drvManagedCfg.rxCfg.bIsAccumlatorCfgValid = 1;
/* Accumulator Configuration. */
drvCfg.u.drvManagedCfg.rxCfg.accCfg.channel = NUM_PA_TX_QUEUES+NUM_PA_RX_CHANNELS;//+CORE_NUM; //M.A
drvCfg.u.drvManagedCfg.rxCfg.accCfg.command = Qmss_AccCmd_ENABLE_CHANNEL;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.queueEnMask = 0;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.queMgrIndex = coreToQueueSelector[0/*CORE_NUM*/];
drvCfg.u.drvManagedCfg.rxCfg.accCfg.maxPageEntries = 2;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.timerLoadCount = 0;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qmss_AccPacingMode_LAST_INTERRUPT;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listEntrySize = Qmss_AccEntrySize_REG_D;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listCountMode = Qmss_AccCountMode_ENTRY_COUNT;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.multiQueueMode = Qmss_AccQueueMode_SINGLE_QUEUE;
/* Initialize the accumulator list memory */
memset ((Void *)&gHiPriAccumList1[0], 0, sizeof(gHiPriAccumList1));
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listAddress = l2_global_address((UInt32)&gHiPriAccumList1[0]);
/* Driver Managed: Transmit Configuration */
drvCfg.u.drvManagedCfg.bIsTxCfgValid = 1;
drvCfg.u.drvManagedCfg.txCfg.txMemRegion = Qmss_MemRegion_MEMORY_REGION1;//Qmss_MemRegion_MEMORY_REGION0; //M.A
drvCfg.u.drvManagedCfg.txCfg.numTxBuffers = 4;
drvCfg.u.drvManagedCfg.txCfg.txMTU = SRIO_MAX_MTU;
/* Start the Driver Managed SRIO Driver. Calls Cppi_open for SRIO */
hAppManagedSrioDrv = Srio_start(&drvCfg);
if (hAppManagedSrioDrv == NULL)
{
return NULL;
}
//Hook up the SRIO interrupt with the core. Don't use standard 48 becuase ndk is using that.
EventCombiner_dispatchPlug (49, (EventCombiner_FuncPtr)Srio_rxCompletionIsr, (UArg)hAppManagedSrioDrv, TRUE);
EventCombiner_enableEvent(49);
/* Get the CSL SRIO Handle. */
hSrioCSL = CSL_SRIO_Open (0);
/* SRIO DIO Interrupts need to be routed from the CPINTC0 to GEM Event.
* - We have configured DIO Interrupts to get routed to Interrupt Destination 0
* (Refer to the CSL_SRIO_RouteLSUInterrupts API configuration in the SRIO Initialization)
* - We want this System Interrupt to mapped to Host Interrupt 8 */
/* Disable Interrupt Pacing for INTDST0 */
CSL_SRIO_DisableInterruptPacing (hSrioCSL, 0);
/* Route LSU0 ICR0 to INTDST0 */
CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 0, 0);
/* Route LSU0 ICR1 to INTDST0 */
CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 1, 0);
/* Route LSU0 ICR2 to INTDST0 */
CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 2, 0);
/* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO ISR Handler. */
CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDIOIsr, (UArg)hAppManagedSrioDrv, TRUE);
/* The configuration is for CPINTC0. We map system interrupt 112 to Host Interrupt 8. */
CpIntc_mapSysIntToHostInt(0, CSL_INTC0_INTDST0, 8);
/* Enable the Host Interrupt. */
CpIntc_enableHostInt(0, 8);
/* Enable the System Interrupt */
CpIntc_enableSysInt(0, CSL_INTC0_INTDST0);
/* Get the event id associated with the host interrupt. */
eventId = CpIntc_getEventId(8);
/* Plug the CPINTC Dispatcher. */
EventCombiner_dispatchPlug (eventId, (EventCombiner_FuncPtr)CpIntc_dispatch, 8, TRUE);
return (int32_t)hAppManagedSrioDrv;
}
I should mentioned that I called SRIO and DIO in two tasks.
Best Regards