]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/transport/tci6614/ipc/examples/srioIpcBenchmark/bench_srio.c
transport: add to PDK
[processor-sdk/pdk.git] / packages / ti / transport / tci6614 / ipc / examples / srioIpcBenchmark / bench_srio.c
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2011, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
33 #include <xdc/std.h>
34 #include <xdc/cfg/global.h>
36 /* XDC.RUNTIME module Headers */
37 #include <xdc/runtime/System.h>
38 #include <xdc/runtime/IHeap.h>
39 #include <xdc/runtime/Timestamp.h>
41 /* IPC module Headers */
42 #include <ti/ipc/MultiProc.h>
43 #include <ti/ipc/MessageQ.h>
44 #include <ti/ipc/HeapBufMP.h>
45 #include <ti/ipc/SharedRegion.h>
47 /* PDK module Headers */
48 #include <ti/platform/platform.h>
50 /* BIOS6 module Headers */
51 #include <ti/sysbios/BIOS.h>
52 #include <ti/sysbios/family/c66/Cache.h>
54 /* CSL modules */
55 #include <ti/csl/csl_cacheAux.h>
56 #include <ti/csl/csl_psc.h>
57 #include <ti/csl/csl_pscAux.h>
58 #include <ti/csl/csl_chip.h>
60 /* QMSS LLD */
61 #include <ti/drv/qmss/qmss_drv.h>
62 #include <ti/drv/qmss/qmss_firmware.h>
64 /* CPPI LLD */
65 #include <ti/drv/cppi/cppi_drv.h>
67 /* SRIO LLD */
68 #include <ti/drv/srio/srio_drv.h>
69  
70 #include <ti/transport/ipc/examples/common/bench_common.h>
72 /************************ EXTERN VARIABLES ********************/
73 /* QMSS device specific configuration */
74 extern Qmss_GlobalConfigParams  qmssGblCfgParams;
75 /* CPPI device specific configuration */
76 extern Cppi_GlobalConfigParams  cppiGblCfgParams;
77 /**************************************************************/
79 #define NUM_HOST_DESC         numDescriptors
80 #define SIZE_HOST_DESC        descriptorSize
81 #define SIZE_CPPI_HEAP            cppiHeapSize
83 #define SRIO_MTU_SIZE srioMtuSize
85 #define HEAP_NAME   "myHeapBuf"
86 #define HEAP_ID         appMsgQHeapId
88 /* Number of times to run the loop */
89 #define NUMLOOPS        100
90 #define NUMIGNORED      (5)
91 #define NUM_MSGS        (10)
93 /* Benchmark parameters */
94 Char localQueueName[6];
95 Char nextQueueName[6];
96 Char prevQueueName[6];
98 UInt numCores = 0;
99 UInt16 prevCoreId;
101 UInt16 selfId;
102 UInt64 timeAdj = 0;
103 Types_FreqHz timerFreq, cpuFreq;
105 /* Results */
106 UInt32 rawtimestamps[NUMLOOPS];
107 UInt32 latencies[NUMLOOPS - 1];
109 MessageQ_Handle messageQ = NULL;
110 MessageQ_QueueId nextQueueId, prevQueueId;
112 UInt64 timeLength = 0;
114 /* These are the device identifiers used used in the TEST Application */
115 const UInt32 DEVICE_ID1_16BIT    = Srio16BitDeviceId1;
116 const UInt32 DEVICE_ID1_8BIT     = Srio8BitDeviceId1;
117 const UInt32 DEVICE_ID2_16BIT    = Srio16BitDeviceId2;
118 const UInt32 DEVICE_ID2_8BIT     = Srio8BitDeviceId2;
119 const UInt32 DEVICE_ID3_16BIT    = Srio16BitDeviceId3;
120 const UInt32 DEVICE_ID3_8BIT     = Srio8BitDeviceId3;
121 const UInt32 DEVICE_ID4_16BIT    = Srio16BitDeviceId4;
122 const UInt32 DEVICE_ID4_8BIT     = Srio8BitDeviceId4;
124 /* These are the garbage queues used in the test Application */
125 const UInt32 GARBAGE_LEN_QUEUE = 905;
126 const UInt32 GARBAGE_TOUT_QUEUE = SrioGarbageQ; /* Timeout errors must be cleaned up by transport */
127 const UInt32 GARBAGE_RETRY_QUEUE = 907;
128 const UInt32 GARBAGE_TRANS_ERR_QUEUE = SrioGarbageQ; /* Transmission errors must be cleaned up by transport */
129 const UInt32 GARBAGE_PROG_QUEUE = 909;
130 const UInt32 GARBAGE_SSIZE_QUEUE = 910;
132 Float cpuTimerFreqRatio;
134 Statistics latencyStats;
137 /* Descriptor pool [Size of descriptor * Number of descriptors] */
138 /* place this host descritor pool in shared memory */
139 #pragma DATA_SECTION (hostDesc, ".desc");
140 #pragma DATA_ALIGN (hostDesc, 16)
141 UInt8               hostDesc[SIZE_HOST_DESC * NUM_HOST_DESC];
143 /* Statically created shared heap for CPPI since IPC does create a
144  * shared heap for SharedRegion prior to Ipc_attach */
145 #pragma DATA_SECTION (cppiHeap, ".cppi_heap");
146 #pragma DATA_ALIGN (cppiHeap, 128)
147 UInt8               cppiHeap[SIZE_CPPI_HEAP];
149 #define NUM_MSGS_TO_PREALLOC (5)
151 #pragma DATA_SECTION (txMsgPtrs, ".msgQ_ptrs");
152 TstMsg *txMsgPtrs[NUM_MSGS_TO_PREALLOC];
154 #pragma DATA_SECTION (rxMsgPtrs, ".msgQ_ptrs");
155 TstMsg *rxMsgPtrs[NUM_MSGS_TO_PREALLOC];
157 #pragma DATA_SECTION (isSRIOInitialized, ".srioSharedMem");
158 volatile Uint32     isSRIOInitialized    = 0;
160 /**
161  *  @b Description
162  *  @n  
163  *      The function provides the initialization sequence for the SRIO IP
164  *      block. This can be modified by customers for their application and
165  *      configuration.
166  *
167  *  @retval
168  *      Success     - 0
169  *  @retval
170  *      Error       - <0
171  */
172 extern int32_t SrioDevice_init (void);
174 /**
175  *  @b Description
176  *  @n  
177  *      This function enables the power/clock domains for SRIO. 
178  *
179  *  @retval
180  *      Success     - 0
181  *  @retval
182  *      Error       - <0
183  */
184 static Int32 enable_srio (void)
186 #ifndef SIMULATOR_SUPPORT
187     /* SRIO power domain is turned OFF by default. It needs to be turned on before doing any 
188      * SRIO device register access. This not required for the simulator. */
190     /* Set SRIO Power domain to ON */        
191     CSL_PSC_enablePowerDomain (CSL_PSC_PD_SRIO);
193     /* Enable the clocks too for SRIO */
194     CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);
196     /* Start the state transition */
197     CSL_PSC_startStateTransition (CSL_PSC_PD_SRIO);
199     /* Wait until the state transition process is completed. */
200     while (!CSL_PSC_isStateTransitionDone (CSL_PSC_PD_SRIO));
202     /* Return SRIO PSC status */
203     if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) == PSC_PDSTATE_ON) &&
204         (CSL_PSC_getModuleState (CSL_PSC_LPSC_SRIO) == PSC_MODSTATE_ENABLE))
205     {
206         /* SRIO ON. Ready for use */            
207         return 0;
208     }
209     else
210     {
211         /* SRIO Power on failed. Return error */            
212         return -1;            
213     }
214 #else
215     /* PSC is not supported on simulator. Return success always */
216     return 0;
217 #endif
220 /**
221  *  @b Description
222  *  @n  
223  *      This functions prints the statistics gathered for the transport during
224  *      the latency test.
225  */
226 Void printStatistics()
228     UInt32 timeElapsed;
229     UInt i;
231     /* Convert timestamps to CPU time */
232     for (i = 0; i < NUMLOOPS; i++) {
233         rawtimestamps[i] *= cpuTimerFreqRatio;
234     }
235     
236     for (i = 0; i < NUMLOOPS - 1; i++) {
237         latencies[i] = (rawtimestamps[i + 1] - rawtimestamps[i]) / numCores;
238     }
240     getStats(latencies + NUMIGNORED, NUMLOOPS - NUMIGNORED - 2, &latencyStats);
241     
242     timeElapsed =  rawtimestamps[NUMLOOPS - NUMIGNORED - 2] -
243             rawtimestamps[NUMIGNORED];
244     /* Throughput = time elapsed divided by total #of of hops */
245     
246     System_printf("======== SYSTEM ATTRIBUTES ======== \n");
247     System_printf("Device name:                  %s\n", DEVICENAME);
248     System_printf("Processor names:              %s\n", PROCNAMES);
249     System_printf("CPU Freq:                     %d MHz\n", 
250         cpuFreq.lo / 1000000);
251     System_printf("Timer Freq:                   %d MHz\n\n", 
252         timerFreq.lo / 1000000);
254     System_printf("======== BENCHMARK ATTRIBUTES ======== \n");
255     System_printf("MessageQ setup delegate:      %s\n", TRANSPORTSETUP);
256     System_printf("Number of processors:         %d\n", numCores);
257     System_printf("Number of messages received:  %d\n", latencyStats.numVals);
258     System_printf("Build profile:                %s\n\n", BUILDPROFILE);
260     System_printf("======== MESSAGEQ BENCHMARK RESULTS ======== \n");    
261     System_printf("Average 1-way latency:        %10d (cycles/msg)           %10d (ns/msg)\n", 
262         (UInt32)latencyStats.mean, CYCLES_TO_NS(latencyStats.mean, cpuFreq.lo));
263     System_printf("Maximum 1-way latency:        %10d (cycles/msg) (#%5d)  %10d (ns/msg)\n", 
264         latencyStats.max, latencyStats.maxIndex, CYCLES_TO_NS(latencyStats.max, cpuFreq.lo));
265     System_printf("Minimum 1-way latency:        %10d (cycles/msg) (#%5d)  %10d (ns/msg)\n", 
266         latencyStats.min, latencyStats.minIndex, CYCLES_TO_NS(latencyStats.min, cpuFreq.lo)); 
267     System_printf("Standard deviation:           %10d (cycles/msg)\n", 
268         (UInt32)latencyStats.stddev);
269     System_printf("Total time elapsed:           %10d (cycles)     %10d (us)\n",
270         timeElapsed, CYCLES_TO_US(timeElapsed, cpuFreq.lo));
273 /**
274  *  @b Description
275  *  @n  
276  *      This function initalizes the platform.  It has called at startup.  This is defined in the
277  *      .cfg file via the Startup.firstFxns.$add('&initPlatform'); definition.
278  */
279 void initPlatform(void)
281   platform_init_flags  pFormFlags;
282   platform_init_config pFormConfig;
283   /* Status of the call to initialize the platform */
284   UInt32 pFormStatus;
286   /* Only run on single core */
287   if (CSL_chipReadReg (CSL_CHIP_DNUM) == 0)
288   {
289     /*
290      * You can choose what to initialize on the platform by setting the following
291      * flags. Things like the DDR, PLL, etc should have been set by the boot loader.
292     */
293     memset( (void *) &pFormFlags,  0, sizeof(platform_init_flags));
294     memset( (void *) &pFormConfig, 0, sizeof(platform_init_config));
296     pFormFlags.pll = 0; /* PLLs for clocking    */
297     pFormFlags.ddr  = 0; /* External memory             */
298     pFormFlags.tcsl = 1; /* Time stamp counter  */
299     pFormFlags.phy  = 0; /* Ethernet                    */
300     pFormFlags.ecc  = 0; /* Memory ECC                  */
302     pFormConfig.pllm = 0;       /* Use libraries default clock divisor */
303     pFormStatus = platform_init(&pFormFlags, &pFormConfig);
305     /* If we initialized the platform okay */
306     if (pFormStatus != Platform_EOK)
307     {
308          /* Initialization of the platform failed. */
309          System_printf("Platform failed to initialize. Error code %d \n", pFormStatus);
310     }
311   }
314 /**
315  *  @b Description
316  *  @n  
317  *      This functions measures latency by sending a message from core0 to core1. 
318  *      Core1 relays all received messages back to core 2.  Core0 will measure the roundtrip latency.
319  */
320 static void measure_latency()
322     Int              status;
323     UInt numReceived;
324     MessageQ_Msg     msg;
326     System_printf("tsk0. selfproc=%d nextQueueName (%s) openned, nextQueueId=%d\n", CSL_chipReadReg (CSL_CHIP_DNUM), nextQueueName, nextQueueId);
328     if (selfId == 0) {
329         msg = MessageQ_alloc(HEAP_ID, MESSAGE_SIZE_IN_BYTES);
330         if (msg == NULL) {
331            System_abort("MessageQ_alloc failed\n");
332         }
334         System_printf("tsk0. selfProc=%d calling MessageQ_put(nextQueueName=%s). msg=0x%x\n", CSL_chipReadReg (CSL_CHIP_DNUM), nextQueueName, msg);
335         /* Kick off the loop */
336         status = MessageQ_put(nextQueueId, msg);
337         if (status < 0) {
338             System_abort("MessageQ_put failed\n");
339         }
340     }
342     for (numReceived = 0; numReceived < NUMLOOPS; numReceived++) {
343     //while (1) {
344         /* Get a message */
345         status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
346         if (status < 0) {
347             System_abort("MessageQ_get failed\n");
348         }
350         if (selfId == 0) {
351             rawtimestamps[numReceived] = Timestamp_get32();
353             if (numReceived == NUMLOOPS - 1) {
354                 printStatistics();
356                 // free the Message.
357                 MessageQ_free(msg);
358                 break;
359             }
360         }
362         status = MessageQ_put(nextQueueId, msg);
363         if (status < 0) {
364             System_abort("MessageQ_put failed\n");
365         }
366     }
369 /**
370  *  @b Description
371  *  @n  
372  *      This functions allocate all messages to be sent up front on core0.  Synchronize core 0 and core1.
373  *      Core 0 sends all messages to Core1 in a burst.  Core 1 receives all the messages 
374  *      and measure the throughput over the time it took to send all the messages.
375  */
376 static void thruputTxRxPairPreallocFullLoad(void)
377
378   /* Source to be executed on Core 0 */
379   if (selfId == 0)
380   {
381     Int16 receiveCores[2] = {1, CORE_SYNC_NULL_CORE};  /* Last entry must be CORE_SYNC_NULL_CORE */
382     UInt32 numTxMsgs =  (NUM_MSGS_TO_PREALLOC-1); /* First message used to synchronize cores */
383     Int status;
384 #if VERBOSE_MODE    
385     UInt32 numSends = 0;
386 #endif
388     System_printf("\nThroughput via upfront allocation: Allocate all messages up front, sync cores, send all messages from core 0 to core 1\n");
390     status = allocateMessages(NUM_MSGS_TO_PREALLOC, HEAP_ID, &txMsgPtrs[0]);
391     if (status != 0)
392     {
393       System_printf("Message Preallocation failed for core %d after allocating %d messages.\n", selfId, status);
394       detachAll(MultiProc_getNumProcessors());
395       System_exit(0);
396     }
398     /* simplified for now since only one core */
399     syncSendCore (&receiveCores[0], messageQ, &nextQueueId, &txMsgPtrs[0], TRUE);
401     /* Send all messages to core 1.  The last message sent will have a flag signifying to core 1 that
402       * all messages have been sent.  Start with second message in the txMsgPtrs array because the 
403       * first was used (and freed by the transport) for the syncSendCore. */
404 #if VERBOSE_MODE
405     numSends = sendMessages(1, &numTxMsgs, &nextQueueId, &txMsgPtrs[1]);
406     System_printf ("Core %d: Sent a total of %d messages.\n", selfId, numSends);
407 #else
408     sendMessages(1, &numTxMsgs, &nextQueueId, &txMsgPtrs[1]);
409 #endif
410   }
412   /* Source to be executed on Core 1 */
413   if (selfId == 1)
414   {
415     Int16 sendCores[2] = {0, CORE_SYNC_NULL_CORE};  /* Last entry must be CORE_SYNC_NULL_CORE */
416     UInt32 numReceived = 0;
417     UInt32 delay = 0;
418     Int status;
419     UInt64 timeStamp;
421 #if VERBOSE_MODE
422     System_printf("Core %d: Per message work delay is %dus\n", selfId, delay);
423 #endif
425     /* Synchronize cores prior to starting test */
426     syncReceiveCore (&sendCores[0], messageQ, &nextQueueId);
428     /* Take time at start of test */
429     timeStamp = getStartTime64();
431     numReceived = receiveMessages(&sendCores[0], messageQ, &rxMsgPtrs[0], delay);
433     /* Get execution time to transfer all messages */
434     timeLength = getExecutionTime64(timeStamp, timeAdj);
436 #if VERBOSE_MODE
437     System_printf("Core %d: Received a total of %d messages.\n", selfId, numReceived);
438 #endif
440     /* Calculate throughput over all messages */
441     calculateThroughput (numReceived, timeLength, cpuFreq);
443     /* Free the messages received */
444     status = freeMessages(numReceived, &rxMsgPtrs[0]);
445     if (status < 0)
446     {
447       System_printf("Message free failed for Core %d\n", selfId);
448     }
449   }
452 /**
453  *  @b Description
454  *  @n  
455  *      This configures the descriptor region and initializes CPPI, QMSS, and SRIO.
456  *      This function should only be called once per chip.
457  *
458  *  @retval
459  *      Success     - 0
460  *  @retval
461  *      Error       - <0
462  */
463 Int32 systemInit (Void)
465   Cppi_InitCfg cppiHeapInit;  /* Static CPPI heap */
466   Qmss_InitCfg qmssInitConfig;   /* QMSS configuration */
467   Qmss_MemRegInfo memInfo; /* Memory region configuration information */
468   Qmss_Result result;
469   UInt32 coreNum;
470   
471   coreNum = CSL_chipReadReg (CSL_CHIP_DNUM);
473   System_printf ("\n-----------------------Initializing---------------------------\n");
474   
475   System_printf ("Core %d : L1D cache size %d. L2 cache size %d.\n", coreNum, CACHE_getL1DSize(), CACHE_getL2Size());
477   memset ((Void *) &qmssInitConfig, 0, sizeof (Qmss_InitCfg));
478   
479   /* Set up the linking RAM. Use the internal Linking RAM. 
480    * LLD will configure the internal linking RAM address and maximum internal linking RAM size if 
481    * a value of zero is specified.
482    * Linking RAM1 is not used */
483   qmssInitConfig.linkingRAM0Base = 0;
484   qmssInitConfig.linkingRAM0Size = 0;
485   qmssInitConfig.linkingRAM1Base = 0;
486   qmssInitConfig.maxDescNum      = NUM_HOST_DESC /* total of other descriptors here */;
489 #ifdef xdc_target__bigEndian
490   qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
491   qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_be;
492   qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
493 #else
494   qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
495   qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_le;
496   qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
497 #endif
499   /* Initialize Queue Manager SubSystem */
500   result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams);
501   if (result != QMSS_SOK)
502   {
503       System_printf ("Error Core %d : Initializing Queue Manager SubSystem error code : %d\n", coreNum, result);
504       return -1;
505   }
507   /* Start the QMSS. */
508   if (Qmss_start() != QMSS_SOK)
509   {
510       System_printf ("Error: Unable to start the QMSS\n");
511       return -1;
512   }
514   cppiHeapInit.heapParams.staticHeapBase = &cppiHeap[0];
515   cppiHeapInit.heapParams.staticHeapSize = SIZE_CPPI_HEAP;
516   cppiHeapInit.heapParams.heapAlignPow2 = 7; /* Power of 7 (128 byte) */
517   cppiHeapInit.heapParams.dynamicHeapBlockSize = -1; /* Shut off malloc if block runs out */
518   result = Cppi_initCfg (&cppiGblCfgParams, &cppiHeapInit);
519   if (result != CPPI_SOK)
520   {
521       System_printf ("Error Core %d : Initializing CPPI LLD error code : %d\n", coreNum, result);
522   }
524   System_printf ("address of hostDesc[] = 0x%x. Converted=0x%x\n", hostDesc, l2_global_address ((UInt32) hostDesc));
526   /* Setup memory region for host descriptors */
527   memset ((Void *) &hostDesc, 0, SIZE_HOST_DESC * NUM_HOST_DESC);
528   memInfo.descBase       = (UInt32 *) hostDesc; /* descriptor pool is in MSMC */
529   memInfo.descSize       = SIZE_HOST_DESC;
530   memInfo.descNum        = NUM_HOST_DESC;
531   memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
532   memInfo.memRegion      = (Qmss_MemRegion) descriptorMemRegion;
533   memInfo.startIndex     = 0;
535   result = Qmss_insertMemoryRegion (&memInfo);
536   if (result < QMSS_SOK)
537   {
538       System_printf ("Error Core %d : Inserting memory region %d error code : %d\n", coreNum, memInfo.memRegion, result);
539       return -1;
540   }
541   else
542   {
543       System_printf ("Core %d : Memory region %d inserted\n", coreNum, result);
544   }
546   /* Writeback the descriptor pool.  Writeback all data cache.
547     * Wait until operation is complete. */    
548   Cache_wb (hostDesc, 
549                      SIZE_HOST_DESC * NUM_HOST_DESC,
550                      Cache_Type_ALLD, TRUE);
551   
552   return 0;
555 /**
556  *  @b Description
557  *  @n  
558  *      Task which kicks off the latency and throughput tests
559  */
560 Void tsk0(UArg arg0, UArg arg1)
562     Int status;
563     HeapBufMP_Handle              heapHandle;
564     HeapBufMP_Params              heapBufParams;
566     System_printf("tsk0 starting\n");
568     if (selfId == 0)
569     {      
570       /* Create the heap that will be used to allocate messages. */     
571       HeapBufMP_Params_init(&heapBufParams);
572       heapBufParams.regionId       = 0;
573       heapBufParams.name           = HEAP_NAME;
574       heapBufParams.numBlocks      = NUM_HOST_DESC;
575       heapBufParams.blockSize      = SRIO_MTU_SIZE;
576       heapHandle = HeapBufMP_create(&heapBufParams);
577       if (heapHandle == NULL) 
578       {
579         System_abort("HeapBufMP_create failed\n" );
580       }
581     }
582     else
583     {
584       /* Open the heap created by the other processor. Loop until opened. */
585       do 
586       {
587         status = HeapBufMP_open(HEAP_NAME, &heapHandle);
588       } while (status < 0);
589     }
591     /* Register this heap with MessageQ */
592     MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAP_ID);
594     /* Open the 'next' remote message queue. Spin until it is ready. */
595     do {
596         status = MessageQ_open(nextQueueName, &nextQueueId);
597     }
598     while (status < 0);
600     measure_latency();
602     thruputTxRxPairPreallocFullLoad();
604     detachAll(MultiProc_getNumProcessors());
605     System_exit(0);
608 /**
609  *  @b Description
610  *  @n  
611  *      Main - Initialize the system and start BIOS
612  */
613 Int main(Int argc, Char* argv[])
615   Int32 result = 0;
616   Types_Timestamp64 time64;
617   UInt64 timeStamp;
619   Timestamp_getFreq(&timerFreq);
620   System_printf("timerFreq.lo = %d. timerFreq.hi = %d\n", timerFreq.lo, timerFreq.hi);
622   BIOS_getCpuFreq(&cpuFreq);
623   System_printf("cpuFreq.lo = %d. cpuFreq.hi = %d\n", cpuFreq.lo, cpuFreq.hi);
624   
625   cpuTimerFreqRatio = (Float)cpuFreq.lo / (Float)timerFreq.lo;
627   Timestamp_get64(&time64);
628   timeStamp = TIMESTAMP64_TO_UINT64(time64.hi,time64.lo);
629   timeAdj = TIMESTAMP64_TO_UINT64(time64.hi,time64.lo) - timeStamp;
631   selfId = CSL_chipReadReg (CSL_CHIP_DNUM);
632   
633   System_printf("Core (\"%s\") starting\n", MultiProc_getName(selfId));
634   
635   if (numCores == 0) {
636       numCores = MultiProc_getNumProcessors();
637   }
639   /* System initializations for each core. */
640   if (selfId == 0) 
641   {
642     /* SRIO, QMSS, and CPPI system wide initializations are run on
643       * this core */
644          result = systemInit();
645          if (result != 0)
646     {
647       System_printf("Error (%d) while initializing QMSS\n", result);
648       return (0);
649          }
651     /* Power on SRIO peripheral before using it */
652     if (enable_srio () < 0)
653     {
654         System_printf ("Error: SRIO PSC Initialization Failed\n");
655         return (0);
656     }
657     
658     /* Device Specific SRIO Initializations: This should always be called before
659       * initializing the SRIO Driver. */
660         if (SrioDevice_init() < 0)
661         return (0);        
663     /* Initialize the SRIO Driver */
664     if (Srio_init () < 0)
665     {
666         System_printf ("Error: SRIO Driver Initialization Failed\n");
667         return (0);
668     }
670         /* SRIO Driver is operational at this time. */
671     System_printf ("Debug(Core %d): SRIO Driver has been initialized\n", selfId);
673     /* Write to the SHARED memory location at this point in time. The other cores cannot execute
674       * till the SRIO Driver is up and running. */
675     isSRIOInitialized = 1;
677     /* The SRIO IP block has been initialized. We need to writeback the cache here because it will
678       * ensure that the rest of the cores which are waiting for SRIO to be initialized would now be
679       * woken up. */
680     Cache_wb ((void *) &isSRIOInitialized, 4, Cache_Type_L1D, TRUE);
681   }
682   else
683   {
684     /* System initialization performed on another core.  Only need to start QMSS for this core */
685     System_printf ("Debug(Core %d): Waiting for SRIO to be initialized.\n", selfId);
686   
687     /* All other cores loop around forever till the SRIO is up and running. 
688      * We need to invalidate the cache so that we always read this from the memory. */
689     while (isSRIOInitialized == 0)
690         Cache_inv ((void *) &isSRIOInitialized, 4, Cache_Type_L1D, TRUE);
691   
692     /* Start the QMSS. */
693     if (Qmss_start() != QMSS_SOK)
694     {
695         System_printf ("Error: Unable to start the QMSS\n");
696         return (0);
697     }
698   
699     System_printf ("Debug(Core %d): SRIO can now be used.\n", selfId);
700   }
702   /* Each core must initialize memory used for the packet descriptor buffers within SRIO */
703   if (Osal_dataBufferInitMemory(SRIO_MTU_SIZE) < 0)
704   {
705     System_printf("Core: %d ERROR: SRIO memory initialization failed\n", selfId);
706     return (0);
707   }
709   /* calling IPC attach. After this attach, QMSS is started and also the descriptor pool is also init'ed */
710   attachAll(numCores);
711      
712   prevCoreId = (selfId - 1 + numCores) % numCores;    
713   
714   System_sprintf(localQueueName, "CORE%d", selfId);
715   System_sprintf(nextQueueName, "CORE%d", 
716       ((selfId + 1) % numCores));
717   System_sprintf(prevQueueName, "CORE%d", prevCoreId);
719   System_printf("localQueueName=%s. nextQueueName=%s. prevQueueName=%s\n", 
720                   localQueueName,  nextQueueName, prevQueueName);
721         
722   /* Create a message queue. */
723   messageQ = MessageQ_create(localQueueName, NULL);    
724   if (messageQ == NULL) {
725       System_abort("MessageQ_create failed\n" );
726   }
728   BIOS_start();
730   System_printf("done BIOS_start\n", result);
732   return (0);