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)
148 {
149 Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));
150 testSyncObj.sem = 0;
151 Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
152 }
154 void takeSyncObj(void)
155 {
156 Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));
157 testSyncObj.sem = 1;
158 Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
159 }
161 void waitOnSyncObj(void)
162 {
163 do
164 {
165 /* Yield for other tasks */
166 Task_yield();
167 Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));
168 } while (testSyncObj.sem == 1);
169 }
171 void releaseSyncObj(void)
172 {
173 Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj));
174 testSyncObj.sem = 0;
175 Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj));
176 }
178 /* ======== RM Application Transport APIs ======== */
180 Rm_Packet *TransportAlloc (Rm_TransportHandle transportHandle, uint32_t pktSize)
181 {
182 Rm_Packet *pkt = NULL;
184 /* All transports will allocate from the same heap */
186 pkt = HeapBufMP_alloc(rmPktHeapHandle, pktSize, 0);
188 if (pkt != NULL)
189 {
190 pkt->pktLenBytes = pktSize;
191 }
193 return (pkt);
194 }
196 int32_t TransportFree (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
197 {
198 uint32_t pktSize = pkt->pktLenBytes;
200 /* All transports will free to the same heap */
202 HeapBufMP_free(rmPktHeapHandle, pkt, pktSize);
204 return (0);
205 }
207 int32_t TransportSend (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
208 {
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 }
255 return (status);
256 }
258 void *TransportReceive (Rm_TransportHandle transportHandle)
259 {
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);
313 }
315 int32_t TransportNumPktsReceived (Rm_TransportHandle transportHandle)
316 {
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 }
348 return (numPkts);
349 }
351 /*
352 * ======== testServiceCallback ========
353 * Application's callback function given to RM on service requests
354 */
355 void testServiceCallback(Rm_ServiceRespInfo *serviceResponse)
356 {
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 }
364 }
366 bool blockForResponse(Rm_ServiceRespInfo *respInfo)
367 {
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);
386 }
388 /*
389 * ======== testRmTsk ========
390 * RM cleanup task
391 */
392 void cleanupRmTsk(UArg arg0, UArg arg1)
393 {
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 }
413 /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */
415 BIOS_exit(0);
416 }
418 /*
419 * ======== testRmTsk ========
420 * RM test task
421 */
422 void testReceiveTsk(UArg arg0, UArg arg1)
423 {
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 }
474 }
476 /*
477 * ======== testRmTsk ========
478 * RM test task
479 */
480 void testRmTsk(UArg arg0, UArg arg1)
481 {
482 Rm_ServiceReqInfo requestInfo;
483 Task_Params taskParams;
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;
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);
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;
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;
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());
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);
595 }
597 /*
598 * ======== startupRmTsk ========
599 * Configures application transports and registers them with RM
600 */
601 Void startupRmTsk(UArg arg0, UArg arg1)
602 {
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());
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 }
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 }
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());
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());
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);
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);
872 }
874 /*
875 * ======== main ========
876 * Synchronizes all processors (in Ipc_start) and calls BIOS_start
877 */
878 Int main(Int argc, Char* argv[])
879 {
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();
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);
940 System_printf("Core %d: RM Server instance created\n", MultiProc_self());
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);
1001 }