57cab204465f1be0ec52fea0df538201347333c8
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 */
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)
242 {
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);
263 }
265 void transportFree (MessageQ_Msg rmMsgQMsg, Rm_Packet *pkt)
266 {
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 }
278 }
280 int32_t transportSend (Rm_AppTransportHandle appTransport, Rm_PacketHandle pktHandle)
281 {
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);
297 }
299 void transportReceive (uint32_t transportMapEntry)
300 {
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 }
333 }
335 /* Receive task has priority of 2 so that it pre-empts the RM instance test tasks */
336 void rmReceiveTskServer(UArg arg0, UArg arg1)
337 {
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 }
343 }
345 void rmReceiveTskClient(UArg arg0, UArg arg1)
346 {
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 }
352 }
354 void rmClientTsk(UArg arg0, UArg arg1)
355 {
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;
396 }
398 void serverInit(void)
399 {
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);
468 }
470 void clientInit(void)
471 {
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);
567 }
569 void rmCleanup(void)
570 {
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);
659 }
661 void startupTsk(UArg arg0, UArg arg1)
662 {
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();
759 }
761 int main(Int argc, Char* argv[])
762 {
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);
798 }