]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
Coverity fixes
[keystone-rtos/rm-lld.git] / src / rm.c
index 06ca39cd4daf310d43aab879f241935c35aed70b..3afc89ed2908db1c4a0706c88d809501e9433843 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -42,7 +42,6 @@
 /* Standard includes */
 #include <stdint.h>
 #include <string.h>
-#include <stdbool.h>
 
 /* RM external includes */
 #include <ti/drv/rm/rm.h>
 #include <ti/drv/rm/rm_transport.h>
 
 /* RM internal includes */
+#include <ti/drv/rm/include/rm_internal.h>
 #include <ti/drv/rm/include/rm_loc.h>
 #include <ti/drv/rm/include/rm_allocatorloc.h>
 #include <ti/drv/rm/include/rm_transportloc.h>
 #include <ti/drv/rm/include/rm_nameserverloc.h>
+#include <ti/drv/rm/include/rm_servicesloc.h>
 
 /* RM LIBFDT includes */
 #include <ti/drv/rm/util/libfdt/libfdt.h>
@@ -66,7 +67,7 @@
  ************************** Globals ***********************************
  **********************************************************************/
 
-/** @brief Global Variable which describes the RM Version Information */
+/* Global Variable which describes the RM Version Information */
 const char  rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;
 
 /**********************************************************************
@@ -209,6 +210,7 @@ static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
     Rm_ServiceRespInfo serviceResponse;
 
+    serviceResponse.rmHandle = (Rm_Handle)rmInst;
     /* The responseTransaction will contain the resultant state details of
      * the requestTransaction's service request */
     serviceResponse.serviceState = transaction->state;
@@ -228,11 +230,16 @@ static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
         serviceResponse.resourceLength = transaction->resourceInfo.length;
     }
 
-    /* Issue the callback to the requesting component with the response information */
-    transaction->callback.serviceCallback(&serviceResponse);
-
-    /* Delete the transaction from the transaction queue */
-    rmTransactionQueueDelete(rmInst, transaction->localId);
+    if (transaction->callback.serviceCallback) {
+        /* Issue the callback to the requesting component with the response information */
+        transaction->callback.serviceCallback(&serviceResponse);
+        /* Delete the transaction from the transaction queue */
+        rmTransactionQueueDelete(rmInst, transaction->localId);
+    }
+    else {
+        rmServiceInternalCallback((Rm_Handle)rmInst);
+    }
+    
     return;
 }
 
@@ -281,7 +288,7 @@ static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
         transaction->state = RM_ERROR_TRANSPORT_REMOTE_HNDL_NOT_REGD;
     }
 errorExit:
-    /* Do not delete transaction on error.  Error transactions should be visible from
+    /* Do not delete transaction on transport error.  Transport rrror transactions should be visible
      * from Rm_printInstanceStatus() */
     return;
 }
@@ -299,54 +306,49 @@ static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)
     Rm_Packet       *rmPkt = NULL;    
     Rm_PacketHandle  pktHandle = NULL;
 
-    /* Forward request if callback function has been plugged (request came from service handle)
-     * or remoteOriginatingId is populated (request came from another instance over transport) */
-    if (transaction->callback.serviceCallback || transaction->remoteOriginatingId) {
-        if (rmInst->instType == Rm_instType_CLIENT) {
-            dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_CLIENT_DELEGATE);
+    if (rmInst->instType == Rm_instType_CLIENT) {
+        dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_CLIENT_DELEGATE);
 
-            if (!dstTransport) {
-                dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_SERVER);
-            }
-        } 
-        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (!dstTransport) {
             dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_SERVER);
         }
+    } 
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_SERVER);
+    }
 
-        /* Just queue transaction if transport hasn't been registered.  Do not return error */
-        if (dstTransport) {            
-            rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle, 
-                                                      sizeof(Rm_Packet), &pktHandle);
-            if (!rmPkt || !pktHandle) {
-                transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
-                goto errorExit;
-            }
+    /* Just queue transaction if transport hasn't been registered.  Do not return error */
+    if (dstTransport) {            
+        rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle, 
+                                                  sizeof(Rm_Packet), &pktHandle);
+        if (!rmPkt || !pktHandle) {
+            transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+            goto errorExit;
+        }
 
-            switch (transaction->type) {
-                case Rm_service_RESOURCE_ALLOCATE_INIT:
-                case Rm_service_RESOURCE_ALLOCATE_USE:
-                case Rm_service_RESOURCE_FREE:
-                case Rm_service_RESOURCE_GET_BY_NAME:
-                    createResourceReqPkt(rmPkt, rmInst->instName, transaction);
-                    break;
-                case Rm_service_RESOURCE_MAP_TO_NAME:
-                case Rm_service_RESOURCE_UNMAP_NAME:
-                    createNsRequestPkt(rmPkt, rmInst->instName, transaction);
-                    break;
-            }
-      
-            if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
-                transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
-                goto errorExit;
-            }              
-            transaction->hasBeenForwarded = true;
-            /* Transaction not deleted.  Waiting for response from RM CD or Server */
+        switch (transaction->type) {
+            case Rm_service_RESOURCE_ALLOCATE_INIT:
+            case Rm_service_RESOURCE_ALLOCATE_USE:
+            case Rm_service_RESOURCE_FREE:
+            case Rm_service_RESOURCE_GET_BY_NAME:
+                createResourceReqPkt(rmPkt, rmInst->instName, transaction);
+                break;
+            case Rm_service_RESOURCE_MAP_TO_NAME:
+            case Rm_service_RESOURCE_UNMAP_NAME:
+                createNsRequestPkt(rmPkt, rmInst->instName, transaction);
+                break;
         }
+  
+        if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+            transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+            goto errorExit;
+        }              
+        transaction->hasBeenForwarded = RM_TRUE;
+        /* Transaction not deleted.  Waiting for response from RM CD or Server */
     }
-    else {
-        transaction->state = RM_ERROR_CALLBACK_NOT_PROVIDED;
-    }        
 errorExit: 
+    /* Do not delete transaction on transport error.  Transport error transactions should be visible
+     * from Rm_printInstanceStatus() */               
     return;
 }
 
@@ -357,14 +359,17 @@ errorExit:
  *              with a Server.  The allocation request is validated
  *              against a static policy.
  */
-static void staticAllocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transaction)
 {
-    Rm_PolicyCheckCfg privCheckCfg;
+    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;
+    void              *staticPolicy = rmPolicyGetPolicy(rmHandle);
+    Rm_PolicyCheckCfg  privCheckCfg;
+    int32_t            result;
     
-    if (rmInst->staticInfo.staticPolicy) {
+    if (staticPolicy) {
         if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
             (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
-            /* Check request against startup policy */
+            /* Check request against static policy */
             memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
     
             if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
@@ -373,21 +378,24 @@ static void staticAllocationHandler (Rm_Inst *rmInst, Rm_Transaction *transactio
             else {
                 privCheckCfg.type = Rm_policyCheck_USE;
             }
-            privCheckCfg.policyDtb = rmInst->staticInfo.staticPolicy;
-            privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmInst->staticInfo.staticValidInstTree, 
-                                                                  rmInst->instName);
-            privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(rmInst->staticInfo.staticPolicy,
+            privCheckCfg.policyDtb = staticPolicy;
+            privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmHandle, rmInst->instName);
+            privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(staticPolicy,
                                                                     transaction->resourceInfo.name);
             privCheckCfg.resourceBase = transaction->resourceInfo.base;
             privCheckCfg.resourceLength = transaction->resourceInfo.length;
     
-            if (rmPolicyCheckPrivilege(&privCheckCfg, &transaction->state)) {
+            if (rmPolicyCheckPrivilege(&privCheckCfg, &result)) {
                 transaction->state = RM_SERVICE_APPROVED_STATIC;
             }
-            else if (transaction->state == RM_SERVICE_PROCESSING) {
+            else if (result == RM_OK) {
                 /* Privilege check returned false without error */
                 transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
             }
+            else {
+                /* Privilege check returned false with error */
+                transaction->state = result;
+            }
         }
         else {
             transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
@@ -416,31 +424,26 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
     int32_t             retVal = transaction->state;
 
     if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        transactionForwarder(rmInst, transaction);   
+        /* Fill in allocation logic for CDs */  
     }
-    else if (rmInst->instType == Rm_instType_SERVER) {
+    else if ((rmInst->instType == Rm_instType_SERVER)||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
         
-        opInfo.policy = rmInst->policy;
+        opInfo.policy = rmInst->u.server.globalPolicy;
         opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);
+        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
         if (opInfo.serviceSrcInstNode) {
-            switch (transaction->type) {
-                case Rm_service_RESOURCE_ALLOCATE_INIT:
-                    RM_policy_SET_PERM(opInfo.allocType, RM_POLICY_PERM_INIT_SHIFT, 1);
-                    break;
-                case Rm_service_RESOURCE_ALLOCATE_USE:
-                    RM_policy_SET_PERM(opInfo.allocType, RM_POLICY_PERM_USE_SHIFT, 1);    
-                    break;
-            }        
-
             /* Populated NameServer name has precedence over base */
             if (strlen(transaction->resourceInfo.nameServerName) > 0) {
                 if ((transaction->resourceInfo.base == 0) &&
                     (transaction->resourceInfo.length == 0) &&
                     (transaction->resourceInfo.alignment == 0)) {
+                    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                        rmNameServerTreeInv(rmInst->u.server.nameServer);
+                    }
                     memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                    nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
                     nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
                     if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
                         strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
@@ -450,25 +453,42 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
                 }
                 else {
                     retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
+                    goto errorExit;
                 }
             }
 
-            if (retVal == RM_SERVICE_PROCESSING) {      
-                if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
-                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;
-                    retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+            if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
                 }
-            
-                if (retVal == RM_SERVICE_PROCESSING) {
-                    opInfo.operation = Rm_allocatorOp_ALLOCATE;
-                    retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
-                }      
+                else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+                }
+                else {
+                    retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                    goto errorExit;
+                }
+                retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
             }
+        
+            if (retVal == RM_SERVICE_PROCESSING) {
+                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                }
+                else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+                }
+                else {
+                    retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                    goto errorExit;
+                }
+                retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+            }      
         }
         else {
             retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
         }
-        
+errorExit:        
         transaction->state = retVal;                 
     }   
 }
@@ -490,22 +510,26 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
     int32_t             retVal = transaction->state;
     
     if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        transactionForwarder(rmInst, transaction);   
+        /* Fill in free logic for CDs */    
     }
-    else if (rmInst->instType == Rm_instType_SERVER) {
+    else if ((rmInst->instType == Rm_instType_SERVER) ||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
         
-        opInfo.policy = rmInst->policy;
+        opInfo.policy = rmInst->u.server.globalPolicy;
         opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);
+        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
         if (opInfo.serviceSrcInstNode) {
             /* Populated NameServer name has precedence over base */
             if (strlen(transaction->resourceInfo.nameServerName) > 0) {
                 if ((transaction->resourceInfo.base == 0) &&
                     (transaction->resourceInfo.length == 0) &&
                     (transaction->resourceInfo.alignment == 0)) {
+                    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                        rmNameServerTreeInv(rmInst->u.server.nameServer);
+                    }                    
                     memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                    nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
                     nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
                     if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
                         strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
@@ -543,10 +567,10 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
  */
 static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    Rm_Transaction *transQ = rmInst->transactionQueue;
+    Rm_Transaction    *transQ = rmInst->transactionQueue;
     
     if (!rmInst->registeredWithDelegateOrServer) {
-        staticAllocationHandler(rmInst, transaction);
+        staticAllocationHandler((Rm_Handle)rmInst, transaction);
     }
     else {
         if (transaction->state == RM_SERVICE_PROCESSING) {
@@ -582,58 +606,93 @@ static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
  *                  - Attempts to complete resource service requests
  *                    received from registered Clients
  */
-static void clientDelegateProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
-{     
+static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{        
     Rm_Transaction *transQ = rmInst->transactionQueue;    
 
     if (!rmInst->registeredWithDelegateOrServer) {
         if ((transaction->state == RM_SERVICE_PROCESSING) &&
-            (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {        
-            staticAllocationHandler(rmInst, transaction);
+            (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
+            /* Attempt static allocation of requests originating from CD inst */
+            staticAllocationHandler((Rm_Handle)rmInst, transaction);
         }
         /* Everything else left in transaction queue for forwarding once transport to
          * Server is registered */
     }
     else {
-        if ((transaction->state == RM_SERVICE_PROCESSING) ||
-            (transaction->state == RM_SERVICE_APPROVED_STATIC)) {        
-            if ((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||
-                (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||
-                (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)) {
+        if ((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||
+            (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||
+            (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)) {
+            if (transaction->state == RM_SERVICE_PROCESSING) {
                 /* Forward all NameServer requests. */
                 transactionForwarder(rmInst, transaction);
             }
-            else if (transaction->type == Rm_service_RESOURCE_FREE) {
-                freeHandler(rmInst, transaction);
-            }
             else {
-                allocationHandler(rmInst, transaction);
+                /* NameServer transaction validated.  Return result. */
+                if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                    /* Transaction did not originate on this instance */
+                    transactionResponder(rmInst, transaction);
+                }
+                else {
+                    /* Transaction originated on this instance */
+                    serviceResponder(rmInst, transaction);
+                }
             }
-            
-            if ((transaction->state != RM_SERVICE_PROCESSING) &&
-                (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
-                /* Transaction error occurred.  Return result */
+        }        
+        else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                 (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+            if ((transaction->state == RM_SERVICE_PROCESSING) ||
+                (transaction->state == RM_SERVICE_APPROVED_STATIC)) {   
+                transactionForwarder(rmInst, transaction);
+            }
+            else {
+                /* Transaction validated.  Return result. */
                 if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-                    /* Source of failed transaction was not CD, return transaction via responder */
+                    /* Transaction did not originate on this instance */
                     transactionResponder(rmInst, transaction);
                 }
-                /* Otherwise let call stack return failed transaction result app via Rm_serviceHandler */                
-            }            
+                else {
+                    /* Transaction originated on this instance */
+                    serviceResponder(rmInst, transaction);
+                }
+            }
         }
-        else {
-            /* Transaction validated.  Return result. */
-            if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-                /* Transaction did not originate on this instance */
-                transactionResponder(rmInst, transaction);
+        else if (transaction->type == Rm_service_RESOURCE_FREE) {     
+            if (transaction->state == RM_SERVICE_PROCESSING) {
+                freeHandler(rmInst, transaction);
+
+                if (transaction->state == RM_SERVICE_PROCESSING) {
+                    /* CD could not handle free.  Forward to Server */
+                    transactionForwarder(rmInst, transaction);
+                }
+                else {
+                    /* Free validated by CD.  Return result */
+                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                        /* Transaction did not originate on this instance */
+                        transactionResponder(rmInst, transaction);
+                    }
+                    else {
+                        /* Transaction originated on this instance */
+                        serviceResponder(rmInst, transaction);
+                    }                    
+                }
             }
             else {
-                /* Transaction originated on this instance */
-                serviceResponder(rmInst, transaction);
+                /* Transaction validated.  Return result. */
+                if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+                    /* Transaction did not originate on this instance */
+                    transactionResponder(rmInst, transaction);
+                }
+                else {
+                    /* Transaction originated on this instance */
+                    serviceResponder(rmInst, transaction);
+                }
             }
         }
 
-        /* Forward any queued static requests (local and received from any registered
-         * Clients that weren't forwarded */
+        /* Attempt allocation of any queued static requests:
+         * RM_SERVICE_APPROVED_STATIC - Originated locally
+         * RM_SERVICE_PROCESSING - Received from any registered Clients */
         while(transQ) {
             if (((transQ->state == RM_SERVICE_PROCESSING) ||
                  (transQ->state == RM_SERVICE_APPROVED_STATIC)) &&
@@ -669,9 +728,12 @@ static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
         case Rm_service_RESOURCE_MAP_TO_NAME:
         case Rm_service_RESOURCE_GET_BY_NAME:
         case Rm_service_RESOURCE_UNMAP_NAME:             
-            if (rmInst->nameServer) {
+            if (rmInst->u.server.nameServer) {
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeInv(rmInst->u.server.nameServer);
+                }                
                 memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
                 nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
                 if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
                     nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
@@ -691,6 +753,10 @@ static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
                 else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
                     transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
                 }
+                
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeWb(rmInst->u.server.nameServer);
+                }
             }
             else {
                 transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
@@ -698,9 +764,12 @@ static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
             break;
     }
 
-    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-        /* Source of transaction was not Server, return transaction via responder */
-        transactionResponder(rmInst, transaction);
+    /* Source of shared server transaction will always be local. */
+    if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+            /* Source of transaction was not Server, return transaction via responder */
+            transactionResponder(rmInst, transaction);
+        }
     }
     /* Otherwise let call stack return transaction result app via Rm_serviceHandler */ 
 }
@@ -809,9 +878,10 @@ void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
         clientProcess(rmInst, transaction);
     }
     else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        clientDelegateProcess(rmInst, transaction);
+        cdProcess(rmInst, transaction);
     }
-    else if (rmInst->instType == Rm_instType_SERVER) {
+    else if ((rmInst->instType == Rm_instType_SERVER) ||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         serverProcess(rmInst, transaction);
     } 
 }
@@ -825,43 +895,87 @@ void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
  * DESCRIPTION: Prints the status (allocate/free status, as well as
  *              owners) for all resources managed by the RM 
  *              instance network.  Also, prints the NameServer name
- *              entries.  This function is only available on server
- *              instances.
+ *              entries.  The number of resource range owners is
+ *              returned as well.  This function is only available on
+ *              server instances.
  */
-void Rm_printResourceStatus(Rm_Handle rmServerHandle)
+int32_t Rm_resourceStatus(Rm_Handle rmServerHandle, int printResources)
 {
     Rm_Inst         *rmInst = (Rm_Inst *)rmServerHandle;
-    Rm_Allocator    *allocator = rmInst->allocators;
+    Rm_Allocator    *allocator = NULL;
     Rm_Owner        *owners;
     Rm_ResourceTree *treeRoot;
     Rm_ResourceNode *treeNode;
+    int32_t          totalResOwners = 0;
+    void            *key; 
 
-    if (rmInst->instType == Rm_instType_SERVER) {
-        while (allocator != NULL) {
-            Rm_osalLog("Resource: %s\n", allocator->resourceName);
+    RM_SS_INST_INV_ENTER_CS(key);
+    RM_SC_INST_INV_ENTER_CS(key);
 
-            treeRoot = allocator->allocatorRootEntry;
+    if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        /* Transfer control to shared server instance */
+        rmInst = rmInst->u.sharedClient.sharedServerHandle;
+    }
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        allocator = rmInst->u.server.allocators;
+        while (allocator) {
+            RM_SS_OBJ_INV(allocator, Rm_Allocator);
+            if (printResources) {
+                Rm_osalLog("Resource: %s\n", allocator->resourceName);
+            }
 
-            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {               
-                Rm_osalLog("          %10d - %10d ", treeNode->base, 
-                                                     treeNode->base + treeNode->length -1);
+            treeRoot = allocator->allocatorRootEntry;
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmResourceTreeInv(treeRoot);
+            }
+            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {
+                if (printResources) {
+                    if ((treeNode->base >= 65536) ||
+                        ((treeNode->base + treeNode->length - 1) >= 65536)) {
+                        /* Print in hex if number is very large */
+                        Rm_osalLog("          0x%08x - 0x%08x ", treeNode->base, 
+                                                                 treeNode->base + treeNode->length - 1);
+                    }
+                    else {
+                        Rm_osalLog("          %10d - %10d ", treeNode->base, 
+                                                             treeNode->base + treeNode->length - 1);
+                    }
+                }
                 
                 if (treeNode->allocationCount == 0) {
-                    Rm_osalLog("FREE\n");
+                    if (printResources) {
+                        Rm_osalLog("FREE\n");
+                    }
                 }
                 else {
                     owners = treeNode->ownerList;
                     while (owners) {
-                        Rm_osalLog("%s ", owners->instNameNode->name);
+                        RM_SS_OBJ_INV(owners, Rm_Owner);
+                        if (printResources) {
+                            Rm_osalLog("%s ", owners->instNameNode->name);
+                        }
+                        totalResOwners++;
                         owners = owners->nextOwner;
                     }
-                    Rm_osalLog("\n");
+                    if (printResources) {
+                        Rm_osalLog("\n");
+                    }
                 }
             }        
-            allocator = allocator->nextAllocator;
+            allocator = allocator->nextAllocator; 
+        }
+        if (printResources) {
+            rmNameServerPrintObjects((Rm_Handle)rmInst);
         }
-        rmNameServerPrintObjects(rmInst->nameServer);
     }
+    else {
+        totalResOwners = RM_ERROR_INVALID_RES_STATUS_INSTANCE;
+    }  
+
+    RM_SS_INST_WB_EXIT_CS(key);
+    return(totalResOwners);
 }
 
 /* FUNCTION PURPOSE: Display status of a RM instance
@@ -870,26 +984,46 @@ void Rm_printResourceStatus(Rm_Handle rmServerHandle)
  *              properties such as the state of all transactions
  *              in the transaction queue and registered transports
  */
-void Rm_printInstanceStatus(Rm_Handle rmHandle)
+void Rm_instanceStatus(Rm_Handle rmHandle)
 {
     Rm_Inst        *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Transport   *transportList = rmInst->transports;
-    Rm_Transaction *transactionQ = rmInst->transactionQueue;
+    Rm_Transport   *transportList = NULL;
+    Rm_Transaction *transactionQ = NULL;
+    void           *key; 
+
+    RM_SS_INST_INV_ENTER_CS(key);
+    RM_SC_INST_INV_ENTER_CS(key);
 
     Rm_osalLog("Instance name: %s\n", rmInst->instName);
+    Rm_osalLog("Handle: 0x%08x\n", rmHandle);    
     if (rmInst->instType == Rm_instType_SERVER) {
-        Rm_osalLog("Type: Server\n");
+        Rm_osalLog("Type:   Server\n");
     }
     else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        Rm_osalLog("Type: Client Delegate\n");
+        Rm_osalLog("Type:   Client Delegate\n");
     }
-    else {
-        Rm_osalLog("Type: Client\n");
+    else if (rmInst->instType == Rm_instType_CLIENT) {
+        Rm_osalLog("Type:   Client\n");
     }
-
+    else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        Rm_osalLog("Type:   Shared Server\n");
+    }
+    else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        Rm_osalLog("Type:   Shared Client\n");
+
+        Rm_osalLog("\nShared Server Properties:\n");
+        /* Transfer to Shared Server instance to print out transport and
+         * transaction status */
+        rmInst = rmInst->u.sharedClient.sharedServerHandle;
+        Rm_osalLog("Instance name: %s\n", rmInst->instName);
+        Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+    }
+    
+    transportList = rmInst->transports;
     if (transportList) {
         Rm_osalLog("\nRegistered Transports:\n");
         while (transportList) {
+            RM_SS_OBJ_INV(transportList, Rm_Transport);
             Rm_osalLog("    Remote instName:    %s\n", transportList->remoteInstName);
             if (transportList->remoteInstType == Rm_instType_SERVER) {
                 Rm_osalLog("    Remote instType:    Server\n");
@@ -906,9 +1040,11 @@ void Rm_printInstanceStatus(Rm_Handle rmHandle)
         }
     }
 
+    transactionQ = rmInst->transactionQueue;
     if (transactionQ) {
         Rm_osalLog("\nQueued Service Transactions:\n");
         while (transactionQ) {
+            RM_SS_OBJ_INV(transactionQ, Rm_Transaction);
             Rm_osalLog("    Service type:       %d\n", transactionQ->type);
             Rm_osalLog("    Service ID:         %d\n", transactionQ->localId);
             Rm_osalLog("    Service srcInstName %s\n", transactionQ->serviceSrcInstName);
@@ -922,6 +1058,7 @@ void Rm_printInstanceStatus(Rm_Handle rmHandle)
             transactionQ = transactionQ->nextTransaction;
         }    
     }
+    RM_SS_INST_WB_EXIT_CS(key);    
 }
 
 /* FUNCTION PURPOSE: RM instance creation and initialization
@@ -932,97 +1069,242 @@ void Rm_printInstanceStatus(Rm_Handle rmHandle)
  */
 Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
 {
-    Rm_Inst *rmInst;
-    void    *globalResourceDtb = NULL;
-    void    *linuxResourceDtb = NULL;
-    bool     addLinux = false;
+    Rm_Inst  *rmInst = NULL;
+    Rm_Inst  *sharedServerInst = NULL;
+    uint32_t  policySize;
+    void     *globalResourceDtb = NULL;
+    void     *linuxResourceDtb = NULL;
+    int       addLinux = RM_FALSE;   
+    void     *key;     
 
     *result = RM_OK;
     
     if ((initCfg->instName == NULL) ||
         ((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {
         *result = RM_ERROR_INVALID_INST_NAME;
-        return (NULL);
+        goto errorExit;
     }
 
     if (initCfg->instType >= Rm_instType_LAST) {
         *result = RM_ERROR_INVALID_INST_TYPE;
+        goto errorExit;
     }
 
     /* Create and initialize instance */
-    rmInst = Rm_osalMalloc (sizeof(Rm_Inst));
-    memset ((void *) rmInst, 0, sizeof(Rm_Inst));
-    rmInst->isLocked = false;
-    rmInst->registeredWithDelegateOrServer = false;
+    rmInst = Rm_osalMalloc(sizeof(*rmInst));
+    memset ((void *)rmInst, 0, sizeof(*rmInst));
+    rmInst->isLocked = RM_FALSE;
+    rmInst->registeredWithDelegateOrServer = RM_FALSE;
     rmInst->transactionSeqNum = transactionInitSequenceNum();
 
     rmInst->instType = initCfg->instType;    
     strncpy (rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);
 
-    if (rmInst->instType == Rm_instType_SERVER) {
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         if (!initCfg->instCfg.serverCfg.globalResourceList ||
             !initCfg->instCfg.serverCfg.globalPolicy) {
             *result = RM_ERROR_INVALID_SERVER_CONFIGURATION;
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
-            return(NULL);
+            goto errorExit;
         }
 
-        rmInst->policy = initCfg->instCfg.serverCfg.globalPolicy;
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            /* Shared Server makes copy of policy in shared memory for Shared Clients
+             * on other cores */
+            policySize = fdt_totalsize(initCfg->instCfg.serverCfg.globalPolicy);
+            /* Align policy size to cache boundary */
+            if (policySize % RM_MAX_CACHE_ALIGN) {
+                policySize += (RM_MAX_CACHE_ALIGN - (policySize % RM_MAX_CACHE_ALIGN));
+            }
+            rmInst->u.server.policySize = policySize;
+            rmInst->u.server.globalPolicy = Rm_osalMalloc(rmInst->u.server.policySize);
+            memcpy(rmInst->u.server.globalPolicy, initCfg->instCfg.serverCfg.globalPolicy, rmInst->u.server.policySize);
+        }
+        else {
+            rmInst->u.server.globalPolicy = initCfg->instCfg.serverCfg.globalPolicy;
+        }
 
         if (initCfg->instCfg.serverCfg.linuxDtb) {
             linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;
-            addLinux = true;
+            addLinux = RM_TRUE;
         }
 
         /* Create valid instance list from policy.  Must be done prior to parsing
          * GRL so that Linux resources can be reserved correctly */
-        rmInst->validInstances = rmPolicyCreateValidInstTree(rmInst->policy, addLinux, result);
-        /* Validate policy assignment strings */
-        *result = rmPolicyValidatePolicy(rmInst->policy, rmInst->validInstances);  
+        rmInst->u.server.globalValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+        if (*result == RM_OK) {
+            *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);  
+        }
+        
+        if (*result != RM_OK) {
+            if (rmInst->u.server.globalValidInstTree) {
+                rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+            }
+            goto errorExit;
+        }
+        else {
+            rmNameServerInit((Rm_Handle)rmInst);
 
-        rmInst->nameServer = rmNameServerInit();
+            globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
 
-        globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
+            if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  
+                *result = rmPolicyValidatePolicyResourceNames((Rm_Handle)rmInst);
+            }
 
-        if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  
-            *result = rmPolicyValidatePolicyResourceNames(rmInst->policy, (void *)rmInst->allocators);
-        }
-        if (*result < RM_OK) {
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
-            return(NULL);
+            if (*result != RM_OK) {
+                rmAllocatorDeleteResources((Rm_Handle)rmInst);
+                rmNameServerDelete((Rm_Handle)rmInst);
+                goto errorExit;
+            }
         }
     }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (initCfg->instCfg.cdCfg.cdPolicy) {
+            rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
+            rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);        
+            if (*result == RM_OK) {
+                *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+            }
 
-    if ((rmInst->instType == Rm_instType_CLIENT) && 
-        (initCfg->instCfg.clientCfg.staticPolicy)) {
-        rmInst->staticInfo.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy; 
-    }
-    else if ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
-             (initCfg->instCfg.cdCfg.staticPolicy)) { 
-        rmInst->staticInfo.staticPolicy = initCfg->instCfg.cdCfg.staticPolicy; 
+            if (*result != RM_OK) {
+                if (rmInst->u.cd.cdValidInstTree) {
+                    rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+                }
+                goto errorExit;
+            }
+        }
+
+        rmInst->u.cd.allocators = NULL;
     }
-    if (rmInst->staticInfo.staticPolicy) {      
-        rmInst->staticInfo.staticValidInstTree = rmPolicyCreateValidInstTree(rmInst->staticInfo.staticPolicy, 
-                                                                             addLinux, result);        
-        if (*result == RM_OK) {
-            /* Validate policy assignment strings */
-            *result = rmPolicyValidatePolicy(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticValidInstTree);
+    else if (rmInst->instType == Rm_instType_CLIENT) {
+        if (initCfg->instCfg.clientCfg.staticPolicy) { 
+            rmInst->u.client.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy;
+            rmInst->u.client.staticValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);        
+            if (*result == RM_OK) {
+                *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+            }
+            
+            if (*result != RM_OK) {
+                if (rmInst->u.client.staticValidInstTree) {
+                    rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+                }
+                goto errorExit;
+            }
         }
-        if (*result != RM_OK) {
-            if (rmInst->staticInfo.staticValidInstTree) {
-                rmPolicyFreeValidInstTree(rmInst->staticInfo.staticValidInstTree);
+    }
+    else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        if (initCfg->instCfg.sharedClientCfg.sharedServerHandle) {
+            rmInst->u.sharedClient.sharedServerHandle = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
+            /* Invalidate the Shared server instance structure on this core to get the latest
+             * instance data. */
+            key = Rm_osalCsEnter();
+            Rm_osalBeginMemAccess((void *)rmInst->u.sharedClient.sharedServerHandle, sizeof(Rm_Inst));
+            sharedServerInst = rmInst->u.sharedClient.sharedServerHandle;
+            if (sharedServerInst->instType != Rm_instType_SHARED_SERVER) {
+                *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+                Rm_osalCsExit(key);
+                goto errorExit;
+            }
+            else {
+                /* Invalidate the policy */
+                Rm_osalBeginMemAccess((void *)sharedServerInst->u.server.globalPolicy, 
+                                      sharedServerInst->u.server.policySize);
             }
-            Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
-            rmInst = NULL;
+            Rm_osalCsExit(key);
+        }
+        else {
+            *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+            goto errorExit;
         }
     }
+
+    if (initCfg->instType == Rm_instType_SHARED_SERVER) {
+        /* Writeback the instance and policy for other cores */
+        Rm_osalEndMemAccess ((void *)rmInst, sizeof(Rm_Inst));
+        Rm_osalEndMemAccess ((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+    }
+    else if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+        /* Create the instance's task blocking mechanism */
+        rmInst->blockHandle = Rm_osalTaskBlockCreate();
+    }
+
     return ((Rm_Handle) rmInst);
+errorExit:
+    if (rmInst) {
+        Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+    }
+    return (NULL); 
+}
+
+/* FUNCTION PURPOSE: Deletes an RM instance
+ ***********************************************************************
+ * DESCRIPTION: Frees all memory associated with an RM instance
+ *              as long as all transports have been unregistered
+ *              and the service handle has been closed
+ */
+int32_t Rm_delete(Rm_Handle rmHandle, int ignorePendingServices)
+{
+    Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+    void    *key; 
+
+    key = Rm_osalCsEnter();
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        Rm_osalBeginMemAccess((void *)rmInst, sizeof(Rm_Inst));
+    }
+
+    if (rmInst->serviceHandle) {
+        return (RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
+    }
+    else if (rmInst->transports) {
+        return (RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
+    }
+    else if (rmInst->transactionQueue && !ignorePendingServices) {
+        return (RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
+    }
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        rmAllocatorDeleteResources(rmHandle);
+        rmNameServerDelete(rmHandle);
+        rmInst->u.server.allocators = NULL;
+
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            Rm_osalFree((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+        }
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        rmAllocatorDeleteResources(rmHandle);
+        rmInst->u.cd.allocators = NULL;
+    }
+
+    if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+        /* Delete valid instance tree */
+        rmPolicyFreeValidInstTree(rmHandle);
+
+        /* Delete any transactions */
+        while(rmInst->transactionQueue) {
+            rmTransactionQueueDelete(rmInst, rmInst->transactionQueue->localId);
+        }
+
+        if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+            /* Delete the instance's task blocking mechanism */
+            Rm_osalTaskBlockDelete(rmInst->blockHandle);
+        }
+        else {
+            Rm_osalEndMemAccess((void *)rmInst, sizeof(Rm_Inst));
+        }
+    }
+
+    Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+   
+    Rm_osalCsExit(key);   
+    return (RM_OK);
 }
 
 /* FUNCTION PURPOSE: Returns RM version information
  ***********************************************************************
  */
-uint32_t Rm_getVersion (void)
+uint32_t Rm_getVersion(void)
 {
     return RM_VERSION_ID;
 }
@@ -1030,7 +1312,7 @@ uint32_t Rm_getVersion (void)
 /* FUNCTION PURPOSE: Returns RM version string
  ***********************************************************************
  */
-const char* Rm_getVersionStr (void)
+const char* Rm_getVersionStr(void)
 {
     return rmVersionStr;
 }