]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blob - test/src/rm_dsp_mt_test.c
57cab204465f1be0ec52fea0df538201347333c8
[keystone-rtos/rm-lld.git] / test / src / rm_dsp_mt_test.c
1 /*
2  *   rm_dsp_mt_test.c
3  *
4  *   Singlecore Multiple Task Resource Manager test that uses IPC to an application
5  *   requesting RM services from a RM Server, and Client.
6  *
7  *  ============================================================================
8  *
9  * Copyright (c) 2012-2013, Texas Instruments Incorporated
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * *  Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  * *  Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * *  Neither the name of Texas Instruments Incorporated nor the names of
24  *    its contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  */
40  
41 /* Standard Includes */
42 #include <string.h>
44 /* XDC Includes */
45 #include <xdc/std.h>
46 #include <xdc/runtime/System.h>
48 /* IPC Includes */
49 #include <ti/ipc/Ipc.h>
50 #include <ti/ipc/MessageQ.h>
51 #include <ti/ipc/HeapBufMP.h>
52 #include <ti/ipc/GateMP.h>
54 /* BIOS Includes */
55 #include <ti/sysbios/BIOS.h>
56 #include <ti/sysbios/knl/Task.h>
57 #include <ti/sysbios/family/c64p/Hwi.h>
58 #include <ti/sysbios/knl/Semaphore.h>
60 /* CSL Includes */
61 #include <ti/csl/csl_chip.h>
62 #include <ti/csl/csl_cacheAux.h>
63 #include <ti/csl/csl_xmcAux.h>
65 /* RM Includes */
66 #include <ti/drv/rm/rm.h>
67 #include <ti/drv/rm/rm_transport.h>
68 #include <ti/drv/rm/rm_services.h>
69 #include <ti/drv/rm/rm_osal.h>
71 /**********************************************************************
72  ************************** RM Test Symbols ***************************
73  **********************************************************************/
75 #define PRINT_USED_RESOURCES         0  /* Make 1 and rebuild project to print resources allocated in example */
77 #define SYSINIT                      0
78 #define NUM_CORES                    1
80 /* Test FALSE */
81 #define RM_TEST_FALSE                0
82 /* Test TRUE */
83 #define RM_TEST_TRUE                 1
85 /* IPC MessageQ heap name */
86 #define MSGQ_HEAP_NAME               "msgQHeapBuf"
87 /* IPC MessageQ heap ID */
88 #define MSGQ_HEAP_ID                 0
90 /* RM packet heap name */
91 #define RM_PKT_HEAP_NAME             "rmHeapBuf"
93 /* Application's core 0 registered RM transport indices */
94 #define SERVER_TO_CLIENT_MAP_ENTRY              0
95 #define CLIENT_TO_SERVER_MAP_ENTRY              1
96 /* Maximum number of registered RM transports */
97 #define MAX_MAPPING_ENTRIES                             2
99 /* Size of RM static allocation response queue.  Must be greater than number of APPROVED
100  * static allocations */
101 #define MAX_STATIC_ALLOCATION_RESPS  5 
103 /* Size of RM service response queue */
104 #define MAX_QUEUED_SERVICE_RESPONSES 10
106 /* Error checking macro */
107 #define ERROR_CHECK(checkVal, resultVal, rmInstName, printMsg)                   \
108     if (resultVal != checkVal) {                                                 \
109         char errorMsgToPrint[] = printMsg;                                       \
110         System_printf("Error Core %d : %s : ", coreNum, rmInstName);             \
111         System_printf("%s with error code : %d\n", errorMsgToPrint, resultVal);  \
112         testErrors++;                                                            \
113         System_abort("Test Failure\n");                                          \
114     }
117 /**********************************************************************
118  ********************** RM Test Data Structures ***********************
119  **********************************************************************/
121 /* IPC MessageQ RM packet encapsulation structure */
122 typedef struct {
123     /* IPC MessageQ header (must be first element in structure) */
124     MessageQ_MsgHeader  msgQHeader;
125     /* Pointer to RM packet */
126     Rm_Packet          *rmPkt;
127 } MsgQ_RmPacket;
129 /* RM registered transport mapping structure */
130 typedef struct {
131     /* Registered RM transport handle */
132     Rm_TransportHandle transportHandle;
133     /* MessageQ receive queue tied to the transport handle */
134     MessageQ_Handle    receiveMsgQ;
135 } Transport_MapEntry;
137 /**********************************************************************
138  ********************** Extern Variables ******************************
139  **********************************************************************/
141 /* Alloc and free OSAL variables */
142 extern uint32_t rmMallocCounter;
143 extern uint32_t rmFreeCounter;
145 /* RM test Global Resource List (GRL) */
146 extern const char rmGRL[];
147 /* Example Linux DTB file provided to RM Server for automatic Linux Kernel resource extraction */
148 extern const char rmLinuxDtb[];
149 /* RM test Global Policy provided to RM Server */
150 extern const char rmGlobalPolicy[];
151 /* RM test Static Policy provided to RM Client Delegate and Client */
152 extern const char rmStaticPolicy[];
154 /**********************************************************************
155  ********************** Global Variables ******************************
156  **********************************************************************/
158 /* DSP core number according to DNUM */
159 uint16_t            coreNum;
160 /* Number of errors that occurred during the test */
161 uint16_t            testErrors;
163 /* Task to configure application transport code for RM */
164 Task_Handle         startupTskHandle = NULL;
165 /* High priority task for server receiving RM packets */
166 Task_Handle         rmReceiveTskHandleServer = NULL;
167 /* High priority task for client receiving RM packets */
168 Task_Handle         rmReceiveTskHandleClient = NULL;
169 /* RM client test task 1 */
170 Task_Handle         rmClientTskHandle1 = NULL;
171 /* RM client test task 2 */
172 Task_Handle         rmClientTskHandle2 = NULL;
173 // task completion count
174 int                                     taskCompleteCount = 0;
176 // client task semaphore lock
177 uint32_t *client_semaphore_lock = NULL;
179 /* Handle for heap that RM packets will be allocated from */
180 HeapBufMP_Handle    rmPktHeapHandle = NULL;
182 /* MessageQ used by RM Client to send packets to RM Server */
183 char                serverFromClientQueueName[30] = "RM_Server_From_Client_Queue";
184 /* MessageQ used by RM Server to send packets to RM Client */
185 char                clientFromServerQueueName[30] = "RM_Client_From_Server_Queue";
187 /* RM Server instance name (must match with RM Global Resource List (GRL) and policies */
188 char                rmServerName[RM_NAME_MAX_CHARS] = "RM_Server";
189 /* RM Client instance name (must match with RM Global Resource List (GRL) and policies */
190 char                rmClientName[RM_NAME_MAX_CHARS] = "RM_Client";
192 /* RM instance handles */
193 Rm_Handle           rmServerHandle = NULL;
194 Rm_Handle           rmClientHandle = NULL;
196 /* RM instance service handles */
197 Rm_ServiceHandle   *rmServerServiceHandle = NULL;
198 Rm_ServiceHandle   *rmClientServiceHandle = NULL;
200 MessageQ_Handle    serverFromClientMsgQ, clientFromServerMsgQ;
201 MessageQ_QueueId   serverToClientQId, clientToServerQId;
202 Rm_TransportHandle serverClientHandle, clientServerHandle;
204 /* Transport map stores the RM transport handle to IPC MessageQ queue mapping */
205 Transport_MapEntry  rmTransportMap[MAX_MAPPING_ENTRIES];
207 /* Static allocation response queue */
208 Rm_ServiceRespInfo  staticResponseQueue[MAX_STATIC_ALLOCATION_RESPS];
209 /* Static allocation response queue index */
210 uint32_t            numStaticResponses;
212 /* RM response info queue used to store service responses received via the callback function */
213 Rm_ServiceRespInfo  responseInfoQueue[MAX_QUEUED_SERVICE_RESPONSES];
215 /* RM resource names (must match resource node names in GRL and policies */
216 char                resourceNameMemRegion[RM_NAME_MAX_CHARS]  = "memory-regions";
217 char                resourceNameAccumCh[RM_NAME_MAX_CHARS]    = "accumulator-ch";
218 char                resourceNameGpQ[RM_NAME_MAX_CHARS]        = "gp-queue";
219 char                resourceNameAifQ[RM_NAME_MAX_CHARS]       = "aif-queue";
220 char                resourceNameQosCluster[RM_NAME_MAX_CHARS] = "qos-cluster";
221 char                resourceNameAifRxCh[RM_NAME_MAX_CHARS]    = "aif-rx-ch";
222 char                resourceNameInfraQ[RM_NAME_MAX_CHARS]     = "infra-queue";
223 char                resourceNameLowPrioQ[RM_NAME_MAX_CHARS]   = "low-prio-queue";
224 char                resourceNamePassQ[RM_NAME_MAX_CHARS]      = "pass-queue";
226 /* Test RM NameServer name */
227 char                nameServerNameFavQ[RM_NAME_MAX_CHARS]     = "My_Favorite_Queue";
229 /* RM resource names (must match resource node names in GRL and policies */
230 char               res_name_link_ram[RM_NAME_MAX_CHARS] = "link-ram";
232 /* Used to track allocations in each task */
233 #define REQUEST_ITERATIONS 16000
234 #define RESOURCE_PRINT_DIVISOR 1000
235 uint32_t           allocs[REQUEST_ITERATIONS];
237 /**********************************************************************
238  *************************** Test Functions ***************************
239  **********************************************************************/
241 Rm_Packet *transportAlloc(Rm_AppTransportHandle appTransport, uint32_t pktSize, Rm_PacketHandle *pktHandle)
243     Rm_Packet     *rmPkt = NULL;
244     MsgQ_RmPacket *rmMsg = NULL;
246     /* Allocate a messageQ message for containing the RM packet */
247     rmMsg = (MsgQ_RmPacket *)MessageQ_alloc(MSGQ_HEAP_ID, sizeof(MsgQ_RmPacket));
248     if (rmMsg == NULL) {
249         System_printf("Error Core %d : MessageQ_alloc failed to allocate message: %d\n", coreNum);
250         testErrors++;
251         *pktHandle = NULL;
252         return(NULL);
253     }
254     else {
255         /* Create and attach RM packet to MessageQ message.  All transports will allocate from the same heap */
256         rmPkt = HeapBufMP_alloc(rmPktHeapHandle, pktSize, 0);
257         rmPkt->pktLenBytes = pktSize;
258         Osal_rmEndMemAccess((void *)rmPkt, rmPkt->pktLenBytes);
259         rmMsg->rmPkt = rmPkt;
260         *pktHandle = (Rm_PacketHandle)rmMsg;
261     }
262     return (rmPkt);
265 void transportFree (MessageQ_Msg rmMsgQMsg, Rm_Packet *pkt)
267     uint32_t pktSize = pkt->pktLenBytes;
268     int32_t  status;
270     /* All transports will free rmPkts to the same heap */
271     HeapBufMP_free(rmPktHeapHandle, pkt, pktSize);
273     status = MessageQ_free(rmMsgQMsg);
274     if (status < 0) { 
275         System_printf("Error Core %d : MessageQ_free failed to free message: %d\n", coreNum, status);
276         testErrors++;
277     }     
280 int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
282     MessageQ_QueueId  remoteQueueId = (MessageQ_QueueId)appTransport;
283     MsgQ_RmPacket    *rmMsg = pktHandle;
284     int32_t           status;    
286     /* Write back data that was written by RM after alloc */
287     Osal_rmEndMemAccess((void *)rmMsg->rmPkt, rmMsg->rmPkt->pktLenBytes);
289     /* Send the message to the remote side */
290     status = MessageQ_put(remoteQueueId, (MessageQ_Msg)rmMsg);
291     if (status < 0) {
292         transportFree((MessageQ_Msg)rmMsg, rmMsg->rmPkt);
293         System_printf("Error Core %d : MessageQ_put failed to send message: %d\n", coreNum, status);
294         testErrors++;
295     }
296     return (status);
299 void transportReceive (uint32_t transportMapEntry)
301     MessageQ_Handle  receiveQ;
302     int32_t          numPkts;
303     MessageQ_Msg     rmMsg = NULL;
304     Rm_Packet       *rmPkt = NULL;
305     int32_t          status;
306     uint32_t         i;  
308     /* Check if any packets available */
309     receiveQ = rmTransportMap[transportMapEntry].receiveMsgQ;
310     numPkts = (int32_t) MessageQ_count(receiveQ);
312     /* Process all available packets */
313     for (i = 0; i < numPkts; i++) {
314         status = (int32_t) MessageQ_get(receiveQ, &rmMsg, MessageQ_FOREVER);
315         if (rmMsg == NULL) {
316             System_printf("Error Core %d : MessageQ_get failed, returning a NULL packet\n", coreNum);
317             testErrors++;
318         }
320         /* Extract the Rm_Packet from the RM msg */
321         rmPkt = ((MsgQ_RmPacket *)rmMsg)->rmPkt;
322         Osal_rmBeginMemAccess((void *) rmPkt, rmPkt->pktLenBytes);
324         /* Provide packet to RM for processing */
325         if (status = Rm_receivePacket(rmTransportMap[transportMapEntry].transportHandle, rmPkt)) {
326             System_printf("Error Core %d : RM failed to process received packet: %d\n", coreNum, status);
327             testErrors++;
328         }
330         /* Free RM packet buffer and messageQ message */
331         transportFree(rmMsg, rmPkt);
332     }
335 /* Receive task has priority of 2 so that it pre-empts the RM instance test tasks */
336 void rmReceiveTskServer(UArg arg0, UArg arg1)
338     while(1) {
339         transportReceive(CLIENT_TO_SERVER_MAP_ENTRY);
340         /* Sleep for 1ms so that the main test tasks can run */
341         Task_sleep(1);
342     }
345 void rmReceiveTskClient(UArg arg0, UArg arg1)
347     while(1) {
348                 transportReceive(SERVER_TO_CLIENT_MAP_ENTRY);
349         /* Sleep for 1ms so that the main test tasks can run */
350         Task_sleep(1);
351     }
354 void rmClientTsk(UArg arg0, UArg arg1)
356     Rm_ServiceReqInfo   request;
357     Rm_ServiceRespInfo  response;
358     uint32_t            i;
360     if (rmServerServiceHandle) {
361         /* Init request - request one resource at a time as unspecified.  Server
362          * will return next available resource */
363         memset(&request, 0, sizeof(request));
364         request.type = Rm_service_RESOURCE_ALLOCATE_INIT;
365         request.resourceName = res_name_link_ram;
366         request.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
367         request.resourceLength = 1;
369         System_printf("Client Task %d : Requesting %d resources...\n", (uint32_t)arg0, REQUEST_ITERATIONS / 2);
370         for (i = 0; i < (REQUEST_ITERATIONS / 2); i++) {
371             memset(&response, 0, sizeof(response));
372             rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &request, &response);
374             if (response.serviceState == RM_SERVICE_APPROVED) {
375                 allocs[response.resourceBase]++;
376                 if (arg0==2)
377                         Task_sleep(1);
379                 if ((i % RESOURCE_PRINT_DIVISOR) == 0) {
380                         System_printf("Client Task %d : Requested %d resources...\n", (uint32_t)arg0, RESOURCE_PRINT_DIVISOR);
381                 }
382             }
383             else {
384                 System_printf("Error Client Task %d : Allocate request was not approved for resource %d\n",
385                                 (uint32_t)arg0, request.resourceBase);
386                 testErrors++;
387                 goto error_exit;
388             }
389         }
390     }
392 error_exit:
393         taskCompleteCount++;
394         System_printf("Client Task %d : Exiting...\n", (uint32_t)arg0);
395     return;
398 void serverInit(void)
400     HeapBufMP_Handle   msgQHeapHandle;
401     HeapBufMP_Params   heapBufParams;
402     int32_t            result = 0;
403     Rm_InitCfg         rmInitCfg;
405     // reset the allocation log
406     memset(&allocs[0], 0, sizeof(allocs));
408     // Server Instance Setup
409     /* Initialize the RM instances - RM must be initialized before anything else in the system
410      * Core 0: 1 RM Instance  - RM Server
411      */
412         /* Create the Server instance */
413     memset(&rmInitCfg, 0, sizeof(rmInitCfg));
414         rmInitCfg.instName = rmServerName;
415         rmInitCfg.instType = Rm_instType_SERVER;
416         rmInitCfg.instCfg.serverCfg.globalResourceList = (void *)rmGRL;
417         rmInitCfg.instCfg.serverCfg.globalPolicy = (void *)rmGlobalPolicy;
418         rmServerHandle = Rm_init(&rmInitCfg, &result);
419         ERROR_CHECK(RM_OK, result, rmServerName, "Initialization failed");
421         /* Open Server service handle */
422         rmServerServiceHandle = Rm_serviceOpenHandle(rmServerHandle, &result);
423         ERROR_CHECK(RM_OK, result, rmServerName, "Service handle open failed");
425     ///rmStartupTskServer(NULL, 0);
426         /* Create the heap that will be used to allocate RM messages. This
427          * heap is a multi-processor heap.  It will be shared amongst
428          * all RM instances. */
429         HeapBufMP_Params_init(&heapBufParams);
430         heapBufParams.regionId       = 0;
431         heapBufParams.name           = RM_PKT_HEAP_NAME;
432         heapBufParams.numBlocks      = 64;
433         heapBufParams.blockSize      = sizeof(Rm_Packet);
434         rmPktHeapHandle = HeapBufMP_create(&heapBufParams);
435         if (rmPktHeapHandle == NULL) {
436                 System_printf("Error Core %d : Failed to create RM packet heap\n", coreNum);
437                 testErrors++;
438         }
439         System_printf("Core %d : RM packet heap created\n", coreNum);
441         /* Create the heap that will be used to allocate messageQ messages. */
442         HeapBufMP_Params_init(&heapBufParams);
443         heapBufParams.regionId       = 0;
444         heapBufParams.name           = MSGQ_HEAP_NAME;
445         heapBufParams.numBlocks      = 64;
446         heapBufParams.blockSize      = sizeof(MsgQ_RmPacket);
447         msgQHeapHandle = HeapBufMP_create(&heapBufParams);
448         if (msgQHeapHandle == NULL) {
449                 System_printf("Error Core %d : Failed to create HeapBufMP MessageQ heap\n", coreNum);
450                 testErrors++;
451         }
452         System_printf("Core %d : IPC MessageQ message heap created\n", coreNum);
454     /* Register the MessageQ heap with MessageQ */
455     MessageQ_registerHeap(msgQHeapHandle, MSGQ_HEAP_ID);
457     /* Create the messageQ's for each RM instance connection
458      * Need four queues.  Topology will be:
459      * RM Server <---> RM Client
460      * 1 queue on RM Server
461      * 1 queue on RM Client */
462         serverFromClientMsgQ = MessageQ_create(serverFromClientQueueName, NULL);
463         if (serverFromClientMsgQ == NULL) {
464                 System_printf("Error Core %d : Failed to create Server's receive Q for Client\n", coreNum);
465                 testErrors++;
466         }
467         System_printf("Core %d : Created Server receive Q for Client\n", coreNum);
470 void clientInit(void)
472     int32_t            result = 0;
473     Rm_InitCfg         rmInitCfg;
474     Semaphore_Params   semParams;
475     HeapBufMP_Handle   msgQHeapHandle;
476     Int                status;
477     Rm_TransportCfg    rmTransportCfg;
479     // Client Instance Setup
480         /* Initialize the client semaphore lock */
481     Semaphore_Params_init(&semParams);
482     client_semaphore_lock = (uint32_t *)Semaphore_create(1, &semParams, NULL);
483     if (client_semaphore_lock==NULL) {
484         System_printf("Error : Failed to init client semaphore lock with error code: \n", client_semaphore_lock);
485         testErrors++;
486         return;
487     }
489         /* Create the RM Client instance */
490     memset(&rmInitCfg, 0, sizeof(rmInitCfg));
491         rmInitCfg.instName = rmClientName;
492         rmInitCfg.instType = Rm_instType_CLIENT;
493     rmInitCfg.mtSemObj = (uint32_t *)client_semaphore_lock;
494         rmClientHandle = Rm_init(&rmInitCfg, &result);
495         ERROR_CHECK(RM_OK, result, rmClientName, "Initialization failed");
497         /* Open Client service handle */
498         rmClientServiceHandle = Rm_serviceOpenHandle(rmClientHandle, &result);
499         ERROR_CHECK(RM_OK, result, rmClientName, "Service handle open failed");
501         /* Open the heaps created by the other processor. Loop until opened. */
502         do {
503                 status = HeapBufMP_open(RM_PKT_HEAP_NAME, &rmPktHeapHandle);
504                 /*
505                  *  Sleep for 1 clock tick to avoid inundating remote processor
506                  *  with interrupts if open failed
507                  */
508                 if (status < 0) {
509                         Task_sleep(1);
510                 }
511         } while (status < 0);
512         System_printf("Core %d : RM packet heap opened\n", coreNum);
514         do {
515                 status = HeapBufMP_open(MSGQ_HEAP_NAME, &msgQHeapHandle);
516                 /*
517                  *  Sleep for 1 clock tick to avoid inundating remote processor
518                  *  with interrupts if open failed
519                  */
520                 if (status < 0) {
521                         Task_sleep(1);
522                 }
523         } while (status < 0);
524         System_printf("Core %d : IPC MessageQ message heap opened\n", coreNum);
526     /* Register the MessageQ heap with MessageQ */
527     MessageQ_registerHeap(msgQHeapHandle, MSGQ_HEAP_ID);
529     /* Create the messageQ's for each RM instance connection
530      * Need four queues.  Topology will be:
531      * RM Server <---> RM Client
532      * 1 queue on RM Server
533      * 1 queue on RM Client */
534         clientFromServerMsgQ = MessageQ_create(clientFromServerQueueName, NULL);
535         if (clientFromServerMsgQ == NULL) {
536                 System_printf("Error Core %d : Failed to create client's receive Q for Server\n", coreNum);
537                 testErrors++;
538         }
539         System_printf("Core %d : Created client receive Q for Server\n", coreNum);
541     /* Open the remote message queues. Also register the RM transports with each RM instance */
542         /* Open the Server messageQ from the Client Delegate */
543         do {
544                 status = MessageQ_open(serverFromClientQueueName, &clientToServerQId);
545                 /*
546                  *  Sleep for 1 clock tick to avoid inundating remote processor
547                  *  with interrupts if open failed
548                  */
549                 if (status < 0) {
550                         Task_sleep(1);
551                 }
552         } while (status < 0);
553         System_printf("Core %d : RM Server MessageQ opened from RM Client\n", coreNum);
555         /* Register the Server with the RM Client Instance */
556         rmTransportCfg.rmHandle = rmClientHandle;
557         rmTransportCfg.appTransportHandle = (Rm_AppTransportHandle) clientToServerQId;
558         rmTransportCfg.remoteInstType = Rm_instType_SERVER;
559         rmTransportCfg.transportCallouts.rmAllocPkt = transportAlloc;
560         rmTransportCfg.transportCallouts.rmSendPkt = transportSend;
561         clientServerHandle = Rm_transportRegister(&rmTransportCfg, &result);
563         /* Store the mapping information in the transport map */
564         rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle = clientServerHandle;
565         rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].receiveMsgQ = clientFromServerMsgQ;
566         System_printf("Core %d : Registered RM Client <=> RM Server transport with RM Client instance\n", coreNum);
569 void rmCleanup(void)
571     int32_t result;
572     int32_t finalMallocFree;
574     /* Delete the RM server receive task */
575     System_printf("Core %d : Deleting RM server receive task...\n", coreNum);
576     if (rmReceiveTskHandleServer) {
577         Task_delete(&rmReceiveTskHandleServer);
578         /* Set the task handle to be NULL so that the delete only occurs once */
579         rmReceiveTskHandleServer = NULL;
580     }
582     /* Delete the RM client receive task */
583     System_printf("Core %d : Deleting RM client receive task...\n", coreNum);
584     if (rmReceiveTskHandleClient) {
585         Task_delete(&rmReceiveTskHandleClient);
586         /* Set the task handle to be NULL so that the delete only occurs once */
587         rmReceiveTskHandleClient = NULL;
588     }
590     /* Delete the RM client test task 1 */
591     System_printf("Core %d : Deleting RM client test task 1...\n", coreNum);
592     if (rmClientTskHandle1) {
593         Task_delete(&rmClientTskHandle1);
594         /* Set the task handle to be NULL so that the delete only occurs once */
595         rmClientTskHandle1 = NULL;
596     }
598     /* Delete the RM client test task 2 */
599     System_printf("Core %d : Deleting RM client test task 2...\n", coreNum);
600     if (rmClientTskHandle2) {
601         Task_delete(&rmClientTskHandle2);
602         /* Set the task handle to be NULL so that the delete only occurs once */
603         rmClientTskHandle2 = NULL;
604     }
606     /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */
607         result = Rm_transportUnregister(rmTransportMap[CLIENT_TO_SERVER_MAP_ENTRY].transportHandle);
608         ERROR_CHECK(RM_OK, result, rmServerName, "Unregister of Server transport failed");
609         result = Rm_serviceCloseHandle(rmServerServiceHandle);
610         ERROR_CHECK(RM_OK, result, rmServerName, "Service handle close failed");
611         result = Rm_delete(rmServerHandle, RM_TEST_TRUE);
612         ERROR_CHECK(RM_OK, result, rmServerName, "Instance delete failed");
614         result = Rm_transportUnregister(rmTransportMap[SERVER_TO_CLIENT_MAP_ENTRY].transportHandle);
615         ERROR_CHECK(RM_OK, result, rmClientName, "Unregister of Client transport failed");
616         result = Rm_serviceCloseHandle(rmClientServiceHandle);
617         ERROR_CHECK(RM_OK, result, rmClientName, "Service handle close failed");
618         result = Rm_delete(rmClientHandle, RM_TEST_TRUE);
619         ERROR_CHECK(RM_OK, result, rmClientName, "Instance delete failed");
621         // delete the client_semaphore_lock
622         if (client_semaphore_lock)
623         {
624                 Semaphore_delete((Semaphore_Handle *)client_semaphore_lock);
625         }
627     System_printf ("Core %d : ---------------------------------------------------------\n", coreNum);
628     System_printf ("Core %d : ------------------ Memory Leak Check --------------------\n", coreNum);
629     System_printf ("Core %d : -                       : malloc count   |   free count -\n", coreNum);
630     System_printf ("Core %d : - Example Completion    :  %6d        |  %6d      -\n", coreNum,
631                    rmMallocCounter, rmFreeCounter);
632     finalMallocFree = rmMallocCounter - rmFreeCounter;
633     if (finalMallocFree > 0) {
634         System_printf ("Core %d : - FAILED - %6d unfreed mallocs                       -\n",
635                        coreNum, finalMallocFree);
636         testErrors++;
637     }
638     else if (finalMallocFree < 0) {
639         System_printf ("Core %d : - FAILED - %6d more frees than mallocs               -\n",
640                        coreNum, -finalMallocFree);
641         testErrors++;
642     }
643     else {
644         System_printf ("Core %d : - PASSED                                                -\n",
645                        coreNum);
646     }
647     System_printf ("Core %d : ---------------------------------------------------------\n", coreNum);
648     System_printf ("\n");
650     System_printf ("Core %d : ---------------------------------------------------------\n", coreNum);
651     System_printf ("Core %d : ------------------ Example Completion -------------------\n", coreNum);
652     if (testErrors) {
653         System_printf ("Core %d : - Test Errors: %-32d         -\n", coreNum, testErrors);
654     }
655     System_printf ("Core %d : ---------------------------------------------------------\n", coreNum);
656     System_printf ("\n");
658     BIOS_exit(0);
661 void startupTsk(UArg arg0, UArg arg1)
663     Int                status, i;
664     Rm_TransportCfg    rmTransportCfg;
665     int32_t            result = 0;
666     Task_Params        taskParams;
668     System_printf ("*********************************************************\n");
669     System_printf ("***************** RM Startup Task ***********************\n");
670     System_printf ("*********************************************************\n");
672     System_printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
674     // Server Instance Setup
675     serverInit();
677     // Client Instance Setup
678     clientInit();
680     /* Open the remote message queues. Also register the RM transports with each RM instance */
681         /* Open the Client Delegate messageQ from the Server */
682         do {
683                 status = MessageQ_open(clientFromServerQueueName, &serverToClientQId);
684                 /*
685                  *  Sleep for 1 clock tick to avoid inundating remote processor
686                  *  with interrupts if open failed
687                  */
688                 if (status < 0) {
689                         Task_sleep(1);
690                 }
691         } while (status < 0);
692         System_printf("Core %d : RM Client MessageQ opened from RM Server\n", coreNum);
694         /* Register the Client with the RM Server Instance */
695         rmTransportCfg.rmHandle = rmServerHandle;
696         rmTransportCfg.appTransportHandle = (Rm_AppTransportHandle) serverToClientQId;
697         rmTransportCfg.remoteInstType = Rm_instType_CLIENT;
698         rmTransportCfg.transportCallouts.rmAllocPkt = transportAlloc;
699         rmTransportCfg.transportCallouts.rmSendPkt = transportSend;
700         serverClientHandle = Rm_transportRegister(&rmTransportCfg, &result);
702         /* Store the mapping information in the transport map */
703         rmTransportMap[CLIENT_TO_SERVER_MAP_ENTRY].transportHandle = serverClientHandle;
704         rmTransportMap[CLIENT_TO_SERVER_MAP_ENTRY].receiveMsgQ = serverFromClientMsgQ;
705         System_printf("Core %d : Registered RM Server <=> RM CLient transport with RM Server instance\n", coreNum);
707         /* Create the RM server receive task */
708         System_printf("Core %d : Creating RM receive task...\n", coreNum);
709         Task_Params_init (&taskParams);
710         taskParams.priority = 4;
711         rmReceiveTskHandleServer = Task_create (rmReceiveTskServer, &taskParams, NULL);
713     /* Create the RM client receive task.  Assign higher priority than the test tasks so that
714      * when they spin waiting for messages from other RM instances the receive task is
715      * executed. */
716     System_printf("Core %d : Creating RM client receive task...\n", coreNum);
717     Task_Params_init (&taskParams);
718     taskParams.priority = 4;
719     rmReceiveTskHandleClient = Task_create (rmReceiveTskClient, &taskParams, NULL);
721         /* Create the RM client test task 1 */
722         System_printf("Core %d : Creating RM client test task 1...\n", coreNum);
723         Task_Params_init (&taskParams);
724     taskParams.priority = 1;
725     taskParams.arg0 = 1;
726     rmClientTskHandle1 = Task_create (rmClientTsk, &taskParams, NULL);
728         /* Create the RM client test task 2 */
729         System_printf("Core %d : Creating RM client test task 2...\n", coreNum);
730         Task_Params_init (&taskParams);
731     taskParams.priority = 2;
732     taskParams.arg0 = 2;
733     rmClientTskHandle2 = Task_create (rmClientTsk, &taskParams, NULL);
735         // wait for all the tasks to complete
736         while (taskCompleteCount!=2)
737         {
738                 Task_sleep(100);
739         }
741         // resource allocation checking
742     if (!testErrors) {
743         System_printf("Tasks complete - Checking for allocation errors\n");
744         for (i = 0; i < REQUEST_ITERATIONS; i++) {
745             if (allocs[i] != 1) {
746                 System_printf ("FAILED : Resource %d not allocated exactly once\n", i);
747                 testErrors++;
748             }
749         }
751         if (!testErrors) {
752                 System_printf("PASSED : All Resources allocated once\n");
753         }
754     }
756     // clean up
757     rmCleanup();
761 int main(Int argc, Char* argv[])
763     Task_Params        taskParams;
764     int                            status, i;
766     System_printf ("*********************************************************\n");
767     System_printf ("********************** RM Testing ***********************\n");
768     System_printf ("*********************************************************\n");
770     System_printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
772     coreNum = CSL_chipReadReg(CSL_CHIP_DNUM);
773     testErrors = 0;
775     System_printf("Core %d : Start IPC...\n", coreNum);
776     status = Ipc_start();
777     if (status < 0) {
778         System_abort("Server Ipc_start failed\n");
779     }
780     System_printf("Core %d : Server Task Started IPC\n", coreNum);
782     /* Initialize the transport map */
783     for (i = 0; i < MAX_MAPPING_ENTRIES; i++) {
784         rmTransportMap[i].transportHandle = NULL;
785     }
786     taskCompleteCount = 0;
788     /* Create the RM client1 task */
789     System_printf("Core %d : Creating RM startup task...\n", coreNum);
790     Task_Params_init (&taskParams);
791     taskParams.priority = 8;
792     startupTskHandle = Task_create (startupTsk, &taskParams, NULL);
794     System_printf("Core %d : Starting BIOS...\n", coreNum);
795     BIOS_start();
797     return (0);