Bug fixes, cleanup, expanded test code
[keystone-rtos/rm-lld.git] / test / rm_test.c
1 /* 
2  * Copyright (c) 2012, 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  * */
32 /*
33  *  ======== rm_test.c ========
34  *  RM multicore test example
35  *
36  *  This is an example program that uses MessageQ to pass a message
37  *  from one processor to another.
38  *
39  *  Each processor creates its own MessageQ first and then will try to open
40  *  a remote processor's MessageQ.  
41  *
42  *  See message_multicore.k file for expected output.
43  */
45 #include <c6x.h>
46 #include <xdc/std.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <stdbool.h>
51 /*  -----------------------------------XDC.RUNTIME module Headers    */
52 #include <xdc/runtime/System.h>
53 #include <xdc/runtime/IHeap.h>
55 /*  ----------------------------------- IPC module Headers           */
56 #include <ti/ipc/Ipc.h>
57 #include <ti/ipc/MessageQ.h>
58 #include <ti/ipc/HeapBufMP.h>
59 #include <ti/ipc/MultiProc.h>
61 /*  ----------------------------------- BIOS6 module Headers         */
62 #include <ti/sysbios/BIOS.h>
63 #include <ti/sysbios/knl/Task.h>
65 /*  ----------------------------------- Resource Manager Headers         */
66 #include <ti/drv/rm/rm.h>
67 #include <ti/drv/rm/rm_osal.h>
68 #include <ti/drv/rm/rm_transport.h>
69 #include <ti/drv/rm/rm_services.h>
71 /* ======== Task Handles ======== */
72 Task_Handle startupRmTskHandle;
73 Task_Handle testReceiveTskHandle;
74 Task_Handle testRmTskHandle;
76 /* ======== Application Heaps ======== */
77 #define RM_PKT_HEAP_NAME   "rmHeapBuf"
78 HeapBufMP_Handle rmPktHeapHandle = NULL;
80 #define MSGQ_HEAP_NAME   "msgQHeapBuf"
81 #define MSGQ_HEAP_ID      0
83 /* ======== RM Instance Names ======== */
84 Char rmServerName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Server";
85 Char rmClientDelegateName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client_Delegate";
86 Char rmClientName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client";
88 /* ======== RM IPC MessageQ Names ======== */
89 Char serverCdQueueName[30] = "RM_Server_CD_Queue";
90 Char cdServerQueueName[30] = "RM_CD_Server_Queue";
91 Char cdClientQueueName[30] = "RM_CD_Client_Queue";
92 Char clientCdQueueName[30] = "RM_Client_CD_Queue";
94 /* ======== RM Instance Handles ======== */
95 Rm_Handle rmServerHandle = NULL;
96 Rm_Handle rmClientDelegateHandle = NULL;
97 Rm_Handle rmClientHandle = NULL;
99 /* ======== RM Instance Service Ports ======== */
100 Rm_ServicePort *rmServerServicePort = NULL;
101 Rm_ServicePort *rmClientDelegateServicePort = NULL;
102 Rm_ServicePort *rmClientServicePort = NULL;
104 /* ======== RM Transport Packet Definition ======== */
105 typedef struct {
106   MessageQ_MsgHeader msgQHeader;
107   /* Pointer to packet provided by RM */
108   Rm_Packet *rmPkt;
109 } MsgQ_RmPacket;
111 /* ======== RM Transport Mapping Tables for Application ======== */
112 /* Core 0 Map Entry Indices */
113 #define SERVER_TO_CD_MAP_ENTRY 0
114 /* Core 1 Map Entry Indicies */
115 #define CD_TO_SERVER_MAP_ENTRY 0
116 #define CD_TO_CLIENT_MAP_ENTRY 1
117 #define CLIENT_TO_CD_MAP_ENTRY 2
119 /* Max map entries across all cores */
120 #define MAX_MAPPING_ENTRIES 3
122 typedef struct {
123     Rm_TransportHandle transportHandle;
124     MessageQ_Handle receiveMsgQ;
125     MessageQ_QueueId remoteMsgQId;
126 } Transport_MapEntry;
128 /* Core 1 will have three mapping entries
129  * Two map entries for the Client Delegate
130  * One map entry for the Client */
131 Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES];
133 uint32_t waitForBlockingOperation = 0;
134 Rm_ServiceRespInfo responseInfo;
136 /* ======== RM Application Sync APIs ======== */
138 typedef struct {
139     uint32_t sem;
140     uint32_t pad[31];
141 } syncObj;
143 #pragma DATA_SECTION (testSyncObj, ".syncObj");
144 #pragma DATA_ALIGN (testSyncObj, 16)
145 syncObj testSyncObj;
147 void initSyncObj(void)
149     Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));    
150     testSyncObj.sem = 0;
151     Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
154 void takeSyncObj(void)
156     Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));    
157     testSyncObj.sem = 1;
158     Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
161 void waitOnSyncObj(void)
163     do
164     {
165         /* Yield for other tasks */
166         Task_yield();
167         Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));    
168     } while (testSyncObj.sem == 1);
171 void releaseSyncObj(void)
173     Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));    
174     testSyncObj.sem = 0;
175     Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
178 /* ======== RM Application Transport APIs ======== */
180 Rm_Packet *TransportAlloc (Rm_TransportHandle transportHandle, uint32_t pktSize)
182     Rm_Packet *pkt = NULL;
184     /* All transports will allocate from the same heap */
185     
186     pkt = HeapBufMP_alloc(rmPktHeapHandle, pktSize, 0);
188     if (pkt != NULL)
189     {
190        pkt->pktLenBytes = pktSize;
191     }
193     return (pkt);
196 int32_t TransportFree (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
198     uint32_t pktSize = pkt->pktLenBytes;
200     /* All transports will free to the same heap */
201     
202     HeapBufMP_free(rmPktHeapHandle, pkt, pktSize);
204     return (0);    
207 int32_t TransportSend (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
209     MsgQ_RmPacket *rmMsg = NULL;
210     MessageQ_QueueId remoteQueueId;
211     bool handleValid = false;
212     int32_t status, i;    
214     /* Get the remoteQueueId based on the transportHandle */
215     for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
216     {
217         /* transportHandle found in mapping table.  Get the remoteQueueId associated
218          * with it */
219         if (rmTransportMap[i].transportHandle == transportHandle)
220         {
221             remoteQueueId = rmTransportMap[i].remoteMsgQId;
222             /* Break out of the search loop */
223             handleValid = true;
224             break;
225         }
226     }
228     if (handleValid)
229     {
230         /* Allocate a messageQ message for containing the RM packet */
231         rmMsg = (MsgQ_RmPacket *)MessageQ_alloc(MSGQ_HEAP_ID, sizeof(MsgQ_RmPacket));
232         if (rmMsg == NULL) 
233         {
234             System_printf("Core %d: MessageQ_alloc failed in TransportSend\n", MultiProc_self());
235         }
237         /* Attach the RM packet to the MessageQ message */
238         Rm_osalEndMemAccess((void *) pkt, pkt->pktLenBytes);
239         rmMsg->rmPkt = pkt;
240         /* Send the message to the remote side */
241         status = MessageQ_put(remoteQueueId, (MessageQ_Msg)rmMsg);
242         if (status < 0) 
243         { 
244             System_printf("Core %d: MessageQ_put had a failure/error in TransportSend\n", MultiProc_self());
245         }
246     }
247     else
248     {   
249         /* Could not find a registered transport handle that matched the handle provided by RM.
250          * Return an error to RM. */
251         System_printf("Core %d: TransportSend couldn't find transportHandle in transport map\n", MultiProc_self());
252         status = -1;
253     }
254     
255     return (status);
258 void *TransportReceive (Rm_TransportHandle transportHandle)
260     MessageQ_Handle receiveQ;
261     MessageQ_Msg rmMsg = NULL;
262     Rm_Packet *rmPkt = NULL;
263     bool queueValid = false;
264     int32_t status, i;    
266     /* Get the receiveQ based on the transportHandle */
267     for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
268     {
269         /* transportHandle found in mapping table.  Get the receiveQ associated
270          * with it */
271         if (rmTransportMap[i].transportHandle == transportHandle)
272         {
273             receiveQ = rmTransportMap[i].receiveMsgQ;
274             /* Break out of the search loop */
275             queueValid = true;
276             break;
277         }
278     }
280     if (queueValid)
281     {
282         /* Get the next message from the receiveQ */
283         status = (int32_t) MessageQ_get(receiveQ, &rmMsg, MessageQ_FOREVER);
284         if (status < 0) 
285         {
286             System_abort("This should not happen since timeout is forever\n");
287         }
288         if (rmMsg == NULL) 
289         {
290             System_printf("Core %d: MessageQ_get failed returning a null packet in TransportReceive\n", MultiProc_self());
291         }
293         /* Extract the Rm_Packet from the RM msg */
294         rmPkt = ((MsgQ_RmPacket *)rmMsg)->rmPkt;
295         Rm_osalBeginMemAccess((void *) rmPkt, rmPkt->pktLenBytes); 
297         /* Free the messageQ message now that RM packet pointer has been extracted */
298         status = MessageQ_free(rmMsg);
299         if (status < 0) 
300         { 
301             System_printf("Core %d: MessageQ_free had a failure/error in TransportReceive\n", MultiProc_self());
302         }
303     }
304     else
305     {   
306         /* Could not find a registered transport handle that matched the handle provided by RM.
307          * Return an error to RM. */
308         System_printf("Core %d: TransportReceive couldn't find transportHandle in transport map\n", MultiProc_self());
309     }
311     /* Pass the RM packet back to RM */
312     return ((void *)rmPkt);
315 int32_t TransportNumPktsReceived (Rm_TransportHandle transportHandle)
317     MessageQ_Handle receiveQ;
318     bool queueValid = false;
319     int32_t numPkts, i;    
321     /* Get the receiveQ based on the transportHandle */
322     for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
323     {
324         /* transportHandle found in mapping table.  Get the receiveQ associated
325          * with it */
326         if (rmTransportMap[i].transportHandle == transportHandle)
327         {
328             receiveQ = rmTransportMap[i].receiveMsgQ;
329             /* Break out of the search loop */
330             queueValid = true;
331             break;
332         }
333     }
335     if (queueValid)
336     {
337         /* Get the number of messages in the receiveQ */
338         numPkts = (int32_t) MessageQ_count(receiveQ);
339     }
340     else
341     {   
342         /* Could not find a registered transport handle that matched the handle provided by RM.
343          * Return an error to RM. */
344         System_printf("Core %d: TransportNumPktsReceived couldn't find transportHandle in transport map\n", MultiProc_self());
345         numPkts = -1;
346     }
347     
348     return (numPkts);
351 /*
352  *  ======== testServiceCallback ========
353  *  Application's callback function given to RM on service requests
354  */
355 void testServiceCallback(Rm_ServiceRespInfo *serviceResponse)
357     if (serviceResponse->serviceId == waitForBlockingOperation)
358     {
359         waitForBlockingOperation = 0;
360         responseInfo.resourceBase = serviceResponse->resourceBase;
361         responseInfo.resourceLength = serviceResponse->resourceLength;
362         responseInfo.serviceState = serviceResponse->serviceState;
363     }
366 bool blockForResponse(Rm_ServiceRespInfo *respInfo)
368     waitForBlockingOperation = respInfo->serviceId;
369     /* Block and wait for the response if the RM needed to perform a blocking operation
370      * to complete the request */
371     while(waitForBlockingOperation)
372     {
373         /* Yield to receive task to see if there are any packets for RM instance */
374         Task_yield();
375     }       
377     if ((respInfo->serviceState != RM_SERVICE_PROCESSING) &&
378         (respInfo->serviceState != RM_SERVICE_APPROVED_AND_COMPLETED))
379     {
380         System_printf("Core %d: Service request encountered error or denial: %d\n", MultiProc_self(),
381                                                                                     respInfo->serviceState);
382         return(FALSE);
383     }
385     return(TRUE);
388 /*
389  *  ======== testRmTsk ========
390  *  RM cleanup task
391  */
392 void cleanupRmTsk(UArg arg0, UArg arg1)
394     /* Delete the RM test task */
395     System_printf("Core %d: Deleting RM test task...\n", MultiProc_self());
396     if (testRmTskHandle)
397     {
398         Task_delete(&testRmTskHandle);
399         /* Set the task handle to be NULL so that the delete only occurs once */
400         testRmTskHandle = NULL;
401     }
402     /* Delete the RM receive task */
403     System_printf("Core %d: Deleting RM receive task...\n", MultiProc_self());
404     if (testReceiveTskHandle)
405     {
406         Task_delete(&testReceiveTskHandle);
407         /* Set the task handle to be NULL so that the delete only occurs once */
408         testReceiveTskHandle = NULL;
409     }
411     
413     /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */
415     BIOS_exit(0);
418 /*
419  *  ======== testRmTsk ========
420  *  RM test task
421  */
422 void testReceiveTsk(UArg arg0, UArg arg1)
424     int32_t retVal;
426     while(1)
427     {
429         /* Run the RM polling functions for each RM instance. */
430         if (MultiProc_self() == 0)
431         {
432             retVal = Rm_receivePktPolling(rmTransportMap[SERVER_TO_CD_MAP_ENTRY].transportHandle);
433             if (retVal != RM_TRANSPORT_SUCCESSFUL)
434             {
435                 System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), 
436                                                                                 rmServerName,
437                                                                                 rmClientDelegateName,
438                                                                                 retVal);
439             }
440         }
441         else if (MultiProc_self() == 1)
442         {
443             retVal = Rm_receivePktPolling(rmTransportMap[CD_TO_SERVER_MAP_ENTRY].transportHandle);
444             if (retVal != RM_TRANSPORT_SUCCESSFUL)
445             {
446                 System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), 
447                                                                                 rmClientDelegateName,
448                                                                                 rmServerName,
449                                                                                 retVal);
450             }
452             retVal = Rm_receivePktPolling(rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].transportHandle);
453             if (retVal != RM_TRANSPORT_SUCCESSFUL)
454             {
455                 System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(),
456                                                                                 rmClientDelegateName,
457                                                                                 rmClientName,
458                                                                                 retVal);
459             }
461             retVal = Rm_receivePktPolling(rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].transportHandle);
462             if (retVal != RM_TRANSPORT_SUCCESSFUL)
463             {
464                 System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), 
465                                                                                 rmClientName,
466                                                                                 rmClientDelegateName,
467                                                                                 retVal);
468             }
469         }
471         /* Yield for main test task */
472         Task_yield();
473     }
476 /*
477  *  ======== testRmTsk ========
478  *  RM test task
479  */
480 void testRmTsk(UArg arg0, UArg arg1)
482     Rm_ServiceReqInfo requestInfo;
483     Task_Params taskParams;    
484        
485     /* Delete the RM startup task */
486     System_printf("Core %d: Deleting RM startup task...\n", MultiProc_self());
487     if (startupRmTskHandle)
488     {
489         Task_delete(&startupRmTskHandle);
490         /* Set the task handle to be NULL so that the delete only occurs once */
491         startupRmTskHandle = NULL;
492     }
494     /* Open service ports on all the RM instances to test service requests from the different
495      * RM instances */
496     if (MultiProc_self() == 0)
497     {
498         rmServerServicePort = Rm_getServicePort(rmServerHandle);
499     }
500     else if (MultiProc_self() == 1)
501     {
502         rmClientDelegateServicePort = Rm_getServicePort(rmClientDelegateHandle);
503         rmClientServicePort = Rm_getServicePort(rmClientHandle);
504     }
506     memset((void *)&requestInfo, 0, sizeof(Rm_ServiceReqInfo));
507     memset((void *)&responseInfo, 0, sizeof(Rm_ServiceRespInfo));
509     System_printf("Core %d: Testing NameServer features...\n", MultiProc_self());
511     /* Use the service ports to test the service requests */
512     if (MultiProc_self() == 0)
513     {
514         char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "gp-queue";
515         char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "My_Favorite_Queue";
517         /* Issue the service request create a new NameServer object via the service port */                
518         requestInfo.type = Rm_service_RESOURCE_MAP_TO_NAME;
519         requestInfo.resourceName = resourceName;
520         requestInfo.resourceBase = 1002;
521         requestInfo.resourceLength = 1;
522         requestInfo.resourceNsName = resourceNsName;
523         requestInfo.callback.serviceCallback = testServiceCallback;
524         
525         System_printf("Core %d: %s creating NameServer object...\n", MultiProc_self(), rmServerName);
526         rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
527         if (blockForResponse(&responseInfo))
528         {
529             System_printf("Core %d: %s created Name: %s base: %d length: %d\n", MultiProc_self(),
530                                                                                 rmServerName,
531                                                                                 resourceNsName, 
532                                                                                 requestInfo.resourceBase,
533                                                                                 requestInfo.resourceLength);            
534         }
536         /* Wait for Client Delegate and Client to retrieve resource via the name and allocate it */
537         waitOnSyncObj();
539         Rm_printResourceStatus(rmServerHandle);
540         
541     }
542     else if (MultiProc_self() == 1)
543     {    
544         char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "gp-queue";
545         char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "My_Favorite_Queue";
547         /* Take the sync obj preparing for NameServer testing */
548         takeSyncObj();    
550         /* Issue the service request for the resources tied to the name via the service port */                
551         requestInfo.type = Rm_service_RESOURCE_GET_BY_NAME;
552         requestInfo.resourceNsName = &resourceNsName[0];
553         requestInfo.callback.serviceCallback = testServiceCallback;
554         
555         System_printf("Core %d: %s getting NameServer object...\n", MultiProc_self(), rmClientDelegateName);
556         rmClientDelegateServicePort->rmService(rmClientDelegateServicePort->rmHandle, &requestInfo, &responseInfo);
557         if (blockForResponse(&responseInfo))
558         {
559             System_printf("Core %d: %s got Name: %s base: %d length: %d\n", MultiProc_self(),
560                                                                             rmClientDelegateName, 
561                                                                             resourceNsName, 
562                                                                             responseInfo.resourceBase,
563                                                                             responseInfo.resourceLength);
564         }
566         /* Allocate the resources via the service port from the Client */
567         requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
568         requestInfo.resourceName = resourceName;
569         requestInfo.resourceBase = responseInfo.resourceBase;
570         requestInfo.resourceLength = responseInfo.resourceLength;
571         requestInfo.resourceNsName = NULL;
572         requestInfo.callback.serviceCallback = testServiceCallback;
573         
574         System_printf("Core %d: %s allocating resources...\n", MultiProc_self(), rmClientName);
575         rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo);
576         if (blockForResponse(&responseInfo))
577         {
578             System_printf("Core %d: %s allocated resources: %s base: %d length: %d\n", MultiProc_self(),
579                                                                                        rmClientName, 
580                                                                                        resourceNsName, 
581                                                                                        responseInfo.resourceBase,
582                                                                                        responseInfo.resourceLength);
583         }
585         /* Release the syncObj so Server can move forward with NameServer object testing */
586         releaseSyncObj();        
587     }
589     System_printf("Core %d: Testing is complete\n", MultiProc_self());
590     
591     /* Create the RM cleanup task. */
592     System_printf("Core %d: Creating RM cleanup task...\n", MultiProc_self());
593     Task_Params_init (&taskParams);
594     Task_create (cleanupRmTsk, &taskParams, NULL);
597 /*
598  *  ======== startupRmTsk ========
599  *  Configures application transports and registers them with RM
600  */
601 Void startupRmTsk(UArg arg0, UArg arg1)
603     MessageQ_Handle  serverCdMsgQ, cdServerMsgQ, cdClientMsgQ, clientCdMsgQ;
604     MessageQ_QueueId serverCdQId, cdServerQId, cdClientQId, clientCdQId;    
605     Int              status, i;
606     HeapBufMP_Handle msgQHeapHandle;
607     HeapBufMP_Params heapBufParams;
608     Rm_TransportCfg rmTransportCfg;
609     Rm_TransportHandle serverCdHandle, cdServerHandle, cdClientHandle, clientCdHandle;
610     Task_Params taskParams;
612     /* Initialize the transport map */
613     for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
614     {
615         rmTransportMap[i].transportHandle = NULL;
616     }
618     if (MultiProc_self() == 0)
619     {
620         /* Create the heap that will be used to allocate RM messages. This
621          * heap is a multi-processor heap.  It will be shared amongst
622          * all RM instances. */     
623         HeapBufMP_Params_init(&heapBufParams);
624         heapBufParams.regionId       = 0;
625         heapBufParams.name           = RM_PKT_HEAP_NAME;
626         heapBufParams.numBlocks      = 64;
627         heapBufParams.blockSize      = sizeof(Rm_Packet);
628         rmPktHeapHandle = HeapBufMP_create(&heapBufParams);
629         if (rmPktHeapHandle == NULL) 
630         {
631             System_abort("HeapBufMP_create failed for RM packet heap\n" );
632         }
633         System_printf("Core %d: RM packet heap created\n", MultiProc_self());
635         /* Create the heap that will be used to allocate messageQ messages. */     
636         HeapBufMP_Params_init(&heapBufParams);
637         heapBufParams.regionId       = 0;
638         heapBufParams.name           = MSGQ_HEAP_NAME;
639         heapBufParams.numBlocks      = 64;
640         heapBufParams.blockSize      = sizeof(MsgQ_RmPacket);
641         msgQHeapHandle = HeapBufMP_create(&heapBufParams);
642         if (msgQHeapHandle == NULL) 
643         {
644             System_abort("HeapBufMP_create failed MessageQ message heap\n" );
645         } 
646         System_printf("Core %d: IPC MessageQ message heap created\n", MultiProc_self());
647     }
648     else 
649     {
650         /* Open the heaps created by the other processor. Loop until opened. */
651         do 
652         {
653             status = HeapBufMP_open(RM_PKT_HEAP_NAME, &rmPktHeapHandle);
654             /* 
655              *  Sleep for 1 clock tick to avoid inundating remote processor
656              *  with interrupts if open failed
657              */
658             if (status < 0)
659             { 
660                 Task_sleep(1);
661             }
662         } while (status < 0);
663         System_printf("Core %d: RM packet heap opened\n", MultiProc_self());
664         
665         do 
666         {
667             status = HeapBufMP_open(MSGQ_HEAP_NAME, &msgQHeapHandle);
668             /* 
669              *  Sleep for 1 clock tick to avoid inundating remote processor
670              *  with interrupts if open failed
671              */
672             if (status < 0)
673             { 
674                 Task_sleep(1);
675             }
676         } while (status < 0);
677         System_printf("Core %d: IPC MessageQ message heap opened\n", MultiProc_self());
678     }
679     
680     /* Register the MessageQ heap with MessageQ */
681     MessageQ_registerHeap((IHeap_Handle)msgQHeapHandle, MSGQ_HEAP_ID);
683     /* Create the messageQ's for each RM instance connection
684      * Need four queues.  Topology will be:
685      * RM Server <---> RM Client Delegate <---> RM Client 
686      * 1 queue on RM Server
687      * 2 queues on RM Client Delegate
688      * 1 queue on RM Client */
689     if (MultiProc_self() == 0)
690     {
691         /* Create the RM Server messageQ used by the RM Client Delegate */
692         serverCdMsgQ = MessageQ_create(serverCdQueueName, NULL);
693         if (serverCdMsgQ == NULL) 
694         {
695             System_abort("MessageQ_create failed for RM Server - Client Delegate queue\n" );
696         }
697         System_printf("Core %d: RM Server MessageQ created for receiving packets from RM CD\n", MultiProc_self());
698     }
699     else if (MultiProc_self() == 1)
700     {
701         /* Create the RM Client Delegate messageQ used by the RM Server */
702         cdServerMsgQ = MessageQ_create(cdServerQueueName, NULL);
703         if (cdServerMsgQ == NULL) 
704         {
705             System_abort("MessageQ_create failed for RM Client Delegate - Server queue\n" );
706         }
707         System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Server\n", MultiProc_self());
708         /* Create the RM Client Delegate messageQ used by the RM Client */
709         cdClientMsgQ = MessageQ_create(cdClientQueueName, NULL);
710         if (cdClientMsgQ == NULL) 
711         {
712             System_abort("MessageQ_create failed for RM Client Delegate - Client queue\n" );
713         } 
714         System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Client\n", MultiProc_self());
715         /* Create the RM Client messageQ used by the RM Client Delegate */
716         clientCdMsgQ = MessageQ_create(clientCdQueueName, NULL);
717         if (clientCdMsgQ == NULL) 
718         {
719             System_abort("MessageQ_create failed for RM Client - Client Delegate queue\n" );
720         }
721         System_printf("Core %d: RM Client MessageQ created for receiving packets from RM CD\n", MultiProc_self());
722     }
723     
724     /* Open the remote message queues. Also register the RM transports with each RM instance */
725     if (MultiProc_self() == 0)
726     {
727         /* Open the Client Delegate messageQ from the Server */
728         do 
729         {
730             status = MessageQ_open(cdServerQueueName, &serverCdQId); 
731             /* 
732              *  Sleep for 1 clock tick to avoid inundating remote processor
733              *  with interrupts if open failed
734              */
735             if (status < 0)
736             { 
737                 Task_sleep(1);
738             }
739         } while (status < 0);
740         System_printf("Core %d: RM CD MessageQ opened from RM Server\n", MultiProc_self());
742         /* Register the Client Delegate with the RM Server Instance */
743         rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE;
744         rmTransportCfg.remoteInstName = &rmClientDelegateName[0];
745         /* Set the callouts as valid for the first transport configuration on Server instance */
746         rmTransportCfg.transportCalloutsValid = true;
747         rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc;
748         rmTransportCfg.transportCallouts.rmFreePkt = TransportFree;
749         rmTransportCfg.transportCallouts.rmSend = TransportSend;
750         rmTransportCfg.transportCallouts.rmReceive = TransportReceive;        
751         rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; 
753         serverCdHandle = Rm_transportRegister(rmServerHandle, &rmTransportCfg);
755         /* Store the mapping information in the transport map */
756         rmTransportMap[SERVER_TO_CD_MAP_ENTRY].transportHandle = serverCdHandle;
757         rmTransportMap[SERVER_TO_CD_MAP_ENTRY].receiveMsgQ = serverCdMsgQ;
758         rmTransportMap[SERVER_TO_CD_MAP_ENTRY].remoteMsgQId = serverCdQId;
759         System_printf("Core %d: Registered RM Server <=> RM CD transport with RM Server instance\n", MultiProc_self());
760         
761     }
762     else if (MultiProc_self() == 1)
763     {
764         /* Open the Server messageQ from the Client Delegate */
765         do 
766         {
767             status = MessageQ_open(serverCdQueueName, &cdServerQId); 
768             /* 
769              *  Sleep for 1 clock tick to avoid inundating remote processor
770              *  with interrupts if open failed
771              */
772             if (status < 0) 
773             { 
774                 Task_sleep(1);
775             }
776         } while (status < 0);
777         System_printf("Core %d: RM Server MessageQ opened from RM CD\n", MultiProc_self());
779         /* Register the Server with the RM Client Delegate Instance */
780         rmTransportCfg.remoteInstType = Rm_instType_SERVER;
781         rmTransportCfg.remoteInstName = &rmServerName[0];
782         /* Set the callouts as valid for the first transport configuration on Client Delegate instance */
783         rmTransportCfg.transportCalloutsValid = true;
784         rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc;
785         rmTransportCfg.transportCallouts.rmFreePkt = TransportFree;
786         rmTransportCfg.transportCallouts.rmSend = TransportSend;
787         rmTransportCfg.transportCallouts.rmReceive = TransportReceive;        
788         rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; 
790         cdServerHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg);
792         /* Store the mapping information in the transport map */
793         rmTransportMap[CD_TO_SERVER_MAP_ENTRY].transportHandle = cdServerHandle;
794         rmTransportMap[CD_TO_SERVER_MAP_ENTRY].receiveMsgQ = cdServerMsgQ;
795         rmTransportMap[CD_TO_SERVER_MAP_ENTRY].remoteMsgQId = cdServerQId;
796         System_printf("Core %d: Registered RM CD <=> RM Server transport with RM CD instance\n", MultiProc_self());
797         
798         /* Open the Client messageQ from the Client Delegate */
799         do 
800         {
801             status = MessageQ_open(clientCdQueueName, &cdClientQId); 
802             /* 
803              *  Sleep for 1 clock tick to avoid inundating remote processor
804              *  with interrupts if open failed
805              */
806             if (status < 0) 
807             { 
808                 Task_sleep(1);
809             }
810         } while (status < 0);
811         System_printf("Core %d: RM Client MessageQ opened from RM CD\n", MultiProc_self());
813         /* Register the Client with the RM Client Delegate Instance */
814         rmTransportCfg.remoteInstType = Rm_instType_CLIENT;
815         rmTransportCfg.remoteInstName = &rmClientName[0];
816         /* Callouts already set on the Client Delegate so set them as invalid */
817         rmTransportCfg.transportCalloutsValid = false;
819         cdClientHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg);
821         /* Store the mapping information in the transport map */
822         rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].transportHandle = cdClientHandle;
823         rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].receiveMsgQ = cdClientMsgQ;
824         rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].remoteMsgQId = cdClientQId;
825         System_printf("Core %d: Registered RM CD <=> RM Client transport with RM CD instance\n", MultiProc_self());
827         /* Open the Client Delegate messageQ from the Client */        
828         do 
829         {
830             status = MessageQ_open(cdClientQueueName, &clientCdQId); 
831             /* 
832              *  Sleep for 1 clock tick to avoid inundating remote processor
833              *  with interrupts if open failed
834              */
835             if (status < 0) 
836             { 
837                 Task_sleep(1);
838             }
839         } while (status < 0);
840         System_printf("Core %d: RM CD MessageQ opened from RM Client\n", MultiProc_self());
842         /* Register the Client Delegate with the RM Client Instance */
843         rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE;
844         rmTransportCfg.remoteInstName = &rmClientDelegateName[0];
845         /* Set the callouts as valid for the first transport configuration on Client instance */
846         rmTransportCfg.transportCalloutsValid = true;
847         rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc;
848         rmTransportCfg.transportCallouts.rmFreePkt = TransportFree;
849         rmTransportCfg.transportCallouts.rmSend = TransportSend;
850         rmTransportCfg.transportCallouts.rmReceive = TransportReceive;        
851         rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; 
853         clientCdHandle = Rm_transportRegister(rmClientHandle, &rmTransportCfg);
855         /* Store the mapping information in the transport map */
856         rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].transportHandle = clientCdHandle;
857         rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].receiveMsgQ = clientCdMsgQ;
858         rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].remoteMsgQId = clientCdQId; 
859         System_printf("Core %d: Registered RM Client <=> RM CD transport with RM Client instance\n", MultiProc_self());
860     }
862     /* Creat the RM receive task. */
863     System_printf("Core %d: Creating RM receive task...\n", MultiProc_self());
864     Task_Params_init (&taskParams);
865     testReceiveTskHandle = Task_create (testReceiveTsk, &taskParams, NULL);
866     
867     
868     /* Create the RM test task. */
869     System_printf("Core %d: Creating RM test task...\n", MultiProc_self());
870     Task_Params_init (&taskParams);
871     testRmTskHandle = Task_create (testRmTsk, &taskParams, NULL);
874 /*
875  *  ======== main ========
876  *  Synchronizes all processors (in Ipc_start) and calls BIOS_start
877  */
878 Int main(Int argc, Char* argv[])
880     Rm_InitCfg rmInitCfg;
881     Task_Params taskParams;
882     FILE *globalResourceFp;
883     FILE *linuxDtbFp;
884     FILE *globalPolicyFp;
885     Int globalResourceFileSize;
886     Int linuxDtbFileSize;
887     Int globalPolicyFileSize;
888     void *globalResourceList = NULL;
889     void *linuxDtb = NULL;
890     void *globalPolicy = NULL;
891     Int status;
892     Int readSize;
894     System_printf ("*********************************************************\n");
895     System_printf ("********************** RM Testing ***********************\n");
896     System_printf ("*********************************************************\n");
898     System_printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
900     /* Initialize the RM instances - RM must be initialized before anything else in the system
901      * Core 0: 1 RM Instance - RM Server
902      * Core 1: 2 RM Instances - RM Client Delegate
903      *                          RM Client
904      */
905     if (MultiProc_self()== 0)
906     {
907         initSyncObj();
908         
909         /* Open the Global Resource and Policy DTB files */
910         globalResourceFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-global-resources.dtb", "rb");
911         linuxDtbFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-linux-evm.dtb", "rb");
912         globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\global-policy.dtb", "rb");
914         /* Get the size of the Global Resource List, Linux DTB, and Global Policy */
915         fseek(globalResourceFp, 0, SEEK_END);
916         globalResourceFileSize = ftell(globalResourceFp);
917         rewind(globalResourceFp);
919         fseek(linuxDtbFp, 0, SEEK_END);
920         linuxDtbFileSize = ftell(linuxDtbFp);
921         rewind(linuxDtbFp);
923         fseek(globalPolicyFp, 0, SEEK_END);
924         globalPolicyFileSize = ftell(globalPolicyFp);
925         rewind(globalPolicyFp);      
927         /* Allocate buffers to hold the Global Resource List, Linux DTB, and Global Policy */
928         globalResourceList = Osal_rmMalloc(globalResourceFileSize);
929         linuxDtb = Osal_rmMalloc(linuxDtbFileSize);
930         globalPolicy = Osal_rmMalloc(globalPolicyFileSize);
932         /* Read the file data into the allocated buffers */
933         readSize = fread(globalResourceList, 1, globalResourceFileSize, globalResourceFp);
934         System_printf("Read Size compared to file size: %d : %d\n", readSize, globalResourceFileSize);
935         readSize = fread(linuxDtb, 1, linuxDtbFileSize, linuxDtbFp);
936         System_printf("Read Size compared to file size: %d : %d\n", readSize, linuxDtbFileSize);        
937         readSize = fread(globalPolicy, 1, globalPolicyFileSize, globalPolicyFp);
938         System_printf("Read Size compared to file size: %d : %d\n", readSize, globalPolicyFileSize);
939         
940         System_printf("Core %d: RM Server instance created\n", MultiProc_self());
941         
942         /* Create the RM Server instance */
943         rmInitCfg.instName = &rmServerName[0];
944         rmInitCfg.instType = Rm_instType_SERVER;
945         /* Provide the DTBs to the RM Server */
946         rmInitCfg.globalResourceList = globalResourceList;
947         rmInitCfg.linuxDtb = linuxDtb;
948         rmInitCfg.startupPolicy = globalPolicy;
950         /* Get the RM Server handle */
951         rmServerHandle = Rm_init(&rmInitCfg);
952         System_printf("Core %d: RM Server instance created\n", MultiProc_self());
954      //   Rm_printResourceStatus(rmServerHandle);
955     }
956     else if (MultiProc_self()== 1)
957     {
958         /* Create the RM Client Delegate instance */
959         rmInitCfg.instName = &rmClientDelegateName[0];
960         rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
961         /* SET TO NULL - FEATURES NOT ADDED YET */
962         rmInitCfg.globalResourceList = NULL;
963         rmInitCfg.startupPolicy = NULL;
965         /* Get the RM Client Delegate handle */
966         rmClientDelegateHandle = Rm_init(&rmInitCfg);
967         System_printf("Core %d: RM Client Delegate instance created\n", MultiProc_self());
969         /* Create the RM Client instance */
970         rmInitCfg.instName = &rmClientName[0];
971         rmInitCfg.instType = Rm_instType_CLIENT;
972         /* SET TO NULL - FEATURES NOT ADDED YET */
973         rmInitCfg.globalResourceList = NULL;
974         rmInitCfg.startupPolicy = NULL;
976         /* Get the RM Client handle */
977         rmClientHandle = Rm_init(&rmInitCfg);
978         System_printf("Core %d: RM Client instance created\n", MultiProc_self());
979     }
981     /*  
982      *  Ipc_start() calls Ipc_attach() to synchronize all remote processors
983      *  because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg
984      */
985     System_printf("Core %d: Starting IPC...\n", MultiProc_self());
986     status = Ipc_start();
987     if (status < 0) 
988     {
989         System_abort("Ipc_start failed\n");
990     }
992     /* Create the RM startup task */
993     System_printf("Core %d: Creating RM startup task...\n", MultiProc_self());
994     Task_Params_init (&taskParams);
995     startupRmTskHandle = Task_create (startupRmTsk, &taskParams, NULL);
997     System_printf("Core %d: Starting BIOS...\n", MultiProc_self());
998     BIOS_start();
1000     return (0);