/* * Copyright (c) 2012, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * ======== rm_test.c ======== * RM multicore test example * * This is an example program that uses MessageQ to pass a message * from one processor to another. * * Each processor creates its own MessageQ first and then will try to open * a remote processor's MessageQ. * * See message_multicore.k file for expected output. */ #include #include #include #include #include /* -----------------------------------XDC.RUNTIME module Headers */ #include #include /* ----------------------------------- IPC module Headers */ #include #include #include #include /* ----------------------------------- BIOS6 module Headers */ #include #include /* ----------------------------------- Resource Manager Headers */ #include #include #include #include /* ======== Task Handles ======== */ Task_Handle startupRmTskHandle; Task_Handle testReceiveTskHandle; Task_Handle testRmTskHandle; /* ======== Application Heaps ======== */ #define RM_PKT_HEAP_NAME "rmHeapBuf" HeapBufMP_Handle rmPktHeapHandle = NULL; #define MSGQ_HEAP_NAME "msgQHeapBuf" #define MSGQ_HEAP_ID 0 /* ======== RM Instance Names ======== */ Char rmServerName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Server"; Char rmClientDelegateName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client_Delegate"; Char rmClientName[RM_INSTANCE_NAME_MAX_CHARS] = "RM_Client"; /* ======== RM IPC MessageQ Names ======== */ Char serverCdQueueName[30] = "RM_Server_CD_Queue"; Char cdServerQueueName[30] = "RM_CD_Server_Queue"; Char cdClientQueueName[30] = "RM_CD_Client_Queue"; Char clientCdQueueName[30] = "RM_Client_CD_Queue"; /* ======== RM Instance Handles ======== */ Rm_Handle rmServerHandle = NULL; Rm_Handle rmClientDelegateHandle = NULL; Rm_Handle rmClientHandle = NULL; /* ======== RM Instance Service Ports ======== */ Rm_ServicePort *rmServerServicePort = NULL; Rm_ServicePort *rmClientDelegateServicePort = NULL; Rm_ServicePort *rmClientServicePort = NULL; /* ======== RM Transport Packet Definition ======== */ typedef struct { MessageQ_MsgHeader msgQHeader; /* Pointer to packet provided by RM */ Rm_Packet *rmPkt; } MsgQ_RmPacket; /* ======== RM Transport Mapping Tables for Application ======== */ /* Core 0 Map Entry Indices */ #define SERVER_TO_CD_MAP_ENTRY 0 /* Core 1 Map Entry Indicies */ #define CD_TO_SERVER_MAP_ENTRY 0 #define CD_TO_CLIENT_MAP_ENTRY 1 #define CLIENT_TO_CD_MAP_ENTRY 2 /* Max map entries across all cores */ #define MAX_MAPPING_ENTRIES 3 typedef struct { Rm_TransportHandle transportHandle; MessageQ_Handle receiveMsgQ; MessageQ_QueueId remoteMsgQId; } Transport_MapEntry; /* Core 1 will have three mapping entries * Two map entries for the Client Delegate * One map entry for the Client */ Transport_MapEntry rmTransportMap[MAX_MAPPING_ENTRIES]; uint32_t waitForBlockingOperation = 0; Rm_ServiceRespInfo responseInfo; /* ======== RM Application Sync APIs ======== */ typedef struct { uint32_t sem; uint32_t pad[31]; } syncObj; #pragma DATA_SECTION (testSyncObj, ".syncObj"); #pragma DATA_ALIGN (testSyncObj, 16) syncObj testSyncObj; void initSyncObj(void) { Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj)); testSyncObj.sem = 0; Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj)); } void takeSyncObj(void) { Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj)); testSyncObj.sem = 1; Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj)); } void waitOnSyncObj(void) { do { /* Yield for other tasks */ Task_yield(); Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj)); } while (testSyncObj.sem == 1); } void releaseSyncObj(void) { Rm_osalBeginMemAccess((void *) &testSyncObj, sizeof(syncObj)); testSyncObj.sem = 0; Rm_osalEndMemAccess((void *) &testSyncObj, sizeof(syncObj)); } /* ======== RM Application Transport APIs ======== */ Rm_Packet *TransportAlloc (Rm_TransportHandle transportHandle, uint32_t pktSize) { Rm_Packet *pkt = NULL; /* All transports will allocate from the same heap */ pkt = HeapBufMP_alloc(rmPktHeapHandle, pktSize, 0); if (pkt != NULL) { pkt->pktLenBytes = pktSize; } return (pkt); } int32_t TransportFree (Rm_TransportHandle transportHandle, Rm_Packet *pkt) { uint32_t pktSize = pkt->pktLenBytes; /* All transports will free to the same heap */ HeapBufMP_free(rmPktHeapHandle, pkt, pktSize); return (0); } int32_t TransportSend (Rm_TransportHandle transportHandle, Rm_Packet *pkt) { MsgQ_RmPacket *rmMsg = NULL; MessageQ_QueueId remoteQueueId; bool handleValid = false; int32_t status, i; /* Get the remoteQueueId based on the transportHandle */ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) { /* transportHandle found in mapping table. Get the remoteQueueId associated * with it */ if (rmTransportMap[i].transportHandle == transportHandle) { remoteQueueId = rmTransportMap[i].remoteMsgQId; /* Break out of the search loop */ handleValid = true; break; } } if (handleValid) { /* Allocate a messageQ message for containing the RM packet */ rmMsg = (MsgQ_RmPacket *)MessageQ_alloc(MSGQ_HEAP_ID, sizeof(MsgQ_RmPacket)); if (rmMsg == NULL) { System_printf("Core %d: MessageQ_alloc failed in TransportSend\n", MultiProc_self()); } /* Attach the RM packet to the MessageQ message */ Rm_osalEndMemAccess((void *) pkt, pkt->pktLenBytes); rmMsg->rmPkt = pkt; /* Send the message to the remote side */ status = MessageQ_put(remoteQueueId, (MessageQ_Msg)rmMsg); if (status < 0) { System_printf("Core %d: MessageQ_put had a failure/error in TransportSend\n", MultiProc_self()); } } else { /* Could not find a registered transport handle that matched the handle provided by RM. * Return an error to RM. */ System_printf("Core %d: TransportSend couldn't find transportHandle in transport map\n", MultiProc_self()); status = -1; } return (status); } void *TransportReceive (Rm_TransportHandle transportHandle) { MessageQ_Handle receiveQ; MessageQ_Msg rmMsg = NULL; Rm_Packet *rmPkt = NULL; bool queueValid = false; int32_t status, i; /* Get the receiveQ based on the transportHandle */ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) { /* transportHandle found in mapping table. Get the receiveQ associated * with it */ if (rmTransportMap[i].transportHandle == transportHandle) { receiveQ = rmTransportMap[i].receiveMsgQ; /* Break out of the search loop */ queueValid = true; break; } } if (queueValid) { /* Get the next message from the receiveQ */ status = (int32_t) MessageQ_get(receiveQ, &rmMsg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } if (rmMsg == NULL) { System_printf("Core %d: MessageQ_get failed returning a null packet in TransportReceive\n", MultiProc_self()); } /* Extract the Rm_Packet from the RM msg */ rmPkt = ((MsgQ_RmPacket *)rmMsg)->rmPkt; Rm_osalBeginMemAccess((void *) rmPkt, rmPkt->pktLenBytes); /* Free the messageQ message now that RM packet pointer has been extracted */ status = MessageQ_free(rmMsg); if (status < 0) { System_printf("Core %d: MessageQ_free had a failure/error in TransportReceive\n", MultiProc_self()); } } else { /* Could not find a registered transport handle that matched the handle provided by RM. * Return an error to RM. */ System_printf("Core %d: TransportReceive couldn't find transportHandle in transport map\n", MultiProc_self()); } /* Pass the RM packet back to RM */ return ((void *)rmPkt); } int32_t TransportNumPktsReceived (Rm_TransportHandle transportHandle) { MessageQ_Handle receiveQ; bool queueValid = false; int32_t numPkts, i; /* Get the receiveQ based on the transportHandle */ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) { /* transportHandle found in mapping table. Get the receiveQ associated * with it */ if (rmTransportMap[i].transportHandle == transportHandle) { receiveQ = rmTransportMap[i].receiveMsgQ; /* Break out of the search loop */ queueValid = true; break; } } if (queueValid) { /* Get the number of messages in the receiveQ */ numPkts = (int32_t) MessageQ_count(receiveQ); } else { /* Could not find a registered transport handle that matched the handle provided by RM. * Return an error to RM. */ System_printf("Core %d: TransportNumPktsReceived couldn't find transportHandle in transport map\n", MultiProc_self()); numPkts = -1; } return (numPkts); } /* * ======== testServiceCallback ======== * Application's callback function given to RM on service requests */ void testServiceCallback(Rm_ServiceRespInfo *serviceResponse) { if (serviceResponse->serviceId == waitForBlockingOperation) { waitForBlockingOperation = 0; strcpy(responseInfo.resourceName, serviceResponse->resourceName); responseInfo.resourceBase = serviceResponse->resourceBase; responseInfo.resourceLength = serviceResponse->resourceLength; responseInfo.serviceState = serviceResponse->serviceState; } } bool blockForResponse(Rm_ServiceRespInfo *respInfo) { waitForBlockingOperation = respInfo->serviceId; /* Block and wait for the response if the RM needed to perform a blocking operation * to complete the request */ while(waitForBlockingOperation) { /* Yield to receive task to see if there are any packets for RM instance */ Task_yield(); } if ((respInfo->serviceState != RM_SERVICE_PROCESSING) && (respInfo->serviceState != RM_SERVICE_APPROVED_AND_COMPLETED)) { System_printf("Core %d: Service request encountered error or denial: %d\n", MultiProc_self(), respInfo->serviceState); return(FALSE); } return(TRUE); } /* * ======== testRmTsk ======== * RM cleanup task */ void cleanupRmTsk(UArg arg0, UArg arg1) { /* Delete the RM test task */ System_printf("Core %d: Deleting RM test task...\n", MultiProc_self()); if (testRmTskHandle) { Task_delete(&testRmTskHandle); /* Set the task handle to be NULL so that the delete only occurs once */ testRmTskHandle = NULL; } /* Delete the RM receive task */ System_printf("Core %d: Deleting RM receive task...\n", MultiProc_self()); if (testReceiveTskHandle) { Task_delete(&testReceiveTskHandle); /* Set the task handle to be NULL so that the delete only occurs once */ testReceiveTskHandle = NULL; } /* Cleanup all service ports, transport handles, RM instances, and IPC constructs */ BIOS_exit(0); } /* * ======== testRmTsk ======== * RM test task */ void testReceiveTsk(UArg arg0, UArg arg1) { int32_t retVal; while(1) { /* Run the RM polling functions for each RM instance. */ if (MultiProc_self() == 0) { retVal = Rm_receivePktPolling(rmTransportMap[SERVER_TO_CD_MAP_ENTRY].transportHandle); if (retVal != RM_TRANSPORT_SUCCESSFUL) { System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), rmServerName, rmClientDelegateName, retVal); } } else if (MultiProc_self() == 1) { retVal = Rm_receivePktPolling(rmTransportMap[CD_TO_SERVER_MAP_ENTRY].transportHandle); if (retVal != RM_TRANSPORT_SUCCESSFUL) { System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), rmClientDelegateName, rmServerName, retVal); } retVal = Rm_receivePktPolling(rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].transportHandle); if (retVal != RM_TRANSPORT_SUCCESSFUL) { System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), rmClientDelegateName, rmClientName, retVal); } retVal = Rm_receivePktPolling(rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].transportHandle); if (retVal != RM_TRANSPORT_SUCCESSFUL) { System_printf("Core %d: %s to %s transport receive error %d\n", MultiProc_self(), rmClientName, rmClientDelegateName, retVal); } } /* Yield for main test task */ Task_yield(); } } /* * ======== testRmTsk ======== * RM test task */ void testRmTsk(UArg arg0, UArg arg1) { Rm_ServiceReqInfo requestInfo; Task_Params taskParams; /* Delete the RM startup task */ System_printf("Core %d: Deleting RM startup task...\n", MultiProc_self()); if (startupRmTskHandle) { Task_delete(&startupRmTskHandle); /* Set the task handle to be NULL so that the delete only occurs once */ startupRmTskHandle = NULL; } /* Open service ports on all the RM instances to test service requests from the different * RM instances */ if (MultiProc_self() == 0) { rmServerServicePort = Rm_getServicePort(rmServerHandle); } else if (MultiProc_self() == 1) { rmClientDelegateServicePort = Rm_getServicePort(rmClientDelegateHandle); rmClientServicePort = Rm_getServicePort(rmClientHandle); } memset((void *)&requestInfo, 0, sizeof(Rm_ServiceReqInfo)); memset((void *)&responseInfo, 0, sizeof(Rm_ServiceRespInfo)); System_printf("Core %d: Testing NameServer features...\n", MultiProc_self()); /* Use the service ports to test the service requests */ if (MultiProc_self() == 0) { char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "gp-queue"; char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "My_Favorite_Queue"; char aifName[RM_RESOURCE_NAME_MAX_CHARS] = "aif-rx-ch"; char memRegionName[RM_RESOURCE_NAME_MAX_CHARS] = "memory-regions"; /* Issue the service request create a new NameServer object via the service port */ requestInfo.type = Rm_service_RESOURCE_MAP_TO_NAME; requestInfo.resourceName = resourceName; requestInfo.resourceBase = 1002; requestInfo.resourceLength = 1; requestInfo.resourceNsName = resourceNsName; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s creating NameServer object...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s created NameServer object: %s base: %d length: %d\n", MultiProc_self(), rmServerName, resourceNsName, requestInfo.resourceBase, requestInfo.resourceLength); } /* Wait for Client Delegate and Client to retrieve resource via the name and allocate it */ waitOnSyncObj(); Rm_printResourceStatus(rmServerHandle); /* Wait for Client to free resource via the NameServer and delete the NameServer object. */ waitOnSyncObj(); Rm_printResourceStatus(rmServerHandle); /* Try to allocate the memory region taken by the Linux Kernel */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = memRegionName; requestInfo.resourceBase = 12; requestInfo.resourceLength = 1; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Trying to reserve memory region taken by Linux...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resource (SHOULD NOT HAPPEN): %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } /* Allocate some resources for testing tree interaction with multiple allocations from different instances */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 14; requestInfo.resourceLength = 5; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 19; requestInfo.resourceLength = 31; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } /* Wait for Client and Client Delegate to do their allocates */ waitOnSyncObj(); Rm_printResourceStatus(rmServerHandle); /* Free resources to show tree handling of different frees */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_FREE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 25; requestInfo.resourceLength = 3; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s freeing resource...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s freed resource: %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } Rm_printResourceStatus(rmServerHandle); memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_FREE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 34; requestInfo.resourceLength = 3; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s freeing resource...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s freed resource: %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } Rm_printResourceStatus(rmServerHandle); memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_FREE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 28; requestInfo.resourceLength = 6; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s freeing resource...\n", MultiProc_self(), rmServerName); rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s freed resource: %s base: %d length: %d\n", MultiProc_self(), rmServerName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } Rm_printResourceStatus(rmServerHandle); } else if (MultiProc_self() == 1) { char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "gp-queue"; char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "My_Favorite_Queue"; char aifName[RM_RESOURCE_NAME_MAX_CHARS] = "aif-rx-ch"; /* Issue the service request for the resources tied to the name via the service port */ requestInfo.type = Rm_service_RESOURCE_GET_BY_NAME; requestInfo.resourceNsName = resourceNsName; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s getting resources tied to NameServer object...\n", MultiProc_self(), rmClientDelegateName); rmClientDelegateServicePort->rmService(rmClientDelegateServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s got Name: %s base: %d length: %d\n", MultiProc_self(), rmClientDelegateName, resourceNsName, responseInfo.resourceBase, responseInfo.resourceLength); } /* Allocate the resources via the service port from the Client */ requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = responseInfo.resourceName; requestInfo.resourceBase = responseInfo.resourceBase; requestInfo.resourceLength = responseInfo.resourceLength; requestInfo.resourceNsName = NULL; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s allocating resources...\n", MultiProc_self(), rmClientName); rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resources: %s base: %d length: %d\n", MultiProc_self(), rmClientName, resourceNsName, responseInfo.resourceBase, responseInfo.resourceLength); } /* Release the syncObj so Server can print results of NameServer object add and resource allocate */ releaseSyncObj(); /* Take the syncObj to free the name resource via the name, rather than the base+length */ takeSyncObj(); /* Free the named resource using the name via the service port from the Client */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_FREE; requestInfo.resourceNsName = resourceNsName; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s freeing resource via name...\n", MultiProc_self(), rmClientName); rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s freed resource with name: %s\n", MultiProc_self(), rmClientName, resourceNsName); } /* Delete the name object from the NameServer */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_UNMAP_NAME; requestInfo.resourceNsName = resourceNsName; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Deleting NameServer object: %s...\n", MultiProc_self(), rmClientName, resourceNsName); rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s deleted NameServer object: %s\n", MultiProc_self(), rmClientName, resourceNsName); } /* Release the syncObj so Server can print results of resource free and NameServer object delete. */ releaseSyncObj(); /* Take the syncObj to allocate resources for testing resource tree interactions. */ takeSyncObj(); /* Allocate some resources for testing tree interaction with multiple allocations from different instances */ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 0; requestInfo.resourceLength = 6; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmClientName); rmClientServicePort->rmService(rmClientServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(), rmClientName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo)); requestInfo.type = Rm_service_RESOURCE_ALLOCATE; requestInfo.resourceName = aifName; requestInfo.resourceBase = 50; requestInfo.resourceLength = 7; requestInfo.callback.serviceCallback = testServiceCallback; System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmClientDelegateName); rmClientDelegateServicePort->rmService(rmClientDelegateServicePort->rmHandle, &requestInfo, &responseInfo); if (blockForResponse(&responseInfo)) { System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(), rmClientDelegateName, requestInfo.resourceName, requestInfo.resourceBase, requestInfo.resourceLength); } /* Release the syncObj so Server can print results of resource allocations */ releaseSyncObj(); } System_printf("Core %d: Testing is complete\n", MultiProc_self()); /* Create the RM cleanup task. */ System_printf("Core %d: Creating RM cleanup task...\n", MultiProc_self()); Task_Params_init (&taskParams); Task_create (cleanupRmTsk, &taskParams, NULL); } /* * ======== startupRmTsk ======== * Configures application transports and registers them with RM */ Void startupRmTsk(UArg arg0, UArg arg1) { MessageQ_Handle serverCdMsgQ, cdServerMsgQ, cdClientMsgQ, clientCdMsgQ; MessageQ_QueueId serverCdQId, cdServerQId, cdClientQId, clientCdQId; Int status, i; HeapBufMP_Handle msgQHeapHandle; HeapBufMP_Params heapBufParams; Rm_TransportCfg rmTransportCfg; Rm_TransportHandle serverCdHandle, cdServerHandle, cdClientHandle, clientCdHandle; Task_Params taskParams; if (MultiProc_self() == 1) { /* Take the syncObj on core 1, preparing for RM testing */ takeSyncObj(); } /* Initialize the transport map */ for (i = 0; i < MAX_MAPPING_ENTRIES; i++) { rmTransportMap[i].transportHandle = NULL; } if (MultiProc_self() == 0) { /* Create the heap that will be used to allocate RM messages. This * heap is a multi-processor heap. It will be shared amongst * all RM instances. */ HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = RM_PKT_HEAP_NAME; heapBufParams.numBlocks = 64; heapBufParams.blockSize = sizeof(Rm_Packet); rmPktHeapHandle = HeapBufMP_create(&heapBufParams); if (rmPktHeapHandle == NULL) { System_abort("HeapBufMP_create failed for RM packet heap\n" ); } System_printf("Core %d: RM packet heap created\n", MultiProc_self()); /* Create the heap that will be used to allocate messageQ messages. */ HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = MSGQ_HEAP_NAME; heapBufParams.numBlocks = 64; heapBufParams.blockSize = sizeof(MsgQ_RmPacket); msgQHeapHandle = HeapBufMP_create(&heapBufParams); if (msgQHeapHandle == NULL) { System_abort("HeapBufMP_create failed MessageQ message heap\n" ); } System_printf("Core %d: IPC MessageQ message heap created\n", MultiProc_self()); } else { /* Open the heaps created by the other processor. Loop until opened. */ do { status = HeapBufMP_open(RM_PKT_HEAP_NAME, &rmPktHeapHandle); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: RM packet heap opened\n", MultiProc_self()); do { status = HeapBufMP_open(MSGQ_HEAP_NAME, &msgQHeapHandle); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: IPC MessageQ message heap opened\n", MultiProc_self()); } /* Register the MessageQ heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)msgQHeapHandle, MSGQ_HEAP_ID); /* Create the messageQ's for each RM instance connection * Need four queues. Topology will be: * RM Server <---> RM Client Delegate <---> RM Client * 1 queue on RM Server * 2 queues on RM Client Delegate * 1 queue on RM Client */ if (MultiProc_self() == 0) { /* Create the RM Server messageQ used by the RM Client Delegate */ serverCdMsgQ = MessageQ_create(serverCdQueueName, NULL); if (serverCdMsgQ == NULL) { System_abort("MessageQ_create failed for RM Server - Client Delegate queue\n" ); } System_printf("Core %d: RM Server MessageQ created for receiving packets from RM CD\n", MultiProc_self()); } else if (MultiProc_self() == 1) { /* Create the RM Client Delegate messageQ used by the RM Server */ cdServerMsgQ = MessageQ_create(cdServerQueueName, NULL); if (cdServerMsgQ == NULL) { System_abort("MessageQ_create failed for RM Client Delegate - Server queue\n" ); } System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Server\n", MultiProc_self()); /* Create the RM Client Delegate messageQ used by the RM Client */ cdClientMsgQ = MessageQ_create(cdClientQueueName, NULL); if (cdClientMsgQ == NULL) { System_abort("MessageQ_create failed for RM Client Delegate - Client queue\n" ); } System_printf("Core %d: RM CD MessageQ created for receiving packets from RM Client\n", MultiProc_self()); /* Create the RM Client messageQ used by the RM Client Delegate */ clientCdMsgQ = MessageQ_create(clientCdQueueName, NULL); if (clientCdMsgQ == NULL) { System_abort("MessageQ_create failed for RM Client - Client Delegate queue\n" ); } System_printf("Core %d: RM Client MessageQ created for receiving packets from RM CD\n", MultiProc_self()); } /* Open the remote message queues. Also register the RM transports with each RM instance */ if (MultiProc_self() == 0) { /* Open the Client Delegate messageQ from the Server */ do { status = MessageQ_open(cdServerQueueName, &serverCdQId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: RM CD MessageQ opened from RM Server\n", MultiProc_self()); /* Register the Client Delegate with the RM Server Instance */ rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE; rmTransportCfg.remoteInstName = &rmClientDelegateName[0]; /* Set the callouts as valid for the first transport configuration on Server instance */ rmTransportCfg.transportCalloutsValid = true; rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc; rmTransportCfg.transportCallouts.rmFreePkt = TransportFree; rmTransportCfg.transportCallouts.rmSend = TransportSend; rmTransportCfg.transportCallouts.rmReceive = TransportReceive; rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; serverCdHandle = Rm_transportRegister(rmServerHandle, &rmTransportCfg); /* Store the mapping information in the transport map */ rmTransportMap[SERVER_TO_CD_MAP_ENTRY].transportHandle = serverCdHandle; rmTransportMap[SERVER_TO_CD_MAP_ENTRY].receiveMsgQ = serverCdMsgQ; rmTransportMap[SERVER_TO_CD_MAP_ENTRY].remoteMsgQId = serverCdQId; System_printf("Core %d: Registered RM Server <=> RM CD transport with RM Server instance\n", MultiProc_self()); } else if (MultiProc_self() == 1) { /* Open the Server messageQ from the Client Delegate */ do { status = MessageQ_open(serverCdQueueName, &cdServerQId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: RM Server MessageQ opened from RM CD\n", MultiProc_self()); /* Register the Server with the RM Client Delegate Instance */ rmTransportCfg.remoteInstType = Rm_instType_SERVER; rmTransportCfg.remoteInstName = &rmServerName[0]; /* Set the callouts as valid for the first transport configuration on Client Delegate instance */ rmTransportCfg.transportCalloutsValid = true; rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc; rmTransportCfg.transportCallouts.rmFreePkt = TransportFree; rmTransportCfg.transportCallouts.rmSend = TransportSend; rmTransportCfg.transportCallouts.rmReceive = TransportReceive; rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; cdServerHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg); /* Store the mapping information in the transport map */ rmTransportMap[CD_TO_SERVER_MAP_ENTRY].transportHandle = cdServerHandle; rmTransportMap[CD_TO_SERVER_MAP_ENTRY].receiveMsgQ = cdServerMsgQ; rmTransportMap[CD_TO_SERVER_MAP_ENTRY].remoteMsgQId = cdServerQId; System_printf("Core %d: Registered RM CD <=> RM Server transport with RM CD instance\n", MultiProc_self()); /* Open the Client messageQ from the Client Delegate */ do { status = MessageQ_open(clientCdQueueName, &cdClientQId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: RM Client MessageQ opened from RM CD\n", MultiProc_self()); /* Register the Client with the RM Client Delegate Instance */ rmTransportCfg.remoteInstType = Rm_instType_CLIENT; rmTransportCfg.remoteInstName = &rmClientName[0]; /* Callouts already set on the Client Delegate so set them as invalid */ rmTransportCfg.transportCalloutsValid = false; cdClientHandle = Rm_transportRegister(rmClientDelegateHandle, &rmTransportCfg); /* Store the mapping information in the transport map */ rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].transportHandle = cdClientHandle; rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].receiveMsgQ = cdClientMsgQ; rmTransportMap[CD_TO_CLIENT_MAP_ENTRY].remoteMsgQId = cdClientQId; System_printf("Core %d: Registered RM CD <=> RM Client transport with RM CD instance\n", MultiProc_self()); /* Open the Client Delegate messageQ from the Client */ do { status = MessageQ_open(cdClientQueueName, &clientCdQId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); System_printf("Core %d: RM CD MessageQ opened from RM Client\n", MultiProc_self()); /* Register the Client Delegate with the RM Client Instance */ rmTransportCfg.remoteInstType = Rm_instType_CLIENT_DELEGATE; rmTransportCfg.remoteInstName = &rmClientDelegateName[0]; /* Set the callouts as valid for the first transport configuration on Client instance */ rmTransportCfg.transportCalloutsValid = true; rmTransportCfg.transportCallouts.rmAllocPkt = TransportAlloc; rmTransportCfg.transportCallouts.rmFreePkt = TransportFree; rmTransportCfg.transportCallouts.rmSend = TransportSend; rmTransportCfg.transportCallouts.rmReceive = TransportReceive; rmTransportCfg.transportCallouts.rmNumPktsReceived = TransportNumPktsReceived; clientCdHandle = Rm_transportRegister(rmClientHandle, &rmTransportCfg); /* Store the mapping information in the transport map */ rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].transportHandle = clientCdHandle; rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].receiveMsgQ = clientCdMsgQ; rmTransportMap[CLIENT_TO_CD_MAP_ENTRY].remoteMsgQId = clientCdQId; System_printf("Core %d: Registered RM Client <=> RM CD transport with RM Client instance\n", MultiProc_self()); } /* Creat the RM receive task. */ System_printf("Core %d: Creating RM receive task...\n", MultiProc_self()); Task_Params_init (&taskParams); testReceiveTskHandle = Task_create (testReceiveTsk, &taskParams, NULL); /* Create the RM test task. */ System_printf("Core %d: Creating RM test task...\n", MultiProc_self()); Task_Params_init (&taskParams); testRmTskHandle = Task_create (testRmTsk, &taskParams, NULL); } /* * ======== main ======== * Synchronizes all processors (in Ipc_start) and calls BIOS_start */ Int main(Int argc, Char* argv[]) { Rm_InitCfg rmInitCfg; Task_Params taskParams; FILE *globalResourceFp; FILE *linuxDtbFp; FILE *globalPolicyFp; Int globalResourceFileSize; Int linuxDtbFileSize; Int globalPolicyFileSize; void *globalResourceList = NULL; void *linuxDtb = NULL; void *globalPolicy = NULL; Int status; Int readSize; System_printf ("*********************************************************\n"); System_printf ("********************** RM Testing ***********************\n"); System_printf ("*********************************************************\n"); System_printf ("RM Version : 0x%08x\nVersion String: %s\n", Rm_getVersion(), Rm_getVersionStr()); /* Initialize the RM instances - RM must be initialized before anything else in the system * Core 0: 1 RM Instance - RM Server * Core 1: 2 RM Instances - RM Client Delegate * RM Client */ if (MultiProc_self()== 0) { initSyncObj(); /* Open the Global Resource and Policy DTB files */ globalResourceFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-global-resources.dtb", "rb"); linuxDtbFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-linux-evm.dtb", "rb"); globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\global-policy.dtb", "rb"); /* Get the size of the Global Resource List, Linux DTB, and Global Policy */ fseek(globalResourceFp, 0, SEEK_END); globalResourceFileSize = ftell(globalResourceFp); rewind(globalResourceFp); fseek(linuxDtbFp, 0, SEEK_END); linuxDtbFileSize = ftell(linuxDtbFp); rewind(linuxDtbFp); fseek(globalPolicyFp, 0, SEEK_END); globalPolicyFileSize = ftell(globalPolicyFp); rewind(globalPolicyFp); /* Allocate buffers to hold the Global Resource List, Linux DTB, and Global Policy */ globalResourceList = Osal_rmMalloc(globalResourceFileSize); linuxDtb = Osal_rmMalloc(linuxDtbFileSize); globalPolicy = Osal_rmMalloc(globalPolicyFileSize); /* Read the file data into the allocated buffers */ readSize = fread(globalResourceList, 1, globalResourceFileSize, globalResourceFp); System_printf("Read Size compared to file size: %d : %d\n", readSize, globalResourceFileSize); readSize = fread(linuxDtb, 1, linuxDtbFileSize, linuxDtbFp); System_printf("Read Size compared to file size: %d : %d\n", readSize, linuxDtbFileSize); readSize = fread(globalPolicy, 1, globalPolicyFileSize, globalPolicyFp); System_printf("Read Size compared to file size: %d : %d\n", readSize, globalPolicyFileSize); System_printf("Core %d: RM Server instance created\n", MultiProc_self()); /* Create the RM Server instance */ rmInitCfg.instName = &rmServerName[0]; rmInitCfg.instType = Rm_instType_SERVER; /* Provide the DTBs to the RM Server */ rmInitCfg.globalResourceList = globalResourceList; rmInitCfg.linuxDtb = linuxDtb; rmInitCfg.startupPolicy = globalPolicy; /* Get the RM Server handle */ rmServerHandle = Rm_init(&rmInitCfg); System_printf("Core %d: RM Server instance created\n", MultiProc_self()); Rm_printResourceStatus(rmServerHandle); } else if (MultiProc_self()== 1) { /* Create the RM Client Delegate instance */ rmInitCfg.instName = &rmClientDelegateName[0]; rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE; /* SET TO NULL - FEATURES NOT ADDED YET */ rmInitCfg.globalResourceList = NULL; rmInitCfg.startupPolicy = NULL; /* Get the RM Client Delegate handle */ rmClientDelegateHandle = Rm_init(&rmInitCfg); System_printf("Core %d: RM Client Delegate instance created\n", MultiProc_self()); /* Create the RM Client instance */ rmInitCfg.instName = &rmClientName[0]; rmInitCfg.instType = Rm_instType_CLIENT; /* SET TO NULL - FEATURES NOT ADDED YET */ rmInitCfg.globalResourceList = NULL; rmInitCfg.startupPolicy = NULL; /* Get the RM Client handle */ rmClientHandle = Rm_init(&rmInitCfg); System_printf("Core %d: RM Client instance created\n", MultiProc_self()); } /* * Ipc_start() calls Ipc_attach() to synchronize all remote processors * because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg */ System_printf("Core %d: Starting IPC...\n", MultiProc_self()); status = Ipc_start(); if (status < 0) { System_abort("Ipc_start failed\n"); } /* Create the RM startup task */ System_printf("Core %d: Creating RM startup task...\n", MultiProc_self()); Task_Params_init (&taskParams); startupRmTskHandle = Task_create (startupRmTsk, &taskParams, NULL); System_printf("Core %d: Starting BIOS...\n", MultiProc_self()); BIOS_start(); return (0); }