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;
74 /* ======== Application Heaps ======== */
75 #define RM_PKT_HEAP_NAME "rmHeapBuf"
76 HeapBufMP_Handle rmPktHeapHandle = NULL;
78 #define MSGQ_HEAP_NAME "msgQHeapBuf"
79 #define MSGQ_HEAP_ID 0
81 /* ======== RM Instance Names ======== */
82 Char rmServerName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Server";
83 Char rmClientDelegateName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client_Delegate";
84 Char rmClientName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client";
86 /* ======== RM IPC MessageQ Names ======== */
87 Char serverCdQueueName[30] = "RM_Server_CD_Queue";
88 Char cdServerQueueName[30] = "RM_CD_Server_Queue";
89 Char cdClientQueueName[30] = "RM_CD_Client_Queue";
90 Char clientCdQueueName[30] = "RM_Client_CD_Queue";
92 /* ======== RM Instance Handles ======== */
93 Rm_Handle rmServerHandle = NULL;
94 Rm_Handle rmClientDelegateHandle = NULL;
95 Rm_Handle rmClientHandle = NULL;
97 /* ======== RM Instance Service Ports ======== */
98 Rm_ServicePort *rmServerServicePort = NULL;
99 Rm_ServicePort *rmClientDelegateServicePort = NULL;
100 Rm_ServicePort *rmClientServicePort = NULL;
102 /* ======== RM Transport Packet Definition ======== */
103 typedef struct {
104 MessageQ_MsgHeader msgQHeader;
105 /* Pointer to packet provided by RM */
106 Rm_Packet *rmPkt;
107 } MsgQ_RmPacket;
109 /* ======== RM Transport Mapping Tables for Application ======== */
110 /* Core 0 Map Entry Indices */
111 #define SERVER_TO_CD_MAP_ENTRY 0
112 /* Core 1 Map Entry Indicies */
113 #define CD_TO_SERVER_MAP_ENTRY 0
114 #define CD_TO_CLIENT_MAP_ENTRY 1
115 #define CLIENT_TO_CD_MAP_ENTRY 2
117 /* Max map entries across all cores */
118 #define MAX_MAPPING_ENTRIES 3
120 typedef struct {
121 Rm_TransportHandle transportHandle;
122 MessageQ_Handle receiveMsgQ;
123 MessageQ_QueueId remoteMsgQId;
124 } Transport_MapEntry;
126 /* Core 1 will have three mapping entries
127 * Two map entries for the Client Delegate
128 * One map entry for the Client */
129 Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES];
131 /* ======== RM Application Transport APIs ======== */
133 Rm_Packet *TransportAlloc (Rm_TransportHandle transportHandle, uint32_t pktSize)
134 {
135 Rm_Packet *pkt = NULL;
137 /* All transports will allocate from the same heap */
139 HeapBufMP_alloc(rmPktHeapHandle, pktSize, 0);
141 if (pkt != NULL)
142 {
143 pkt->pktLenBytes = pktSize;
144 }
146 return (pkt);
147 }
149 int32_t TransportFree (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
150 {
151 uint32_t pktSize = pkt->pktLenBytes;
153 /* All transports will free to the same heap */
155 HeapBufMP_free(rmPktHeapHandle, pkt, pktSize);
157 return (0);
158 }
160 int32_t TransportSend (Rm_TransportHandle transportHandle, Rm_Packet *pkt)
161 {
162 MsgQ_RmPacket *rmMsg = NULL;
163 MessageQ_QueueId remoteQueueId;
164 bool handleValid = false;
165 int32_t status, i;
167 /* Get the remoteQueueId based on the transportHandle */
168 for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
169 {
170 /* transportHandle found in mapping table. Get the remoteQueueId associated
171 * with it */
172 if (rmTransportMap[i].transportHandle == transportHandle)
173 {
174 remoteQueueId = rmTransportMap[i].remoteMsgQId;
175 /* Break out of the search loop */
176 handleValid = true;
177 break;
178 }
179 }
181 if (handleValid)
182 {
183 /* Allocate a messageQ message for containing the RM packet */
184 rmMsg = (MsgQ_RmPacket *)MessageQ_alloc(MSGQ_HEAP_ID, sizeof(MsgQ_RmPacket));
185 if (rmMsg == NULL)
186 {
187 System_printf("Core %d: MessageQ_alloc failed in TransportSend\n", MultiProc_self());
188 }
190 /* Attach the RM packet to the MessageQ message */
191 rmMsg->rmPkt = pkt;
192 /* Send the message to the remote side */
193 status = MessageQ_put(remoteQueueId, (MessageQ_Msg)rmMsg);
194 if (status < 0)
195 {
196 System_printf("Core %d: MessageQ_put had a failure/error in TransportSend\n", MultiProc_self());
197 }
198 }
199 else
200 {
201 /* Could not find a registered transport handle that matched the handle provided by RM.
202 * Return an error to RM. */
203 System_printf("Core %d: TransportSend couldn't find transportHandle in transport map\n", MultiProc_self());
204 status = -1;
205 }
207 return (status);
208 }
210 void * TransportReceive (Rm_TransportHandle transportHandle)
211 {
212 MessageQ_Handle receiveQ;
213 MessageQ_Msg rmMsg = NULL;
214 Rm_Packet *rmPkt = NULL;
215 bool queueValid = false;
216 int32_t status, i;
218 /* Get the receiveQ based on the transportHandle */
219 for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
220 {
221 /* transportHandle found in mapping table. Get the receiveQ associated
222 * with it */
223 if (rmTransportMap[i].transportHandle == transportHandle)
224 {
225 receiveQ = rmTransportMap[i].receiveMsgQ;
226 /* Break out of the search loop */
227 queueValid = true;
228 break;
229 }
230 }
232 if (queueValid)
233 {
234 /* Get the next message from the receiveQ */
235 status = (int32_t) MessageQ_get(receiveQ, &rmMsg, MessageQ_FOREVER);
236 if (status < 0)
237 {
238 System_abort("This should not happen since timeout is forever\n");
239 }
240 if (rmMsg == NULL)
241 {
242 System_printf("Core %d: MessageQ_get failed returning a null packet in TransportReceive\n", MultiProc_self());
243 }
245 /* Extract the Rm_Packet from the RM msg */
246 rmPkt = ((MsgQ_RmPacket *)rmMsg)->rmPkt;
248 /* Free the messageQ message now that RM packet pointer has been extracted */
249 status = MessageQ_free(rmMsg);
250 if (status < 0)
251 {
252 System_printf("Core %d: MessageQ_free had a failure/error in TransportReceive\n", MultiProc_self());
253 }
254 }
255 else
256 {
257 /* Could not find a registered transport handle that matched the handle provided by RM.
258 * Return an error to RM. */
259 System_printf("Core %d: TransportReceive couldn't find transportHandle in transport map\n", MultiProc_self());
260 }
262 /* Pass the RM packet back to RM */
263 return ((void *)rmPkt);
264 }
266 int32_t TransportNumPktsReceived (Rm_TransportHandle transportHandle)
267 {
268 MessageQ_Handle receiveQ;
269 bool queueValid = false;
270 int32_t numPkts, i;
272 /* Get the receiveQ based on the transportHandle */
273 for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
274 {
275 /* transportHandle found in mapping table. Get the receiveQ associated
276 * with it */
277 if (rmTransportMap[i].transportHandle == transportHandle)
278 {
279 receiveQ = rmTransportMap[i].receiveMsgQ;
280 /* Break out of the search loop */
281 queueValid = true;
282 break;
283 }
284 }
286 if (queueValid)
287 {
288 /* Get the number of messages in the receiveQ */
289 numPkts = (int32_t) MessageQ_count(receiveQ);
290 }
291 else
292 {
293 /* Could not find a registered transport handle that matched the handle provided by RM.
294 * Return an error to RM. */
295 System_printf("Core %d: TransportNumPktsReceived couldn't find transportHandle in transport map\n", MultiProc_self());
296 numPkts = -1;
297 }
299 return (numPkts);
300 }
302 /*
303 * ======== testServiceCallback ========
304 * Application's callback function given to RM on service requests
305 */
306 Void testServiceCallback(Rm_ServiceRespInfo *serviceResponse)
307 {
309 }
311 /*
312 * ======== testRmTsk ========
313 * RM test task
314 */
315 Void testRmTsk(UArg arg0, UArg arg1)
316 {
317 Rm_ServiceReqInfo requestInfo;
318 Rm_ServiceRespInfo responseInfo;
320 /* Delete the RM startup task */
321 System_printf("Core %d: Deleting RM startup task...\n", MultiProc_self());
322 if (startupRmTskHandle)
323 {
324 Task_delete(&startupRmTskHandle);
325 /* Set the task handle to be NULL so that the delete only occurs once */
326 startupRmTskHandle = NULL;
327 }
329 /* Open service ports on all the RM instances to test service requests from the different
330 * RM instances */
331 if (MultiProc_self() == 0)
332 {
333 rmServerServicePort = Rm_getServicePort(rmServerHandle);
334 }
335 else if (MultiProc_self() == 1)
336 {
337 rmClientDelegateServicePort = Rm_getServicePort(rmClientDelegateHandle);
338 rmClientServicePort = Rm_getServicePort(rmClientHandle);
339 }
341 memset((void *)&requestInfo, 0, sizeof(Rm_ServiceReqInfo));
342 memset((void *)&responseInfo, 0, sizeof(Rm_ServiceRespInfo));
344 /* Use the service ports to test the service requests */
345 if (MultiProc_self() == 0)
346 {
347 char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "hw_semaphore";
348 char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "dsp_core_lock";
350 /* TEMP: Try mapping a resource in Name Server */
351 requestInfo.type = Rm_service_RESOURCE_MAP_TO_NAME;
352 requestInfo.resourceName = &resourceName[0];
353 requestInfo.resourceBase = 1;
354 requestInfo.resourceRange = 2;
355 requestInfo.resourceNsName = &resourceNsName[0];
356 requestInfo.callback.serviceCallback = testServiceCallback;
358 /* Issue the service request via the service port */
359 rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
360 }
361 else if (MultiProc_self() == 1)
362 {
363 char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "timer";
364 char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "dsp_timer";
366 /* TEMP: Try mapping a resource in Name Server from Client to test transports */
367 requestInfo.type = Rm_service_RESOURCE_MAP_TO_NAME;
368 requestInfo.resourceName = &resourceName[0];
369 requestInfo.resourceBase = 2;
370 requestInfo.resourceRange = 3;
371 requestInfo.resourceNsName = &resourceNsName[0];
372 requestInfo.callback.serviceCallback = testServiceCallback;
374 /* Issue the service request via the service port */
375 rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo);
376 }
378 System_printf("The test is complete\n");
379 BIOS_exit(0);
380 }
382 /*
383 * ======== startupRmTsk ========
384 * Configures application transports and registers them with RM
385 */
386 Void startupRmTsk(UArg arg0, UArg arg1)
387 {
388 MessageQ_Handle serverCdMsgQ, cdServerMsgQ, cdClientMsgQ, clientCdMsgQ;
389 MessageQ_QueueId serverCdQId, cdServerQId, cdClientQId, clientCdQId;
390 Int status, i;
391 HeapBufMP_Handle msgQHeapHandle;
392 HeapBufMP_Params heapBufParams;
393 Rm_TransportCfg rmTransportCfg;
394 Rm_TransportHandle serverCdHandle, cdServerHandle, cdClientHandle, clientCdHandle;
395 Task_Params taskParams;
397 /* Initialize the transport map */
398 for (i = 0; i < MAX_MAPPING_ENTRIES; i++)
399 {
400 rmTransportMap[i].transportHandle = NULL;
401 }
403 if (MultiProc_self() == 0)
404 {
405 /* Create the heap that will be used to allocate RM messages. This
406 * heap is a multi-processor heap. It will be shared amongst
407 * all RM instances. */
408 HeapBufMP_Params_init(&heapBufParams);
409 heapBufParams.regionId = 0;
410 heapBufParams.name = RM_PKT_HEAP_NAME;
411 heapBufParams.numBlocks = 64;
412 heapBufParams.blockSize = sizeof(Rm_Packet);
413 rmPktHeapHandle = HeapBufMP_create(&heapBufParams);
414 if (rmPktHeapHandle == NULL)
415 {
416 System_abort("HeapBufMP_create failed for RM packet heap\n" );
417 }
418 System_printf("Core %d: RM packet heap created\n", MultiProc_self());
420 /* Create the heap that will be used to allocate messageQ messages. */
421 HeapBufMP_Params_init(&heapBufParams);
422 heapBufParams.regionId = 0;
423 heapBufParams.name = MSGQ_HEAP_NAME;
424 heapBufParams.numBlocks = 64;
425 heapBufParams.blockSize = sizeof(MsgQ_RmPacket);
426 msgQHeapHandle = HeapBufMP_create(&heapBufParams);
427 if (msgQHeapHandle == NULL)
428 {
429 System_abort("HeapBufMP_create failed MessageQ message heap\n" );
430 }
431 System_printf("Core %d: IPC MessageQ message heap created\n", MultiProc_self());
432 }
433 else
434 {
435 /* Open the heaps created by the other processor. Loop until opened. */
436 do
437 {
438 status = HeapBufMP_open(RM_PKT_HEAP_NAME, &rmPktHeapHandle);
439 /*
440 * Sleep for 1 clock tick to avoid inundating remote processor
441 * with interrupts if open failed
442 */
443 if (status < 0)
444 {
445 Task_sleep(1);
446 }
447 } while (status < 0);
448 System_printf("Core %d: RM packet heap opened\n", MultiProc_self());
450 do
451 {
452 status = HeapBufMP_open(MSGQ_HEAP_NAME, &msgQHeapHandle);
453 /*
454 * Sleep for 1 clock tick to avoid inundating remote processor
455 * with interrupts if open failed
456 */
457 if (status < 0)
458 {
459 Task_sleep(1);
460 }
461 } while (status < 0);
462 System_printf("Core %d: IPC MessageQ message heap opened\n", MultiProc_self());
463 }
465 /* Register the MessageQ heap with MessageQ */
466 MessageQ_registerHeap((IHeap_Handle)msgQHeapHandle, MSGQ_HEAP_ID);
468 /* Create the messageQ's for each RM instance connection
469 * Need four queues. Topology will be:
470 * RM Server <---> RM Client Delegate <---> RM Client
471 * 1 queue on RM Server
472 * 2 queues on RM Client Delegate
473 * 1 queue on RM Client */
474 if (MultiProc_self() == 0)
475 {
476 /* Create the RM Server messageQ used by the RM Client Delegate */
477 serverCdMsgQ = MessageQ_create(serverCdQueueName, NULL);
478 if (serverCdMsgQ == NULL)
479 {
480 System_abort("MessageQ_create failed for RM Server - Client Delegate queue\n" );
481 }
482 System_printf("Core %d: RM Server MessageQ created for receiving packets from RM CD\n", MultiProc_self());
483 }
484 else if (MultiProc_self() == 1)
485 {
486 /* Create the RM Client Delegate messageQ used by the RM Server */
487 cdServerMsgQ = MessageQ_create(cdServerQueueName, NULL);
488 if (cdServerMsgQ == NULL)
489 {
490 System_abort("MessageQ_create failed for RM Client Delegate - Server queue\n" );
491 }
492 System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Server\n", MultiProc_self());
493 /* Create the RM Client Delegate messageQ used by the RM Client */
494 cdClientMsgQ = MessageQ_create(cdClientQueueName, NULL);
495 if (cdClientMsgQ == NULL)
496 {
497 System_abort("MessageQ_create failed for RM Client Delegate - Client queue\n" );
498 }
499 System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Client\n", MultiProc_self());
500 /* Create the RM Client messageQ used by the RM Client Delegate */
501 clientCdMsgQ = MessageQ_create(clientCdQueueName, NULL);
502 if (clientCdMsgQ == NULL)
503 {
504 System_abort("MessageQ_create failed for RM Client - Client Delegate queue\n" );
505 }
506 System_printf("Core %d: RM Client MessageQ created for receiving packets from RM CD\n", MultiProc_self());
507 }
509 /* Open the remote message queues. Also register the RM transports with each RM instance */
510 if (MultiProc_self() == 0)
511 {
512 /* Open the Client Delegate messageQ from the Server */
513 do
514 {
515 status = MessageQ_open(cdServerQueueName, &serverCdQId);
516 /*
517 * Sleep for 1 clock tick to avoid inundating remote processor
518 * with interrupts if open failed
519 */
520 if (status < 0)
521 {
522 Task_sleep(1);
523 }
524 } while (status < 0);
525 System_printf("Core %d: RM CD MessageQ opened from RM Server\n", MultiProc_self());
527 /* Register the Client Delegate with the RM Server Instance */
528 rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE;
529 rmTransportCfg.remoteInstName = &rmClientDelegateName[0];
530 rmTransportCfg.transportCalloutsValid = true;
531 rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc;
532 rmTransportCfg.transportCallouts.rmFreePkt = TransportFree;
533 rmTransportCfg.transportCallouts.rmSend = TransportSend;
534 rmTransportCfg.transportCallouts.rmReceive = TransportReceive;
535 rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived;
537 serverCdHandle = Rm_transportRegister(rmServerHandle, &rmTransportCfg);
539 /* Store the mapping information in the transport map */
540 rmTransportMap[SERVER_TO_CD_MAP_ENTRY].transportHandle = serverCdHandle;
541 rmTransportMap[SERVER_TO_CD_MAP_ENTRY].receiveMsgQ = serverCdMsgQ;
542 rmTransportMap[SERVER_TO_CD_MAP_ENTRY].remoteMsgQId = serverCdQId;
543 System_printf("Core %d: Registered RM Server <=> RM CD transport with RM Server instance\n", MultiProc_self());
545 }
546 else if (MultiProc_self() == 1)
547 {
548 /* Open the Server messageQ from the Client Delegate */
549 do
550 {
551 status = MessageQ_open(serverCdQueueName, &cdServerQId);
552 /*
553 * Sleep for 1 clock tick to avoid inundating remote processor
554 * with interrupts if open failed
555 */
556 if (status < 0)
557 {
558 Task_sleep(1);
559 }
560 } while (status < 0);
561 System_printf("Core %d: RM Server MessageQ opened from RM CD\n", MultiProc_self());
563 /* Register the Server with the RM Client Delegate Instance */
564 rmTransportCfg.remoteInstType = Rm_instType_SERVER;
565 rmTransportCfg.remoteInstName = &rmServerName[0];
566 /* Set the callouts as valid for the first transport configuration on this core */
567 rmTransportCfg.transportCalloutsValid = true;
568 rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc;
569 rmTransportCfg.transportCallouts.rmFreePkt = TransportFree;
570 rmTransportCfg.transportCallouts.rmSend = TransportSend;
571 rmTransportCfg.transportCallouts.rmReceive = TransportReceive;
572 rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived;
574 cdServerHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg);
576 /* Store the mapping information in the transport map */
577 rmTransportMap[CD_TO_SERVER_MAP_ENTRY].transportHandle = cdServerHandle;
578 rmTransportMap[CD_TO_SERVER_MAP_ENTRY].receiveMsgQ = cdServerMsgQ;
579 rmTransportMap[CD_TO_SERVER_MAP_ENTRY].remoteMsgQId = cdServerQId;
580 System_printf("Core %d: Registered RM CD <=> RM Server transport with RM CD instance\n", MultiProc_self());
582 /* Open the Client messageQ from the Client Delegate */
583 do
584 {
585 status = MessageQ_open(clientCdQueueName, &cdClientQId);
586 /*
587 * Sleep for 1 clock tick to avoid inundating remote processor
588 * with interrupts if open failed
589 */
590 if (status < 0)
591 {
592 Task_sleep(1);
593 }
594 } while (status < 0);
595 System_printf("Core %d: RM Client MessageQ opened from RM CD\n", MultiProc_self());
597 /* Register the Client with the RM Client Delegate Instance */
598 rmTransportCfg.remoteInstType = Rm_instType_CLIENT;
599 rmTransportCfg.remoteInstName = &rmClientName[0];
600 /* Callouts already set so set them as invalid */
601 rmTransportCfg.transportCalloutsValid = false;
603 cdClientHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg);
605 /* Store the mapping information in the transport map */
606 rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].transportHandle = cdClientHandle;
607 rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].receiveMsgQ = cdClientMsgQ;
608 rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].remoteMsgQId = cdClientQId;
609 System_printf("Core %d: Registered RM CD <=> RM Client transport with RM CD instance\n", MultiProc_self());
611 /* Open the Client Delegate messageQ from the Client */
612 do
613 {
614 status = MessageQ_open(cdClientQueueName, &clientCdQId);
615 /*
616 * Sleep for 1 clock tick to avoid inundating remote processor
617 * with interrupts if open failed
618 */
619 if (status < 0)
620 {
621 Task_sleep(1);
622 }
623 } while (status < 0);
624 System_printf("Core %d: RM CD MessageQ opened from RM Client\n", MultiProc_self());
626 /* Register the Client Delegate with the RM Client Instance */
627 rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE;
628 rmTransportCfg.remoteInstName = &rmClientDelegateName[0];
629 /* Callouts already set so set them as invalid */
630 rmTransportCfg.transportCalloutsValid = false;
632 clientCdHandle = Rm_transportRegister(rmClientHandle, &rmTransportCfg);
634 /* Store the mapping information in the transport map */
635 rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].transportHandle = clientCdHandle;
636 rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].receiveMsgQ = clientCdMsgQ;
637 rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].remoteMsgQId = clientCdQId;
638 System_printf("Core %d: Registered RM Client <=> RM CD transport with RM Client instance\n", MultiProc_self());
639 }
641 /* Create the RM test task. */
642 System_printf("Core %d: Creating RM test task...\n", MultiProc_self());
643 Task_Params_init (&taskParams);
644 Task_create (testRmTsk, &taskParams, NULL);
645 }
647 /*
648 * ======== main ========
649 * Synchronizes all processors (in Ipc_start) and calls BIOS_start
650 */
651 Int main(Int argc, Char* argv[])
652 {
653 Rm_InitCfg rmInitCfg;
654 Task_Params taskParams;
655 FILE *globalResourceFp;
656 FILE *globalPolicyFp;
657 Int globalResourceFileSize;
658 Int globalPolicyFileSize;
659 void *globalResourceList = NULL;
660 void *globalPolicy = NULL;
661 Int status;
662 Int readSize;
664 System_printf ("*********************************************************\n");
665 System_printf ("********************** RM Testing ***********************\n");
666 System_printf ("*********************************************************\n");
668 System_printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr());
670 /* Initialize the RM instances - RM must be initialized before anything else in the system
671 * Core 0: 1 RM Instance - RM Server
672 * Core 1: 2 RM Instances - RM Client Delegate
673 * RM Client
674 */
675 if (MultiProc_self()== 0)
676 {
677 /* Open the Global Resource and Policy DTB files */
678 globalResourceFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\resources2.dtb", "rb");
679 globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\global-policy.dtb", "rb");
681 /* Get the size of the Global Resource List and Global Policy */
682 fseek(globalResourceFp, 0, SEEK_END);
683 globalResourceFileSize = ftell(globalResourceFp);
684 rewind(globalResourceFp);
686 fseek(globalPolicyFp, 0, SEEK_END);
687 globalPolicyFileSize = ftell(globalPolicyFp);
688 rewind(globalPolicyFp);
690 /* Allocate buffers to hold the Global Resource List and Global Policy */
691 globalResourceList = Osal_rmMalloc(globalResourceFileSize);
692 globalPolicy = Osal_rmMalloc(globalPolicyFileSize);
694 /* Read the file data into the allocated buffers */
695 readSize = fread(globalResourceList, 1, globalResourceFileSize, globalResourceFp);
696 System_printf("Read Size compared to file size: %d : %d\n", readSize, globalResourceFileSize);
697 readSize = fread(globalPolicy, 1, globalPolicyFileSize, globalPolicyFp);
698 System_printf("Read Size compared to file size: %d : %d\n", readSize, globalPolicyFileSize);
700 System_printf("Core %d: RM Server instance created\n", MultiProc_self());
702 /* Create the RM Server instance */
703 rmInitCfg.instName = &rmServerName[0];
704 rmInitCfg.instType = Rm_instType_SERVER;
705 /* SET TO NULL - FEATURES NOT ADDED YET */
706 rmInitCfg.globalResourceList = globalResourceList;
707 rmInitCfg.startupPolicy = globalPolicy;
709 /* Get the RM Server handle */
710 rmServerHandle = Rm_init(&rmInitCfg);
711 System_printf("Core %d: RM Server instance created\n", MultiProc_self());
712 }
713 else if (MultiProc_self()== 1)
714 {
715 /* Create the RM Client Delegate instance */
716 rmInitCfg.instName = &rmClientDelegateName[0];
717 rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
718 /* SET TO NULL - FEATURES NOT ADDED YET */
719 rmInitCfg.globalResourceList = NULL;
720 rmInitCfg.startupPolicy = NULL;
722 /* Get the RM Client Delegate handle */
723 rmClientDelegateHandle = Rm_init(&rmInitCfg);
724 System_printf("Core %d: RM Client Delegate instance created\n", MultiProc_self());
726 /* Create the RM Client instance */
727 rmInitCfg.instName = &rmClientName[0];
728 rmInitCfg.instType = Rm_instType_CLIENT;
729 /* SET TO NULL - FEATURES NOT ADDED YET */
730 rmInitCfg.globalResourceList = NULL;
731 rmInitCfg.startupPolicy = NULL;
733 /* Get the RM Client handle */
734 rmClientHandle = Rm_init(&rmInitCfg);
735 System_printf("Core %d: RM Client instance created\n", MultiProc_self());
736 }
738 /*
739 * Ipc_start() calls Ipc_attach() to synchronize all remote processors
740 * because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg
741 */
742 System_printf("Core %d: Starting IPC...\n", MultiProc_self());
743 status = Ipc_start();
744 if (status < 0)
745 {
746 System_abort("Ipc_start failed\n");
747 }
749 /* Create the RM startup task */
750 System_printf("Core %d: Creating RM startup task...\n", MultiProc_self());
751 Task_Params_init (&taskParams);
752 startupRmTskHandle = Task_create (startupRmTsk, &taskParams, NULL);
754 System_printf("Core %d: Starting BIOS...\n", MultiProc_self());
755 BIOS_start();
757 return (0);
758 }