]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
Added Linux example and updated release notes
[keystone-rtos/rm-lld.git] / src / rm.c
index b846210264c2c99ccabafa688029c94f3ed0374e..cfa937e2e484e7d095aa58c78b8470d51bc550bd 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__;
 
 /**********************************************************************
@@ -121,7 +122,10 @@ void createResourceReqPkt(Rm_Packet *rmPkt, char *localInstName, Rm_Transaction
     }
     else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
         resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_USE;
-    }    
+    }   
+    else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+        resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_STATUS;
+    }
     else if (transaction->type == Rm_service_RESOURCE_FREE) {
         resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;
     }
@@ -209,18 +213,24 @@ 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;
     /* Pass back the ID that was provided to the component when it requested
      * the service */
     serviceResponse.serviceId = transaction->localId;
+    /* Owner count will only be set within RM under certain circumstances.  Most of time
+     * it will be RM_RESOURCE_NUM_OWNERS_INVALID */
+    serviceResponse.resourceNumOwners = transaction->resourceInfo.ownerCount;
 
     /* Service was approved and service was an allocate request.  The resource
      * data is passed back to the component */
     if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&
         ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
          (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+         (transaction->type == Rm_service_RESOURCE_FREE) ||
+         (transaction->type == Rm_service_RESOURCE_STATUS) ||
          (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
     {
         strncpy(serviceResponse.resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
@@ -228,11 +238,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->u.callback.serviceCallback) {
+        /* Issue the callback to the requesting component with the response information */
+        transaction->u.callback.serviceCallback(&serviceResponse);
+        /* Delete the transaction from the transaction queue */
+        rmTransactionQueueDelete(rmInst, transaction->localId);
+    }
+    else {
+        rmServiceInternalCallback((Rm_Handle)rmInst);
+    }
+    
     return;
 }
 
@@ -245,43 +260,40 @@ static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
  */
 static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    Rm_Transport    *dstTransport = NULL;
+    Rm_Transport    *dstTransport = transaction->u.respTrans;
     Rm_Packet       *rmPkt = NULL;
     Rm_PacketHandle  pktHandle = NULL;
 
-    if (dstTransport = rmTransportFindRemoteName(rmInst->transports, transaction->pktSrcInstName)) {
-        rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle, 
-                                                  sizeof(Rm_Packet), &pktHandle);
-        if (!rmPkt || !pktHandle) {
-            transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
-            goto errorExit;
-        }
+    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:
-                createResourceResponsePkt(rmPkt, transaction);
-                break;
-            case Rm_service_RESOURCE_MAP_TO_NAME:
-            case Rm_service_RESOURCE_UNMAP_NAME:
-                createNsResponsePkt(rmPkt, transaction);
-                break;
-        }
-        if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
-            transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
-            goto errorExit;
-        }
-        
-        /* Response packet sent: Delete transaction from queue */
-        rmTransactionQueueDelete(rmInst, transaction->localId);
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+        case Rm_service_RESOURCE_STATUS:
+        case Rm_service_RESOURCE_FREE:
+        case Rm_service_RESOURCE_GET_BY_NAME:
+            createResourceResponsePkt(rmPkt, transaction);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+        case Rm_service_RESOURCE_UNMAP_NAME:
+            createNsResponsePkt(rmPkt, transaction);
+            break;
     }
-    else {
-        transaction->state = RM_ERROR_TRANSPORT_REMOTE_HNDL_NOT_REGD;
+    if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+        transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+        goto errorExit;
     }
+    
+    /* Response packet sent: Delete transaction from queue */
+    rmTransactionQueueDelete(rmInst, transaction->localId);
+
 errorExit:
-    /* Do not delete transaction on error.  Error transactions should be visible from
+    /* Do not delete transaction on transport error.  Transport error transactions should be visible
      * from Rm_printInstanceStatus() */
     return;
 }
@@ -322,6 +334,7 @@ static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)
         switch (transaction->type) {
             case Rm_service_RESOURCE_ALLOCATE_INIT:
             case Rm_service_RESOURCE_ALLOCATE_USE:
+            case Rm_service_RESOURCE_STATUS:
             case Rm_service_RESOURCE_FREE:
             case Rm_service_RESOURCE_GET_BY_NAME:
                 createResourceReqPkt(rmPkt, rmInst->instName, transaction);
@@ -336,13 +349,160 @@ static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)
             transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
             goto errorExit;
         }              
-        transaction->hasBeenForwarded = true;
+        transaction->hasBeenForwarded = RM_TRUE;
         /* Transaction not deleted.  Waiting for response from RM CD or Server */
     }
 errorExit: 
+    /* Do not delete transaction on transport error.  Transport error transactions should be visible
+     * from Rm_printInstanceStatus() */               
     return;
 }
 
+/* FUNCTION PURPOSE: Handles static allocation requests
+ ***********************************************************************
+ * DESCRIPTION: Validates allocation requests received on CDs and
+ *              Clients prior to the instance's registering
+ *              with a Server.  The allocation request is validated
+ *              against a static policy.
+ */
+static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transaction)
+{
+    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;
+    void              *staticPolicy = rmPolicyGetPolicy(rmHandle);
+    Rm_PolicyCheckCfg  privCheckCfg;
+    int32_t            result;
+    
+    if (staticPolicy) {
+        if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+            (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+            /* Check request against static policy */
+            memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+    
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                privCheckCfg.type = Rm_policyCheck_INIT;
+            }
+            else {
+                privCheckCfg.type = Rm_policyCheck_USE;
+            }
+            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, &result)) {
+                transaction->state = RM_SERVICE_APPROVED_STATIC;
+            }
+            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;
+        }
+    }
+    else {
+        transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
+    } 
+}
+
+/* FUNCTION PURPOSE: Requests resources from Server for CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to allocate resources
+ *              from the Server for local management by the CD.  The
+ *              transaction which causes this request is put in the
+ *              pending state in order to wait for the response from the 
+ *              Server
+ */
+static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_Transaction *newTrans = NULL;
+    void *          policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    int32_t         resourceOffsetInPolicy;
+    uint32_t        allocSize = 0;
+    int32_t         retVal;
+
+    resourceOffsetInPolicy = rmPolicyGetResourceOffset(policy, transaction->resourceInfo.name);
+    if (resourceOffsetInPolicy > 0) {
+        if (allocSize = rmPolicyGetResourceAllocSize(policy, resourceOffsetInPolicy)) {
+            if (newTrans = rmTransactionQueueAdd(rmInst)) {
+                newTrans->type = transaction->type;
+                strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+                newTrans->state = RM_SERVICE_PROCESSING;       
+                strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+                newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                /* Make sure request length will satisfy transaction length */
+                newTrans->resourceInfo.length = allocSize;
+                while (newTrans->resourceInfo.length < transaction->resourceInfo.length) {
+                    newTrans->resourceInfo.length += allocSize;
+                }
+                newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
+                newTrans->pendingTransactionId = transaction->localId;
+                transactionForwarder(rmInst, newTrans);
+
+                retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+            }
+            else {
+                retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+            }       
+        }
+        else {
+            /* Forward request to Server for completion if policy has 
+             * no allocation size for resource */
+            retVal = RM_SERVICE_PROCESSING;
+        }
+    }
+    else {
+        /* Resource could not be found in policy */
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Frees local resources to Server from CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to free locally
+ *              managed resources that are now localized back to
+ *              the Server.
+ */
+static int32_t cdFreeResourcesToServer(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    int32_t         baseToFree = transaction->resourceInfo.base;
+    uint32_t        lenToFree = transaction->resourceInfo.length;
+    Rm_Transaction *newTrans = NULL; 
+    /* This function should only be called after a free was approved */
+    int32_t         retVal = RM_SERVICE_APPROVED;    
+    
+    /* Did free result in a localized free node that can be given back to Server?  If
+     * so create transaction to Server to free localized resource node */
+    if (rmAllocatorGetNodeLocalization((Rm_Handle)rmInst, transaction->resourceInfo.name,
+                                       &baseToFree, &lenToFree)) {
+        if (newTrans = rmTransactionQueueAdd(rmInst)) {
+            newTrans->type = transaction->type;
+            strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+            newTrans->state = RM_SERVICE_PROCESSING;       
+            strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+            newTrans->resourceInfo.base = baseToFree;
+            newTrans->resourceInfo.length = lenToFree;
+            newTrans->pendingTransactionId = transaction->localId;
+            transactionForwarder(rmInst, newTrans);
+
+            retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+        }
+        else {
+            /* Error: Need to re-allocate what was freed */
+            retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+        }
+    }    
+    return (retVal);
+}
+
 /* FUNCTION PURPOSE: Arbitrates allocation service requests
  ***********************************************************************
  * DESCRIPTION: Issues a set of allocator operations in order to
@@ -353,67 +513,219 @@ errorExit:
  *              retrieved from the NameServer prior to the allocation
  *              attempt.
  */
-static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode,
-                               uint32_t allocType)
+static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    Rm_AllocatorOpInfo  opInfo;
-    Rm_NameServerObjCfg nameServerObjCfg;
-    int32_t             retVal = transaction->state;
+    Rm_AllocatorOpInfo   opInfo;
+    Rm_NameServerObjCfg  nameServerObjCfg;
+    int32_t              retVal = transaction->state;
 
     memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-    
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }        
+                
     if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        /* Forward all allocation requests to Server if transport is up.  Otherwise, just queue. */
-        if (rmInst->registeredWithDelegateOrServer) {
-            transactionForwarder(rmInst, transaction);   
-        }  
-    }
-    else if (rmInst->instType == Rm_instType_SERVER) {
-        opInfo.policy = rmInst->policy;
-        opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = validInstNode;
-        opInfo.allocType = allocType;
+        if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
+            if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                /* Attempt to allocate from local resources that were provided by Server */
+                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);
 
+                if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                    /* Request resource range was not found within local resources
+                     * provided by Server.  Set back to PROCESSING so request is forwarded to
+                     * Server */
+                    retVal = RM_SERVICE_PROCESSING;
+                }
+            }
+        }
+        else {
+            if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                int32_t oldAlign = transaction->resourceInfo.alignment;
+                
+                /* Attempt to allocate from local resources that were provided by Server */
+                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+                }
+                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);
+
+                    if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                        /* Request resource range was not found within local resources
+                         * provided by Server.  Set back to PROCESSING so request is forwarded to
+                         * Server */
+                        retVal = RM_SERVICE_PROCESSING;
+                    }                    
+                }
+                else if (retVal == RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET) {
+                    if (transaction->pendingTransactionId) {
+                        /* Request to Server for resources to complete transaction locally
+                         * performed once already.  Forward transaction to Server for completion */
+                        retVal = RM_SERVICE_PROCESSING;
+                    }
+                    else {
+                        /* Restore base and alignment since they were replaced in pre-allocate routine */
+                        transaction->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                        transaction->resourceInfo.alignment = oldAlign;
+                        
+                        retVal = cdRequestServerResources(rmInst, transaction);
+                    }
+                }
+            }
+            else {
+                retVal = cdRequestServerResources(rmInst, transaction);
+            }                
+        }
+    }
+    else if ((rmInst->instType == Rm_instType_SERVER)||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         /* 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)) {
-                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                nameServerObjCfg.nameServerTree = rmInst->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);
-                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                }                
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            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);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
             }
             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);
         }
-        
-        transaction->state = retVal;
+    
+        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);
+        }             
+    }
+errorExit:        
+    transaction->state = retVal;      
+}
 
-        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-            /* Source of allocation was not the server instance, provide the transaction
-             * to the transaction responder */
-            transactionResponder(rmInst, transaction);
+/* FUNCTION PURPOSE: Handles resource status service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations to retrieve the
+ *              current status (currently just owner reference count)
+ *              for the resource specified in the transaction
+ */
+static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_NameServerObjCfg nameServerObjCfg;
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.operation = Rm_allocatorOp_GET_STATUS;
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }     
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+            /* Attempt to get status from local resources that were provided by Server */
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+            if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                /* Request resource range was not found within local allocator resources
+                 * provided by Server.  Set back to PROCESSING so request is forwarded to
+                 * Server */
+                retVal = RM_SERVICE_PROCESSING;
+            }            
         }
-        /* Otherwise let the return stack return the transaction to the serviceHandler */                   
-    }   
+    }
+    else if ((rmInst->instType == Rm_instType_SERVER)||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base and length values */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            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);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            }
+            else {
+                goto errorExit;
+            }
+        }
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);                 
+    }
+errorExit:        
+    transaction->state = retVal;       
 }
 
 /* FUNCTION PURPOSE: Arbitrates free service requests
@@ -426,58 +738,364 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, voi
  *              retrieved from the NameServer prior to the free
  *              attempt.
  */
-static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)
+static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
     Rm_AllocatorOpInfo  opInfo; 
     Rm_NameServerObjCfg nameServerObjCfg;    
     int32_t             retVal = transaction->state;
 
     memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-    
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        /* Forward all free requests to Server if transport is up.  Otherwise, just queue. */
-        if (rmInst->registeredWithDelegateOrServer) {
-            transactionForwarder(rmInst, transaction);   
-        }
+    opInfo.operation = Rm_allocatorOp_FREE;
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
     }
-    else if (rmInst->instType == Rm_instType_SERVER) {
-        opInfo.policy = rmInst->policy;
-        opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = validInstNode;
 
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+            /* Attempt to free from local resources that were provided by Server */
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+            if (retVal == RM_SERVICE_APPROVED) {
+                /* Check if free allows local resources to be freed back to Server */
+                retVal = cdFreeResourcesToServer(rmInst, transaction);
+            }
+            else if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                /* Request resource range was not found within local allocator resources
+                 * provided by Server.  Set back to PROCESSING so request is forwarded to
+                 * Server */
+                retVal = RM_SERVICE_PROCESSING;
+            }  
+        } 
+    }
+    else if ((rmInst->instType == Rm_instType_SERVER) ||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
         /* 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)) {
-                memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                nameServerObjCfg.nameServerTree = rmInst->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);
-                    transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                    transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                } 
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }                    
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            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);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
             }
             else {
-                retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
-            }                
+                goto errorExit;
+            }             
+        }
+             
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);     
+    }   
+errorExit:
+    transaction->state = retVal;       
+}
+
+/* FUNCTION PURPOSE: Client transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Client process:
+ *                  - Performs static allocations if no transport
+ *                    to CD or Server has been registered
+ *                  - Forwards all service requests to CD or Server
+ *                    once transport has been registered
+ */
+static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_Transaction    *transQ = rmInst->transactionQueue;
+    
+    if (!rmInst->registeredWithDelegateOrServer) {
+        staticAllocationHandler((Rm_Handle)rmInst, transaction);
+    }
+    else {
+        if (transaction->state == RM_SERVICE_PROCESSING) {
+            /* Forward all new transactions to CD or Server */
+            transactionForwarder(rmInst, transaction);                
+        }
+        else {
+            /* Transaction validated.  Return result. */
+            serviceResponder(rmInst, transaction);
+        }
+
+        /* Forward any queued static requests that weren't forwarded */
+        while(transQ) {
+            if ((transQ->state == RM_SERVICE_APPROVED_STATIC) &&
+                (!transQ->hasBeenForwarded)) {
+                transactionForwarder(rmInst, transQ);
+            }
+            transQ = transQ->nextTransaction;
+        }        
+    }
+    /* Let call stack return transaction result app via Rm_serviceHandler */
+}
+
+/* FUNCTION PURPOSE: Client Delegate transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client Delegate process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Client Delegate process:
+ *                  - Performs static allocations if no transport
+ *                    to Server has been registered
+ *                  - Forwards all NameServer related service requests 
+ *                    to Server once transport has been registered
+ *                  - Attempts to complete resource service requests
+ *                    received from registered Clients
+ */
+static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{      
+    Rm_Transaction *newTrans = NULL;
+    Rm_Allocator   *allocator = NULL;
+    Rm_Transaction *transQ = rmInst->transactionQueue;
+
+    if (!rmInst->registeredWithDelegateOrServer) {
+        if ((transaction->state == RM_SERVICE_PROCESSING) &&
+            (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->pendingTransactionId) {
+            Rm_Transaction *pendingTrans = rmTransactionQueueFind(rmInst, transaction->pendingTransactionId);
+            
+            /* Transaction is response from Server for transaction sent to get
+             * information in order to complete pending transaction */
+            if (transaction->state == RM_SERVICE_APPROVED) {
+                if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+                    /* Transfer resource data tied to name to pending transaction */
+                    strncpy(pendingTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+                    pendingTrans->resourceInfo.base = transaction->resourceInfo.base;
+                    pendingTrans->resourceInfo.length = transaction->resourceInfo.length;
+                    /* Delete NS name from pending transaction so Server isn't queried again */
+                    memset(pendingTrans->resourceInfo.nameServerName, 0, RM_NAME_MAX_CHARS);
+                    /* Now that resource values have been retrieved clear pending transaction ID so 
+                     * CD doesn't think a resource request was sent to Server already for more local resources */
+                    pendingTrans->pendingTransactionId = 0;
+
+                    /* Return original transaction to processing state to attempt completion. */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                }
+                else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                         (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+                    /* Add resources provided by Server to those managed by CD */
+                    if (allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                        Rm_ResourceNode *treeNode = NULL;
+                        
+                        treeNode = rmResourceNodeNew(transaction->resourceInfo.base, transaction->resourceInfo.length);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, treeNode);
+                    }
+                    else {
+                        Rm_ResourceRange resRange;
+
+                        memset((void *)&resRange, 0, sizeof(resRange));
+                        resRange.base = transaction->resourceInfo.base;
+                        resRange.length = transaction->resourceInfo.length;
+                        
+                        rmAllocatorCreate((Rm_Handle)rmInst, transaction->resourceInfo.name, &resRange);
+                    }
+
+                    /* Return original transaction to processing state to attempt completion */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                }
+                else if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    /* Local resource freed on Server.  Need to remove from local allocator. */
+                    rmAllocatorDeleteNode((Rm_Handle)rmInst, transaction->resourceInfo.name,
+                                          transaction->resourceInfo.base, transaction->resourceInfo.length);                   
+                    
+                    /* Delete the allocator if there are no nodes left in the tree */
+                    allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name);
+                    if (RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry) == NULL) {
+                        rmAllocatorDelete((Rm_Handle)rmInst, transaction->resourceInfo.name);
+                    }   
+
+                    /* Allow original free to complete */
+                    pendingTrans->state = RM_SERVICE_APPROVED;
+                }
+            }
+            else {
+                if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    /* Error occurred when trying to free local resource on Server.  Reinsert local
+                     * resources freed by original request */
+                    Rm_AllocatorOpInfo   opInfo;
+
+                    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+                    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+                    opInfo.resourceInfo = &pendingTrans->resourceInfo;
+                    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, pendingTrans->serviceSrcInstName);
+                    /* Can't regain the original type of allocate.  Default to init */
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) != RM_SERVICE_APPROVED) {
+                        transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
+                    }                    
+                }
+                /* Transfer error or denial to pending transaction */
+                pendingTrans->state = transaction->state;
+            }
+            rmTransactionQueueDelete(rmInst, transaction->localId);
+            /* Switch to pending transaction */
+            transaction = pendingTrans;
         }
         
-        if(retVal == RM_SERVICE_PROCESSING) {        
-            opInfo.operation = Rm_allocatorOp_FREE;
-            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
-        }       
+        if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+            (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+            (transaction->type == Rm_service_RESOURCE_STATUS) ||
+            (transaction->type == Rm_service_RESOURCE_FREE)) {
+            if ((transaction->state == RM_SERVICE_PROCESSING) &&
+                (strlen(transaction->resourceInfo.nameServerName) > 0)) {   
+                /* Create and forward new transaction to Server to
+                 * retrieve resource data mapped to name */
+                if (newTrans = rmTransactionQueueAdd(rmInst)) {
+                    newTrans->type = Rm_service_RESOURCE_GET_BY_NAME;
+                    strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+                    newTrans->state = RM_SERVICE_PROCESSING;       
+                    strncpy(newTrans->resourceInfo.nameServerName, transaction->resourceInfo.nameServerName, 
+                            RM_NAME_MAX_CHARS);
+                    newTrans->pendingTransactionId = transaction->localId;
+                    transactionForwarder(rmInst, newTrans);
+
+                    transaction->state = RM_SERVICE_PENDING_SERVER_RESPONSE;
+                }
+                else {
+                    transaction->state = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+                }        
+            }                
+        }
 
-        transaction->state = retVal;
+        if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+            (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+            if (transaction->state == RM_SERVICE_PROCESSING) {   
+                allocationHandler(rmInst, transaction);
+            }
+        }
+        else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+            if (transaction->state == RM_SERVICE_PROCESSING) {   
+                statusHandler(rmInst, transaction);
+            }               
+        }        
+        else if (transaction->type == Rm_service_RESOURCE_FREE) {     
+            if (transaction->state == RM_SERVICE_PROCESSING) {
+                freeHandler(rmInst, transaction);
+            }     
+        }
+        /* Forward all NameServer-based transactions */
 
+        if (transaction->state == RM_SERVICE_PROCESSING) {
+            /* CD could not complete transaction.  Forward to Server */
+            transactionForwarder(rmInst, transaction);
+        }
+        else if (transaction->state != RM_SERVICE_PENDING_SERVER_RESPONSE) {
+            /* Transaction completed by CD or completed response received from Server.  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);
+            }                    
+        }           
+
+        /* 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)) &&
+                (!transQ->hasBeenForwarded)) {
+                transactionForwarder(rmInst, transQ);
+            }
+            transQ = transQ->nextTransaction;
+        }        
+    }
+}
+
+/* FUNCTION PURPOSE: Server transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Server process for handling transactions created
+ *              from services received via the service handle or the
+ *              transport.  The Server process:
+ *                  - Validates all service requests received from
+ *                    the service handle and registered CDs and
+ *                    Clients
+ */
+static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_NameServerObjCfg  nameServerObjCfg;        
+
+    switch (transaction->type) {
+        case Rm_service_RESOURCE_STATUS:
+            statusHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_ALLOCATE_INIT:
+        case Rm_service_RESOURCE_ALLOCATE_USE:
+            allocationHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_FREE:               
+            freeHandler(rmInst, transaction);
+            break;
+        case Rm_service_RESOURCE_MAP_TO_NAME:
+        case Rm_service_RESOURCE_GET_BY_NAME:
+        case Rm_service_RESOURCE_UNMAP_NAME:             
+            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->u.server.nameServer;
+                nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+                if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
+                    nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
+                    nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
+                    nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
+                    transaction->state = rmNameServerAddObject(&nameServerObjCfg);
+                }
+                else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+                    if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
+                        RM_SERVICE_PROCESSING) {
+                        strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                        transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                        transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+                        transaction->state = RM_SERVICE_APPROVED;
+                    } 
+                }
+                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;
+            }
+            break;
+    }
+
+    /* 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 allocation was not the server instance, provide the transaction
-             * to the transaction responder */
+            /* Source of transaction was not Server, return transaction via responder */
             transactionResponder(rmInst, transaction);
         }
-        /* Otherwise let the return stack return the transaction to the serviceHandler */        
-    }   
+    }
+    /* Otherwise let call stack return transaction result app via Rm_serviceHandler */ 
 }
 
 /**********************************************************************
@@ -573,190 +1191,23 @@ int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)
     return (retVal);
 }
 
-/* FUNCTION PURPOSE: Processes a transaction
+/* FUNCTION PURPOSE: Routes a transaction for processing
  ***********************************************************************
- * DESCRIPTION: Processes transactions created from services
- *              received via the service handle or the transport.
- *              Transactions will be routed within the RM system
- *              based on the RM instance type and the type of
- *              the transaction.
+ * DESCRIPTION: Routes a received transaction to the appropriate
+ *              instance processing routine
  */
-void rmTransactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
+void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    void                *validInstNode;
-    Rm_PolicyCheckCfg    privCheckCfg;
-    Rm_NameServerObjCfg  nameServerObjCfg;      
-    uint32_t             allocType = 0;    
-
-    /* Handle static transactions originating on this instance.  Any other static transactions will be
-     * stored in transaction queue until all transports are up. */
-    if (((rmInst->instType == Rm_instType_CLIENT) || (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&
-        (!rmInst->registeredWithDelegateOrServer) && 
-        (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
-        if (rmInst->staticInfo.staticPolicy) {
-            if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
-                (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
-                /* Check request against startup policy */
-                memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-
-                if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
-                    privCheckCfg.type = Rm_policyCheck_INIT;
-                }
-                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,
-                                                                        transaction->resourceInfo.name);
-                privCheckCfg.resourceBase = transaction->resourceInfo.base;
-                privCheckCfg.resourceLength = transaction->resourceInfo.length;
-
-                if (rmPolicyCheckPrivilege(&privCheckCfg, &transaction->state)) {
-                    transaction->state = RM_SERVICE_APPROVED_STATIC;
-                }
-                else if (transaction->state == RM_SERVICE_PROCESSING) {
-                    /* Privilege check returned false without error */
-                    transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
-                }
-            }
-            else {
-                transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
-            }
-        }
-        else {
-            transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
-        }        
-    }
-    else {
-        /* Handle auto-forwarded transactions.  These transactions include:
-         * - All request transactions received on Clients are forwarded to the Client Delegate
-         * - NameServer requests received on the Client Delegate are forwarded to the Server */
-        if ((rmInst->instType == Rm_instType_CLIENT) ||
-            ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
-             ((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) &&
-                (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
-                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 {
-                /* Forward request if transport is up.  Otherwise, just queue. */
-                if (rmInst->registeredWithDelegateOrServer) {
-                    transactionForwarder(rmInst, transaction);   
-                } 
-            }
-        }
-        else {
-            /* Validate service's originating instance name */
-            if (rmInst->instType == Rm_instType_SERVER) {
-                validInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);
-                if (validInstNode == NULL) {
-                    transaction->state = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
-
-                    /* Send result via responder if transaction did not originate from this instance */
-                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-                        transactionResponder(rmInst, transaction);
-                    }
-                }
-            }
-
-            switch (transaction->type) {
-                case Rm_service_RESOURCE_ALLOCATE_INIT:
-                case Rm_service_RESOURCE_ALLOCATE_USE:
-                case Rm_service_RESOURCE_FREE:               
-                    if ((transaction->state != RM_SERVICE_PROCESSING) &&
-                        (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
-                        /* Transaction complete */
-                        if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-                            /* Transaction result not destined for this instance */
-                            transactionResponder(rmInst, transaction);
-                        }
-                        else {
-                            /* Transaction result destined for this instance */
-                            serviceResponder(rmInst, transaction);      
-                        }
-                    }
-                    else {
-                        /* Complete allocation/free request */
-                        if (transaction->type == Rm_service_RESOURCE_FREE) {
-                            freeHandler(rmInst, transaction, validInstNode);
-                        }
-                        else {
-                            switch (transaction->type) {
-                                case Rm_service_RESOURCE_ALLOCATE_INIT:
-                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT, 1);
-                                    break;
-                                case Rm_service_RESOURCE_ALLOCATE_USE:
-                                    RM_policy_SET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT, 1);    
-                                    break;
-                            }
-                            allocationHandler(rmInst, transaction, validInstNode, allocType);
-                        }
-                    }
-                    break;
-                case Rm_service_RESOURCE_MAP_TO_NAME:
-                case Rm_service_RESOURCE_GET_BY_NAME:
-                case Rm_service_RESOURCE_UNMAP_NAME:                
-                    /* NameServer resides on server */
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    if (rmInst->nameServer) {
-                        nameServerObjCfg.nameServerTree = rmInst->nameServer;
-                        nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
-                        if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
-                            nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
-                            nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
-                            nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
-                            transaction->state = rmNameServerAddObject(&nameServerObjCfg);
-                        }
-                        else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
-                            if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
-                                RM_SERVICE_PROCESSING) {
-                                strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
-                                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                                transaction->state = RM_SERVICE_APPROVED;
-                            } 
-                        }
-                        else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
-                            transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
-                        }
-                    }
-                    else {
-                        transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
-                    }
-
-                    /* Send result via responder if transaction did not originate from this instance */
-                    if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
-                        transactionResponder(rmInst, transaction);
-                    }
-                    break;
-            }
-        }
+    if (rmInst->instType == Rm_instType_CLIENT) {
+        clientProcess(rmInst, transaction);
     }
-
-    /* Forward any queued requests that weren't forwarded yet */
-    if (rmInst->registeredWithDelegateOrServer) {
-        transaction = rmInst->transactionQueue;
-        while(transaction) {
-            if (((transaction->state == RM_SERVICE_PROCESSING) ||
-                 (transaction->state == RM_SERVICE_APPROVED_STATIC)) &&
-                !transaction->hasBeenForwarded) {
-                transactionForwarder(rmInst, transaction);
-            }
-            transaction = transaction->nextTransaction;
-        }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        cdProcess(rmInst, transaction);
     }
+    else if ((rmInst->instType == Rm_instType_SERVER) ||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        serverProcess(rmInst, transaction);
+    } 
 }
      
 /**********************************************************************
@@ -768,43 +1219,116 @@ void rmTransactionProcessor (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 and CD instances.
  */
-void Rm_printResourceStatus(Rm_Handle rmServerHandle)
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
 {
-    Rm_Inst         *rmInst = (Rm_Inst *)rmServerHandle;
-    Rm_Allocator    *allocator = rmInst->allocators;
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    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_CLIENT) {
+        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");
+        }
+        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+            Rm_osalLog("Type:   Client Delegate\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("\nResource Status:\n\n");
+    }
+
+    if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+        /* Transfer control to shared server instance */
+        rmInst = rmInst->u.sharedClient.sharedServerHandle;
+    }
 
-            RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {               
-                Rm_osalLog("          %10d - %10d ", treeNode->base, 
-                                                     treeNode->base + treeNode->length -1);
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER) ||
+        (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
+        allocator = rmAllocatorGetAllocatorList(rmHandle);
+        
+        if (!allocator) {
+            Rm_osalLog("No resources managed by instance at the moment\n\n");
+        }
+        
+        while (allocator) {
+            RM_SS_OBJ_INV(allocator, Rm_Allocator);
+            if (printResources) {
+                Rm_osalLog("Resource: %s\n", allocator->resourceName);
+            }
+
+            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 ((rmInst->instType == Rm_instType_SERVER) ||
+            (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+            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
@@ -813,27 +1337,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_osalLog("    Remote instName:    %s\n", transportList->remoteInstName);
+            RM_SS_OBJ_INV(transportList, Rm_Transport);
             if (transportList->remoteInstType == Rm_instType_SERVER) {
                 Rm_osalLog("    Remote instType:    Server\n");
             }
@@ -849,9 +1392,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);
@@ -865,6 +1410,7 @@ void Rm_printInstanceStatus(Rm_Handle rmHandle)
             transactionQ = transactionQ->nextTransaction;
         }    
     }
+    RM_SS_INST_WB_EXIT_CS(key);    
 }
 
 /* FUNCTION PURPOSE: RM instance creation and initialization
@@ -875,102 +1421,245 @@ 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;
-        fdt_open_into(rmInst->policy, rmInst->policy, fdt_totalsize(rmInst->policy)); 
+        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;
-            fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));
-            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;
-        fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));
+            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) {
+            *result = RM_ERROR_INVALID_CD_CONFIGURATION;
+            goto errorExit;
+        }        
 
-    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 (rmInst->staticInfo.staticPolicy) {
-        fdt_open_into(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticPolicy, 
-                      fdt_totalsize(rmInst->staticInfo.staticPolicy));       
-        rmInst->staticInfo.staticValidInstTree = rmPolicyCreateValidInstTree(rmInst->staticInfo.staticPolicy, 
-                                                                             addLinux, result);        
+        rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
+        rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);        
         if (*result == RM_OK) {
-            /* Validate policy assignment strings */
-            *result = rmPolicyValidatePolicy(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticValidInstTree);
+            *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
         }
+
         if (*result != RM_OK) {
-            if (rmInst->staticInfo.staticValidInstTree) {
-                rmPolicyFreeValidInstTree(rmInst->staticInfo.staticValidInstTree);
+            if (rmInst->u.cd.cdValidInstTree) {
+                rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+            }
+            goto errorExit;
+        }
+
+        rmInst->u.cd.allocators = NULL;
+    }
+    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;
+            }
+        }
+    }
+    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;
 }
@@ -978,7 +1667,7 @@ uint32_t Rm_getVersion (void)
 /* FUNCTION PURPOSE: Returns RM version string
  ***********************************************************************
  */
-const char* Rm_getVersionStr (void)
+const char* Rm_getVersionStr(void)
 {
     return rmVersionStr;
 }