Created allocator module
authorJustin Sobota <jsobota@ti.com>
Fri, 15 Feb 2013 20:53:46 +0000 (15:53 -0500)
committerJustin Sobota <jsobota@ti.com>
Fri, 15 Feb 2013 20:53:46 +0000 (15:53 -0500)
include/rm_allocatorloc.h [new file with mode: 0644]
include/rm_loc.h
rm_transport.h
src/Module.xs
src/rm.c
src/rm_allocator.c [new file with mode: 0644]
src/rm_policy.c

diff --git a/include/rm_allocatorloc.h b/include/rm_allocatorloc.h
new file mode 100644 (file)
index 0000000..25b7e70
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  file  rm_allocatorloc.h
+ *
+ *  Private data structures and APIS for Resource Manager allocators.
+ *
+ *  ============================================================================
+ *      (C) Copyright 2012-2013, Texas Instruments, Inc.
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  \par
+*/
+
+#ifndef RM_ALLOCATORLOC_H_
+#define RM_ALLOCATORLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Standard includes */
+#include <stdbool.h>
+
+/* RM external includes */
+#include <ti/drv/rm/rm.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rm_internal.h>
+#include <ti/drv/rm/include/rm_treeloc.h>
+
+/* Resource properties extracted from the GRL DTB */
+typedef struct {
+    /* Pointer to a resource's range data within the GRL DTB */
+    const void *rangeData;
+    /* Length in bytes of a resource's range data in the GRL DTB */
+    int32_t     rangeLen;
+    /* Pointer to a resource's NameServer assignment data within the GRL DTB.
+     * Will be NULL if not defined for the resource node. */
+    const void *nsAssignData;
+    /* Length in bytes of a resource's NameServer assignment data in the GRL DTB.
+     * Will be zero if not defined for the resource node. */
+    int32_t     nsAssignLen;
+    /* Pointer to a resource's Linux alias data within the GRL DTB.  Will be
+     * NULL if not defined for the resource node. */
+    const void *linuxAliasData;
+    /* Length in bytes of a resource's Linux alias data data in the GRL DTB.
+     * Will be zero if not defined for the resource node. */
+    int32_t     linuxAliasLen;
+} Rm_ResourceProperties;
+
+/* Resource allocator operations */
+typedef enum {
+    /* Allocate operation */
+    Rm_allocatorOp_ALLOCATE = 0,
+    /* Free operation */
+    Rm_allocatorOp_FREE,
+    /* Preallocate based on Policy DTB information operation */
+    Rm_allocatorOp_PRE_ALLOCATE
+} Rm_AllocatorOp;
+
+/* Allocator operation configuration structure */
+typedef struct {
+    /* Pointer to policy used for validation of allocator operation */
+    void                   *policy;
+    /* RM instance for which the allocator operation is taking place */
+    Rm_PolicyValidInstNode *serviceSrcInstNode;
+    /* Allocator operation type */
+    Rm_AllocatorOp          operation;
+    /* Specifies the type of allocation
+     * a) Allocate to initialize
+     * b) Allocate to use */
+    uint32_t                allocType;
+    /* Resources for which the allocator operation will affect */
+    Rm_ResourceInfo        *resourceInfo;
+    /* Linux kernel resource allocations bypass all policy checks */
+    bool                    LinuxKernelBypass;
+} Rm_AllocatorOpInfo;
+
+/* RM allocator linked list node */
+typedef struct Rm_Allocator_s {
+    /* Resource name for which the allocator was created.  The resource name
+     * must match a resource node defined in both the GRL and the Policy */
+    char                   resourceName[RM_NAME_MAX_CHARS];
+    /* Pointer to the root entry of the allocator tree */
+    void                  *allocatorRootEntry;
+    /* Pointer to next resource allocator node */
+    struct Rm_Allocator_s *nextAllocator;
+} Rm_Allocator;
+
+Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName);
+int32_t rmAllocatorOperation(Rm_Allocator *allocatorList, Rm_AllocatorOpInfo *opInfo);
+int32_t rmAllocatorInitializeResources(Rm_Handle rmHandle, void *globalResourceDtb, void *linuxDtb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RM_ALLOCATORLOC_H_ */
+
index 1379ce68018abc54de7cd08939ca2fc1cb0b1f44..1d0ffb409a65fd7c40a88fddcd2e6d5b417f3fce 100644 (file)
@@ -50,6 +50,7 @@ extern "C" {
 
 /* RM internal includes */
 #include <ti/drv/rm/include/rm_internal.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
 #include <ti/drv/rm/include/rm_policyloc.h>
 #include <ti/drv/rm/include/rm_transportloc.h>
 #include <ti/drv/rm/include/rm_nameserverloc.h>
@@ -85,61 +86,6 @@ typedef struct Rm_Transaction_s {
     struct Rm_Transaction_s *nextTransaction;    
 } Rm_Transaction;
 
-/* Resource properties extracted from the GRL DTB */
-typedef struct {
-    /* Pointer to a resource's range data within the GRL DTB */
-    const void *rangeData;
-    /* Length in bytes of a resource's range data in the GRL DTB */
-    int32_t     rangeLen;
-    /* Pointer to a resource's NameServer assignment data within the GRL DTB.
-     * Will be NULL if not defined for the resource node. */
-    const void *nsAssignData;
-    /* Length in bytes of a resource's NameServer assignment data in the GRL DTB.
-     * Will be zero if not defined for the resource node. */
-    int32_t     nsAssignLen;
-    /* Pointer to a resource's Linux alias data within the GRL DTB.  Will be
-     * NULL if not defined for the resource node. */
-    const void *linuxAliasData;
-    /* Length in bytes of a resource's Linux alias data data in the GRL DTB.
-     * Will be zero if not defined for the resource node. */
-    int32_t     linuxAliasLen;
-} Rm_ResourceProperties;
-
-/* Resource allocator operations */
-typedef enum {
-    /* Allocate operation */
-    Rm_allocatorOp_ALLOCATE = 0,
-    /* Free operation */
-    Rm_allocatorOp_FREE,
-    /* Preallocate based on Policy DTB information operation */
-    Rm_allocatorOp_PRE_ALLOCATE
-} Rm_AllocatorOp;
-
-/* Allocator operation configuration structure */
-typedef struct {
-    /* RM instance for which the allocator operation is taking place */
-    Rm_PolicyValidInstNode *serviceSrcInstNode;
-    /* Allocator operation type */
-    Rm_AllocatorOp          operation;
-    /* Specifies the type of allocation
-     * a) Allocate to initialize
-     * b) Allocate to use */
-    uint32_t                allocType;
-    /* Resources for which the allocator operation will affect */
-    Rm_ResourceInfo        *resourceInfo;
-} Rm_AllocatorOpInfo;
-
-/* RM allocator linked list node */
-typedef struct Rm_Allocator_s {
-    /* Resource name for which the allocator was created.  The resource name
-     * must match a resource node defined in both the GRL and the Policy */
-    char                   resourceName[RM_NAME_MAX_CHARS];
-    /* Pointer to the root entry of the allocator tree */
-    void                  *allocatorRootEntry;
-    /* Pointer to next resource allocator node */
-    struct Rm_Allocator_s *nextAllocator;
-} Rm_Allocator;
-
 /* Static policy information */
 typedef struct {
     /* Pointer to the static policy if provided */
@@ -185,7 +131,6 @@ typedef struct {
 Rm_Transaction *rmTransactionQueueAdd(Rm_Inst *rmInst);
 Rm_Transaction *rmTransactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId);
 int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId);
-Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName);
 void rmTransactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction);
 
 #ifdef __cplusplus
index ede4acc1c4e83e347b7784cebaba875ca27b7ded..f530a7fcad942a0f54dd0fc5256da1bed0aa8476 100644 (file)
@@ -81,7 +81,7 @@ typedef void *Rm_AppTransportHandle;
 /**
  * @brief A void pointer to the start of a registered application transport
  *        packet buffer.  The Rm_PacketHandle may be different from the 
- *        rm_Packet pointer based on the application transport.  For example,
+ *        Rm_Packet pointer based on the application transport.  For example,
  *        for a QMSS based transport the Rm_PacketHandle may point to the
  *        beginning of a Host descriptor where as the Rm_Packet pointer would
  *        point to the beginning of the data buffer linked with the Host
@@ -250,7 +250,9 @@ typedef struct {
  *  @retval
  *      Failure - NULL RM_TransportHandle and result = #RM_ERROR_ALREADY_REGD_SERVER_OR_CD
  *  @retval
- *      Failure - NULL RM_TransportHandle and result = #RM_ERROR_NULL_CALLOUTS_WHEN_VALID 
+ *      Failure - NULL RM_TransportHandle and result = #RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD
+ *  @retval
+ *      Failure - NULL RM_TransportHandle and result = #RM_ERROR_TRANSPORT_SEND_NOT_REGD 
  */
 Rm_TransportHandle Rm_transportRegister(const Rm_TransportCfg *transportCfg, int32_t *result);
 
index b240df90d983746422fdaba7d21bea6edb1b460d..00373459985bcaecca5cee97f06226c70786789c 100644 (file)
@@ -20,6 +20,7 @@ var rmFile = [
     "src/rm_transport.c",
     "src/rm_tree.c",
     "src/rm_dtb_util.c",
+    "src/rm_allocator.c",
     "util/libfdt/fdt.c",
     "util/libfdt/fdt_ro.c",
     "util/libfdt/fdt_rw.c",
index f66643c9974cc4f4231047cf9eb73a78b6b90855..cb51888a8dc5d3cb8c730511765405cc06aba06a 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
 
 /* RM internal includes */
 #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_dtb_utilloc.h>
-#include <ti/drv/rm/include/rm_policyloc.h>
-#include <ti/drv/rm/include/rm_treeloc.h>
 
 /* RM LIBFDT includes */
 #include <ti/drv/rm/util/libfdt/libfdt.h>
 
-/* Tree algorithm includes */
-#include <ti/drv/rm/util/tree.h>
-
 /* RM OSAL layer */
 #include <rm_osal.h>
 
@@ -106,852 +101,6 @@ static uint32_t transactionGetSequenceNum(Rm_Inst *rmInst)
     return (rmInst->transactionSeqNum);
 }
 
-/* FUNCTION PURPOSE: Creates a resource allocator
- ***********************************************************************
- * DESCRIPTION: Returns a newly Created and initialized resource
- *              The allocator is also stored in the RM instance
- *              allocator list.            
- */
-static Rm_Allocator *allocatorAdd(Rm_Inst *rmInst, const char *resourceName)
-{
-    Rm_Allocator *allocators   = rmInst->allocators;
-    Rm_Allocator *newAllocator = NULL;
-
-    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));
-
-    if (newAllocator) {
-        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));
-        strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);
-        newAllocator->allocatorRootEntry = NULL;
-        newAllocator->nextAllocator = NULL;  
-
-        /* Add allocator to end of list */
-        if (allocators) {
-            while (allocators->nextAllocator) {
-                allocators = allocators->nextAllocator;
-            }
-            allocators->nextAllocator = newAllocator;
-        }
-        else {
-            rmInst->allocators = newAllocator;
-        }
-    }
-    return (newAllocator);
-}
-
-/* FUNCTION PURPOSE: Deletes a resource allocator
- ***********************************************************************
- * DESCRIPTION: Deletes a resource allocator based on the given
- *              resource name.  The resource allocator will be
- *              removed from the RM instance allocator list.
- */
-static int32_t allocatorDelete(Rm_Inst *rmInst, char *resourceName)
-{
-    Rm_Allocator *allocator = rmInst->allocators;
-    Rm_Allocator *prevAllocator = NULL;
-    int32_t       retVal = RM_OK;
-
-    while (allocator) {
-        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
-            break;             
-        }
-        prevAllocator = allocator;
-        allocator = allocator->nextAllocator;
-    }
-
-    if (allocator) {
-        if (prevAllocator == NULL) {
-            rmInst->allocators = allocator->nextAllocator;
-        }
-        else {
-            prevAllocator->nextAllocator = allocator->nextAllocator;
-        }
-        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));
-    }
-    else {
-        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
-    }
-    return (retVal);
-}
-
-/* FUNCTION PURPOSE: Adds an owner to an allocator resource
- ***********************************************************************
- * DESCRIPTION: Adds a RM instance node to a resource node's
- *              list of owners.
- */
-static void addOwner(Rm_ResourceNode *node, void *serviceInstNode)
-{
-    Rm_Owner *ownerList = node->ownerList;
-    Rm_Owner *newOwner = NULL;
-
-    newOwner = Rm_osalMalloc(sizeof(Rm_Owner));
-
-    if (newOwner) {
-        newOwner->instNameNode = serviceInstNode;
-        newOwner->nextOwner = NULL;  
-
-        /* Add owner entry to end of list */
-        if (ownerList) {
-            while (ownerList->nextOwner) {
-                ownerList = ownerList->nextOwner;
-            }
-            ownerList->nextOwner = newOwner;
-        }
-        else {
-            node->ownerList = newOwner;
-        }
-
-        node->allocationCount++;
-        newOwner->instNameNode->allocRefCount++;
-    }
-}
-
-/* FUNCTION PURPOSE: Checks a resource node's ownership
- ***********************************************************************
- * DESCRIPTION: Returns TRUE if the provided instance node is
- *              in the list of resource node owners.  Otherwise,
- *              returns FALSE.
- */
-static bool isOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)
-{
-    Rm_Owner *owner = node->ownerList;
-
-    while (owner) {
-        if (owner->instNameNode == serviceInstNode) {
-            return(true);           
-        }
-        owner = owner->nextOwner;
-    }
-    return(false);
-}
-
-/* FUNCTION PURPOSE: Compares two resource node's owners
- ***********************************************************************
- * DESCRIPTION: Returns TRUE if the owners of two resource nodes 
- *              are equivalent.  Otherwise, returns FALSE.
- */
-static bool compareResourceNodeOwners(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
-{
-    Rm_Owner *node1Owners = node1->ownerList;
-    Rm_Owner *node2Owners = node2->ownerList;
-    bool      matchedInst;
-
-    if (node1->allocationCount == node2->allocationCount) {
-        while (node1Owners) {
-            matchedInst = false;
-            while (node2Owners) {
-                if (node1Owners->instNameNode == node2Owners->instNameNode) {
-                    matchedInst = true;
-                    break;
-                }
-                node2Owners = node2Owners->nextOwner;
-            }
-
-            if (matchedInst) {
-                node2Owners = node2->ownerList;
-                node1Owners = node1Owners->nextOwner;
-            }
-            else {
-                return(false);
-            }                
-        }
-    }
-    else {
-        return(false);
-    }  
-    
-    return(true);
-}
-
-/* FUNCTION PURPOSE: Deletes an owner from an allocator resource
- ***********************************************************************
- * DESCRIPTION: Removes a RM instance node from a resource node's
- *              list of owners.
- */
-static void deleteOwner(Rm_ResourceNode *node, void *serviceInstNode)
-{
-    Rm_Owner *owner = node->ownerList;
-    Rm_Owner *prevOwner = NULL;
-
-    while (owner) {
-        if (owner->instNameNode == serviceInstNode) {
-            break;             
-        }
-        prevOwner = owner;
-        owner = owner->nextOwner;
-    }
-
-    if (prevOwner == NULL) {
-        node->ownerList = owner->nextOwner;
-    }
-    else {
-        prevOwner->nextOwner = owner->nextOwner;
-    }
-    
-    node->allocationCount--;
-    owner->instNameNode->allocRefCount--;
-    Rm_osalFree((void *)owner, sizeof(Rm_Owner));
-}
-
-/* FUNCTION PURPOSE: Copies the owners of a resource node
- ***********************************************************************
- * DESCRIPTION: Creates a list of resource owners for the destination
- *              resource node that is equivalent to the the 
- *              source resource node's owners
- */
-static void copyOwners(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
-{
-    Rm_Owner *srcOwnerList = srcNode->ownerList;
-    Rm_Owner *dstNewOwner;
-    Rm_Owner *dstPrevOwner;
-
-    dstNode->allocationCount = srcNode->allocationCount;
-
-    while (srcOwnerList) {
-        dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));
-        dstNewOwner->instNameNode = srcOwnerList->instNameNode;
-        dstNewOwner->nextOwner = NULL;
-
-        if (dstNode->ownerList == NULL) {
-            dstNode->ownerList = dstNewOwner;
-        }
-        else {
-            dstPrevOwner->nextOwner = dstNewOwner;
-        }
-        dstPrevOwner = dstNewOwner;
-        srcOwnerList = srcOwnerList->nextOwner;
-    }
-}
-
-/* FUNCTION PURPOSE: Clears a resource node's owners
- ***********************************************************************
- * DESCRIPTION: Deletes all owners from the owners list of a 
- *              resource node.
- */
-static void clearOwners(Rm_ResourceNode *node)
-{
-    Rm_Owner *owner = node->ownerList;
-    Rm_Owner *nextOwner;
-
-    while (owner) {
-        nextOwner = owner->nextOwner;
-        node->allocationCount--;
-        Rm_osalFree((void *)owner, sizeof(Rm_Owner));
-        owner = nextOwner;
-    }
-}
-
-/* FUNCTION PURPOSE: Creates a new resource tree
- ***********************************************************************
- * DESCRIPTION: Creates a new resource tree using the provided
- *              resource name and value range.  The name and value
- *              typically originate from the GRL.
- */
-static int32_t createResourceTree(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)
-{
-    Rm_Allocator    *allocator = NULL;
-    Rm_ResourceTree *treeRootEntry = NULL;
-    Rm_ResourceNode *treeNode = NULL;
-    Rm_ResourceNode *collidingNode = NULL;
-
-    allocator = allocatorAdd(rmInst, resourceName);
-    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));
-    RB_INIT(treeRootEntry);
-
-    while (range != NULL) {
-        treeNode = rmResourceNodeNew(range->base, range->length);
-        collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
-
-        if (collidingNode) {
-            Rm_ResourceNode *nextNode = NULL;
-            
-            /* Node that was inserted collides with existing node.  Destroy tree and return error */
-            for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {
-                       nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
-                       RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);
-                rmResourceNodeFree(treeNode);
-               }
-            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));
-            allocatorDelete(rmInst, allocator->resourceName);
-            return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);
-        }
-        range = range->nextRange;
-    }
-    
-    allocator->allocatorRootEntry = treeRootEntry;
-    return(RM_OK);
-}
-
-/* FUNCTION PURPOSE: Preallocates a resource
- ***********************************************************************
- * DESCRIPTION: Called when an allocate request is made but the base 
- *              is unspecified.  The preallocation algorithm looks at 
- *              available resources as well as policy permissions to 
- *              determine a resource range that satisfies the request.
- *              If a valid range is found it will be returned for the 
- *              treeAllocate algorithm to handle.
- */
-static int32_t treePreAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,
-                               Rm_AllocatorOpInfo *opInfo)
-{
-    Rm_ResourceNode    findNode;
-    Rm_ResourceNode   *matchingNode = NULL;
-    uint32_t           matchingEnd;
-    uint32_t           rangeIndex;
-    bool               resourceFound = false;
-    Rm_PolicyCheckType policyCheckType;
-    Rm_PolicyCheckCfg  policyCheckCfg;
-    bool               nodePassesPolicy;
-    int32_t            retVal = RM_SERVICE_PROCESSING;    
-
-    opInfo->resourceInfo->base = rmPolicyGetResourceBase(rmInst->policy, opInfo->serviceSrcInstNode, 
-                                                          resourcePolicy, opInfo->allocType, 
-                                                          &retVal);
-    if (retVal != RM_SERVICE_PROCESSING) {
-        return (retVal);
-    }
-
-    if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {  
-        /* Get alignment from policy */
-        opInfo->resourceInfo->alignment = rmPolicyGetResourceAlignment(rmInst->policy, resourcePolicy);
-    }
-    
-    if (opInfo->resourceInfo->alignment == 0) {
-        opInfo->resourceInfo->alignment = 1;
-    }    
-
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
-    findNode.base = opInfo->resourceInfo->base;
-    findNode.length = opInfo->resourceInfo->length;
-
-    /* Configure policy checking structure */
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
-        policyCheckType = Rm_policyCheck_INIT;
-    }
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
-        policyCheckType = Rm_policyCheck_USE;
-    }
-    policyCheckCfg.policyDtb = rmInst->policy;
-    policyCheckCfg.resourceOffset = resourcePolicy;
-    
-    do {
-        matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
-        
-        if (matchingNode) {
-            nodePassesPolicy = false;
-            policyCheckCfg.type = policyCheckType;
-            policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
-            policyCheckCfg.resourceBase = findNode.base;
-            policyCheckCfg.resourceLength = findNode.length;
-            nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);    
-            
-            if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
-                /* Check exclusive privileges of instance requesting resource.  Requesting
-                 * instance with exclusive privileges can't reserve resource if already owned*/
-                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
-                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-            }
-            
-            if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {
-                /* Check exclusive privileges of instance that currently owns resource */
-                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
-                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-            }
-
-            if (retVal != RM_SERVICE_PROCESSING) {
-                break;
-            }
-
-            if (nodePassesPolicy) {
-                matchingEnd = matchingNode->base + matchingNode->length - 1;
-                /* Initialize indexer to be first resource value that alignment */
-                rangeIndex = findNode.base;
-                if (rangeIndex % opInfo->resourceInfo->alignment) {
-                    rangeIndex += (opInfo->resourceInfo->alignment -
-                                  (rangeIndex % opInfo->resourceInfo->alignment));
-                }
-                
-                if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd) {
-                    /* Block of unallocated resources within matchingNode that satisfies
-                     * allocate requirements */
-                    opInfo->resourceInfo->base = rangeIndex;
-                    resourceFound = true;
-                }     
-            }
-            
-            if (!resourceFound) {
-                /* Check next resource node for available resources */
-                findNode.base = matchingNode->base + matchingNode->length;
-            }
-        }
-        else {
-            retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;
-        }
-    } while ((!resourceFound) && 
-             (retVal != RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET));
-
-    return(retVal); 
-}
-
-/* FUNCTION PURPOSE: Allocates a resource
- ***********************************************************************
- * DESCRIPTION: Will attempt to allocate the resource with specified
- *              base and length from the resource's allocator.  The
- *              allocation algorithm will verify the allocation against
- *              the policy permissions for the instance requesting the
- *              allocation.  If the policy allows the allocation the 
- *              algorithm will allocate the resource then combine any
- *              resource nodes that may have become equivalent (in terms
- *              of ownership) after the allocation.
- */
-static int32_t treeAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,
-                            Rm_AllocatorOpInfo *opInfo)
-{
-    Rm_ResourceNode     findNode;
-    Rm_ResourceNode    *matchingNode = NULL;
-    Rm_ResourceNode    *leftNode = NULL;
-    Rm_ResourceNode    *rightNode = NULL;
-    Rm_PolicyCheckType  policyCheckType;    
-    Rm_PolicyCheckCfg   policyCheckCfg;
-    bool                allocPassesPolicy;
-    bool                combineLeft = false;
-    bool                combineRight = false;    
-    uint32_t            findEnd;
-    uint32_t            matchingEnd;  
-    int32_t             retVal = RM_SERVICE_PROCESSING;
-
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
-    findNode.base = opInfo->resourceInfo->base;
-    findNode.length = opInfo->resourceInfo->length;
-    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
-
-    /* Prepare privilege checks */
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
-        policyCheckType = Rm_policyCheck_INIT;
-    }
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
-        policyCheckType = Rm_policyCheck_USE;
-    }
-
-    if (matchingNode) {
-        findEnd = findNode.base + findNode.length - 1;
-        matchingEnd = matchingNode->base + matchingNode->length - 1;
-        
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
-            if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmInst->validInstances)) {
-                /* Bypass policy checks since Linux Kernel has full privileges */
-                allocPassesPolicy = true;
-            }
-            else {
-                policyCheckCfg.policyDtb = rmInst->policy;
-                policyCheckCfg.resourceOffset = resourcePolicy;    
-                policyCheckCfg.type = policyCheckType;
-                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
-                policyCheckCfg.resourceBase = findNode.base;
-                policyCheckCfg.resourceLength = findNode.length;
-                allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-                if (!allocPassesPolicy) {
-                    if (policyCheckType == Rm_policyCheck_INIT) {
-                        retVal = RM_SERVICE_DENIED_INIT_PERM_NOT_GIVEN;
-                    }
-                    else {
-                        retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;
-                    }
-                }
-
-                if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
-                    /* Perform exclusive checks if requesting instance does not already an
-                     * owner of the resource */
-                    if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
-                        /* Check exclusive privileges of instance requesting resource.  Requesting
-                         * instance with exclusive privileges can't reserve resource if already owned*/
-                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                        policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
-                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-                        if (!allocPassesPolicy) {
-                            retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;
-                        }
-                    }
-                    if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {
-                        /* Check exclusive privileges of instance that currently owns resource */
-                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                        policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
-                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-                        if (!allocPassesPolicy) {
-                            retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;
-                        }                
-                    }  
-                }
-            }
-            
-            if (allocPassesPolicy) {
-                if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
-                    /* Handle any possible node combinations if requesting instance is
-                     * not already in resource's owner list.  Automatic approval if requesting
-                     * instance is already in owner list. */
-                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
-                        /* findNode range matches matchingNode range
-                         *
-                         *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
-                         *                    |<--alloc request-->|  => requested resources
-                         */                     
-                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
-
-                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            combineLeft = true;
-                        }
-                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                            combineRight = true;
-                        }
-
-                        if (combineLeft && combineRight) {
-                            /* Combine all three nodes into matchingNode */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
-
-                            clearOwners(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            clearOwners(rightNode);
-                            rmResourceNodeFree(rightNode);                        
-                        }
-                        else if (combineLeft) {
-                            /* Combine left and matching nodes.  Reinsert right. */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length += leftNode->length;
-
-                            clearOwners(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
-                        }
-                        else if (combineRight) {
-                            /* Combine right and matching nodes.  Reinsert left. */
-                            matchingNode->length += rightNode->length;
-
-                            clearOwners(rightNode);
-                            rmResourceNodeFree(rightNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        }
-                        else {
-                            /* No combine. */
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                        }
-
-                        /* Always reinsert matchingNode */                
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);   
-                    }   
-                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
-                        /* findNode range is subset of matchingNode range and neither boundary is
-                         * equivalent.
-                         *
-                         * |<----------matched node---------->|
-                         *        |<---alloc request--->|
-                         */ 
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
-                        copyOwners(leftNode, matchingNode);
-                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
-                        copyOwners(rightNode, matchingNode);
-
-                        matchingNode->base = findNode.base;                                    
-                        matchingNode->length = findNode.length;
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
-
-                        /* Insert all the nodes */
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                    }  
-                    else {    
-                        if (findNode.base == matchingNode->base) {
-                            /* findNode base and matchingNode base are equivalent.  May be combine
-                             * possibilities to the left
-                             *
-                             * |<---left node (alloc'd)--->||<----------matched node---------->|
-                             *                              |<---findNode (alloc req)--->|
-                             */                         
-                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            /* Add allocating instance to owner list for compare with leftNode */
-                            addOwner(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                                /* Combine leftNode and findNode */
-                                leftNode->length += findNode.length;
-                            }
-                            else {
-                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                copyOwners(leftNode, matchingNode);
-                            }
-
-                            /* Account for leftNode in matchingNode */
-                            matchingNode->base = findNode.base + findNode.length;
-                            matchingNode->length = matchingEnd - findEnd;  
-
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        }
-                        else if (findEnd == matchingEnd) {
-                            /* findNode end and matchingNode end are equivalent.  May be combine
-                             * possibilities to the right
-                             *
-                             * |<----------matched node---------->||<---right node (alloc'd)--->|
-                             *       |<---findNode (alloc req)--->| 
-                             */                        
-                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            /* Add allocating instance to owner list for compare with rightNode */
-                            addOwner(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                                /* Combine rightNode and findNode */
-                                rightNode->base = findNode.base;
-                                rightNode->length += findNode.length;
-                            }
-                            else {
-                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                copyOwners(rightNode, matchingNode);
-                            }
-
-                            /* Account for rightNode in matchingNode */
-                            matchingNode->length -= findNode.length;  
-
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                        }
-                        /* Remove allocating instance from leftover matchingNode */
-                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                    }
-                }
-                retVal = RM_SERVICE_APPROVED;
-            }
-        }
-        else {
-            retVal = RM_SERVICE_DENIED_PARTIAL_ALLOCATION;
-        }
-    }
-    else {
-        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
-    }
-
-    return(retVal);        
-}
-
-/* FUNCTION PURPOSE: Frees a resource
- ***********************************************************************
- * DESCRIPTION: Will attempt to free the resource with specified
- *              base and length from the resource's allocator.  The
- *              free algorithm will verify the free request parameters
- *              match an allocated range for the resource and that the
- *              range is owned by the instance requesting the free. If
- *              the free is validated the algorithm will free the 
- *              resource then combine any resource nodes that may have
- *              become equivalent (in terms of ownership) after the
- *              allocation.
- */
-static int32_t treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
-{
-    Rm_ResourceNode  findNode;
-    Rm_ResourceNode *matchingNode = NULL;
-    Rm_ResourceNode *leftNode = NULL;
-    Rm_ResourceNode *rightNode = NULL;
-    bool             combineLeft = false;
-    bool             combineRight = false;
-    uint32_t         findEnd;
-    uint32_t         matchingEnd;
-    int32_t          retVal;
-
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
-    findNode.base = opInfo->resourceInfo->base;
-    findNode.length = opInfo->resourceInfo->length;
-    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
-
-    if (matchingNode) {
-        findEnd = findNode.base + findNode.length - 1;
-        matchingEnd = matchingNode->base + matchingNode->length - 1;
-        
-        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {  
-            if (matchingNode->allocationCount) {
-                if (isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
-                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
-                    {
-                        /* Case 1: Free range equals allocated matched node exactly. Attempt to combine 
-                         *         freed node with nodes to left and right.
-                         *
-                         * |<--left node-->||<---matched node--->||<--right node-->|
-                         *                  |<---free request--->|
-                         */ 
-                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
-
-                        if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            combineLeft = true;
-                        }
-                        if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                            combineRight = true;
-                        }
-
-                        if (combineLeft && combineRight) {
-                            /* Combine all three nodes into matchingNode */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
-
-                            clearOwners(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            clearOwners(rightNode);
-                            rmResourceNodeFree(rightNode);                        
-                        }
-                        else if (combineLeft) {
-                            /* Combine left and matching nodes.  Reinsert right. */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length += leftNode->length;
-
-                            clearOwners(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
-                        }
-                        else if (combineRight) {
-                            /* Combine right and matching nodes.  Reinsert left. */
-                            matchingNode->length += rightNode->length;
-
-                            clearOwners(rightNode);
-                            rmResourceNodeFree(rightNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        }
-                        else {
-                            /* No combine. */
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                        }
-
-                        /* Always reinsert matchingNode */
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);                    
-                    }
-                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
-                        /* Case 2: Free range is less than range in matched node. Split
-                         *         matched node into three nodes.
-                         *
-                         * |<----------matched node---------->|
-                         *        |<---free request--->|
-                         *
-                         * Remove instance from AllocatedTo list then add it back in for side nodes for
-                         * proper accounting of allocations in validInstance list
-                         */ 
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
-                        
-                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
-                        copyOwners(leftNode, matchingNode);
-                        addOwner(leftNode, opInfo->serviceSrcInstNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        
-                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
-                        copyOwners(rightNode, matchingNode);
-                        addOwner(rightNode, opInfo->serviceSrcInstNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-
-                        matchingNode->base = findNode.base;                                    
-                        matchingNode->length = findNode.length;
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                    }
-                    else {                        
-                        if (findNode.base == matchingNode->base) {
-                            /* Case 3: Free range is on left boundary of matched node. Try to 
-                             *         combine free range with left node.
-                             *
-                             * |<---left node (free)--->||<----------matched node---------->|
-                             *                           |<---findNode (free req)--->|
-                             */ 
-
-                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            /* Remove freeing instance from owner list for compare with leftNode */
-                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                                /* Combine leftNode and findNode */
-                                leftNode->length += findNode.length;
-                            }
-                            else {
-                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                copyOwners(leftNode, matchingNode);
-                            }
-
-                            /* Remove leftNode range from matchingNode */
-                            matchingNode->base = findNode.base + findNode.length;
-                            matchingNode->length = matchingEnd - findEnd;  
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        }
-                        else if (findEnd == matchingEnd) {
-                            /* Case 4: Free range is on right boundary of matched node. Try to 
-                             *         combine free range with right node.
-                             *
-                             * |<----------matched node---------->||<---right node (free)--->|
-                             *        |<---findNode (free req)--->|
-                             */ 
-                            
-                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); 
-                            /* Remove freeing instance from owner list for compare with rightNode */
-                            deleteOwner(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                                /* Combine rightNode and findNode */
-                                rightNode->base = findNode.base;
-                                rightNode->length += findNode.length;
-                            }
-                            else {
-                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                copyOwners(rightNode, matchingNode);
-                            }
-
-                            /* Remove rightNode range from matchingNode */
-                            matchingNode->length -= findNode.length;  
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                        }
-
-                        /* Add freeing instance back into matchingNode allocations */
-                        addOwner(matchingNode, opInfo->serviceSrcInstNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                    }
-
-                    retVal = RM_SERVICE_APPROVED;
-                }
-                else {
-                    retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
-                }
-            }
-            else {
-                retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
-            }
-        }
-        else {
-            retVal = RM_SERVICE_DENIED_PARTIAL_FREE;
-        }
-    }
-    else {
-        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
-    }
-    return(retVal);  
-}
-
-
 /* FUNCTION PURPOSE: Creates a resource request packet
  ***********************************************************************
  * DESCRIPTION: Returns a RM packet handle that points to a RM
@@ -1194,38 +343,6 @@ errorExit:
     return;
 }
 
-/* FUNCTION PURPOSE: Issues an allocator operation
- ***********************************************************************
- * DESCRIPTION: Issues an allocator preallocate, allocate, or free
- *              for an RM resource.
- */
-static int32_t allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)
-{
-    Rm_Allocator *allocator = NULL;
-    int32_t       resourceOffsetInPolicy;
-    int32_t       retVal;
-    
-    resourceOffsetInPolicy = rmPolicyGetResourceOffset(rmInst->policy, opInfo->resourceInfo->name);
-    allocator = rmAllocatorFind(rmInst->allocators, opInfo->resourceInfo->name);
-    
-    if ((resourceOffsetInPolicy > 0) && allocator) {
-        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {
-            retVal = treePreAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);
-        }               
-        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {
-            retVal = treeAllocate(rmInst, allocator, resourceOffsetInPolicy, opInfo);
-        }
-        else if (opInfo->operation == Rm_allocatorOp_FREE) {
-            retVal = treeFree(allocator, opInfo);
-        }         
-    }
-    else {
-        /* Resource could not be found in policy and/or allocator */
-        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
-    }
-    return(retVal);
-}
-
 /* FUNCTION PURPOSE: Arbitrates allocation service requests
  ***********************************************************************
  * DESCRIPTION: Issues a set of allocator operations in order to
@@ -1252,8 +369,15 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, voi
         }  
     }
     else if (rmInst->instType == Rm_instType_SERVER) {
+        opInfo.policy = rmInst->policy;
         opInfo.resourceInfo = &transaction->resourceInfo;
         opInfo.serviceSrcInstNode = validInstNode;
+        if (validInstNode == rmPolicyGetLinuxInstNode(rmInst->validInstances)) {
+            opInfo.LinuxKernelBypass = true;
+        }
+        else {
+            opInfo.LinuxKernelBypass = false;
+        }
         opInfo.allocType = allocType;
 
         /* Populated NameServer name has precedence over base */
@@ -1278,12 +402,12 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, voi
         if (retVal == RM_SERVICE_PROCESSING) {      
             if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
                 opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;
-                retVal = allocatorOperation(rmInst, &opInfo);
+                retVal = rmAllocatorOperation(rmInst->allocators, &opInfo);
             }
         
             if (retVal == RM_SERVICE_PROCESSING) {
                 opInfo.operation = Rm_allocatorOp_ALLOCATE;
-                retVal = allocatorOperation(rmInst, &opInfo);
+                retVal = rmAllocatorOperation(rmInst->allocators, &opInfo);
             }      
         }
         
@@ -1323,6 +447,7 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *val
         }
     }
     else if (rmInst->instType == Rm_instType_SERVER) {
+        opInfo.policy = rmInst->policy;
         opInfo.resourceInfo = &transaction->resourceInfo;
         opInfo.serviceSrcInstNode = validInstNode;
 
@@ -1347,7 +472,7 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *val
         
         if(retVal == RM_SERVICE_PROCESSING) {        
             opInfo.operation = Rm_allocatorOp_FREE;
-            retVal = allocatorOperation(rmInst, &opInfo);
+            retVal = rmAllocatorOperation(rmInst->allocators, &opInfo);
         }       
 
         transaction->state = retVal;
@@ -1361,326 +486,6 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *val
     }   
 }
 
-/* FUNCTION PURPOSE: Reserves a Linux resource
- ***********************************************************************
- * DESCRIPTION: Reserves resources for Linux using the base and length
- *              values retrieved from the Linux DTB via the
- *              "linux-dtb-alias" properties within the GRL.
- */
-static int32_t reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, 
-                                    Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)
-{
-    int32_t  retVal = RM_OK;
-    bool     baseFound = false;
-    bool     lengthFound = false;
-    uint32_t valueIndex = 0;
-
-    while ((linuxValues) && (!baseFound || !lengthFound)) {
-        if (linuxAlias->baseOffset == valueIndex) {
-            opInfo->resourceInfo->base = linuxValues->value;
-            baseFound = true;
-
-            if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
-                opInfo->resourceInfo->length = 1;
-                lengthFound = true;
-            }
-        }
-        else if (linuxAlias->lengthOffset == valueIndex) {
-            opInfo->resourceInfo->length = linuxValues->value;
-            lengthFound = true;
-        }
-
-        linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;
-        valueIndex++;
-    }
-
-    if (!baseFound || !lengthFound) {
-        retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
-    }
-    else {
-        /* Allocate resource to Linux */
-        retVal = allocatorOperation(rmInst, opInfo);
-    }
-    return (retVal);
-}
-
-/* FUNCTION PURPOSE: Finds and reserves Linux resources
- ***********************************************************************
- * DESCRIPTION: Parses the Linux DTB for resources consumed by the
- *              Linux kernel.  If the resource is found via the
- *              "linux-dtb-alias" property defined in the GRL it is 
- *              reserved.
- */
-static int32_t findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName, void *linuxDtb, 
-                                           Rm_LinuxAlias *linuxAlias)
-{
-    Rm_AllocatorOpInfo  opInfo;
-    Rm_ResourceInfo     resourceInfo;
-    uint32_t            pathOffset;
-    uint32_t            pathSize;
-    char               *spacePtr;
-    int32_t             propOffset;
-    int32_t             nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
-    int32_t             prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
-    int32_t             depth;
-    int32_t             propertyLen;
-    const char         *propertyName;
-    const void         *propertyData; 
-    Rm_LinuxValueRange *linuxValueRange;
-    int32_t             retVal = RM_OK; 
-
-    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));
-
-    strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
-    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->validInstances);
-    opInfo.operation = Rm_allocatorOp_ALLOCATE;
-    opInfo.resourceInfo = &resourceInfo;    
-
-    while(linuxAlias) {
-        /* Reset parsing variables */
-        pathOffset = 0;
-        pathSize = strlen(linuxAlias->path) + 1;
-        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
-        prevDepth = RM_DTB_UTIL_STARTING_DEPTH;   
-        resourceInfo.base = 0;
-        resourceInfo.length = 0;
-
-        spacePtr = strpbrk(linuxAlias->path, " ");
-        if (spacePtr) {
-            *spacePtr = '\0';
-        }       
-        
-        while(pathOffset < pathSize) {
-            /* Move through DTB nodes until next alias path node found */
-            if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {
-                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);
-
-                if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {
-                    /* Returning from subnode that matched part of alias path without finding
-                     * resource values */
-                    retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
-                    break;
-                }
-            }
-            else {
-                /* Found next alias path node.  Move to next node name in path string. */
-                pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
-                spacePtr = strpbrk(linuxAlias->path + pathOffset, " ");
-                if (spacePtr) {
-                    *spacePtr = '\0';
-                }       
-                
-                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);
-               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);
-                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
-                       (pathOffset < pathSize)) {
-                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, 
-                                                         &propertyName, &propertyLen);
-
-                    if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0) {
-                        /* Found resource at end of alias path */
-                        pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
-                        linuxValueRange = rmDtbUtilLinuxExtractValues(propertyData, propertyLen);
-                        retVal = reserveLinuxResource(rmInst, linuxAlias, 
-                                                      linuxValueRange, &opInfo);
-                        rmDtbUtilLinuxFreeValues(linuxValueRange);
-                    }
-                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);
-                } 
-
-                if (propOffset < -FDT_ERR_NOTFOUND) {
-                    retVal = propOffset;
-                    break;
-                }
-            }
-        }
-
-        if (retVal < RM_OK) {
-            break;
-        }
-        linuxAlias = linuxAlias->nextLinuxAlias;
-    }
-    return (retVal);
-}
-
-/* FUNCTION PURPOSE: Creates and initializes a resource allocator
- ***********************************************************************
- * DESCRIPTION: Creates a resource allocator for the provided
- *              resource name and resource properties retrieved
- *              from the GRL.  Resources will be reserved for 
- *              the Linux kernel if the Linux DTB is provided
- *              and there are "linux-dtb-alias" properties
- *              specified in the GRL.
- */
-static int32_t createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, 
-                                      Rm_ResourceProperties *resourceProperties, void *linuxDtb)
-{
-    Rm_ResourceRange    *range = NULL;
-    Rm_ResourceRange    *rangeBasePtr = NULL;
-    Rm_NsAssignment     *nsAssignments = NULL;
-    Rm_NsAssignment     *nsAssignmentBasePtr = NULL;
-    Rm_LinuxAlias       *linuxAlias = NULL;
-    Rm_NameServerObjCfg  nameServerObjCfg;      
-    int32_t              retVal = RM_OK;
-
-    if (resourceProperties->rangeData && (resourceProperties->rangeLen > 0)) {
-        range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, 
-                                                        resourceProperties->rangeLen);
-        
-        if ((retVal = createResourceTree(rmInst, resourceName, range)) >= RM_OK) {
-            if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
-                if (linuxDtb) {
-                    linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
-                                                               resourceProperties->linuxAliasLen, &retVal);
-                    if (linuxAlias) {
-                        retVal = findAndReserveLinuxResource(rmInst, resourceName, linuxDtb, linuxAlias);            
-                    }
-                }
-                else {
-                    retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;
-                }
-            }
-        }
-    }
-    
-    if (retVal >= RM_OK) {
-        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen) {
-            nsAssignments = rmDtbUtilResExtractNsAssignment(resourceProperties->nsAssignData, 
-                                                            resourceProperties->nsAssignLen, &retVal);
-            if (nsAssignments) {
-                nsAssignmentBasePtr = nsAssignments;
-                while (nsAssignments) {
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->nameServer;
-                    nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
-                    nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
-                    nameServerObjCfg.nodeCfg.resourceBase= nsAssignments->resourceBase;
-                    nameServerObjCfg.nodeCfg.resourceLength = nsAssignments->resourceLength;                
-                    rmNameServerAddObject(&nameServerObjCfg);
-                    nsAssignments = nsAssignments->nextNsAssignment;
-                }
-                rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
-            }
-        }
-    }
-
-    rmDtbUtilResFreeRange(rangeBasePtr);
-    if (linuxAlias) {
-        rmDtbUtilResFreeLinuxAlias(linuxAlias);
-    }
-    return(retVal);
-}
-
-/* FUNCTION PURPOSE: Recursively parses GRL resource properties
- ***********************************************************************
- * DESCRIPTION: Recursively parses and stores GRL resource node 
- *              properties using the LIBFDT APIs
- */
-static int32_t parseResourceProperty(void *globalResourceDtb, int32_t offset, 
-                                     Rm_ResourceProperties *propertyInfo)
-{
-       int32_t              propertyLen;
-       const char          *propertyName;
-       const void          *propertyData;
-    Rm_ResourcePropType  propertyType;
-    int32_t              retVal = RM_OK;
-
-       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);
-    propertyType = rmDtbUtilResGetPropertyType(propertyName);
-    if (propertyType == Rm_resourcePropType_RESOURCE_RANGE) {
-        propertyInfo->rangeData = propertyData;
-        propertyInfo->rangeLen = propertyLen;
-    }
-    else if (propertyType == Rm_resourcePropType_NSASSIGNMENT) {
-        propertyInfo->nsAssignData = propertyData;
-        propertyInfo->nsAssignLen = propertyLen;
-    }
-    else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS) {
-        propertyInfo->linuxAliasData = propertyData;
-        propertyInfo->linuxAliasLen = propertyLen;
-    }        
-    else {
-        retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;
-    }
-
-    if (retVal == RM_OK) {
-        offset = fdt_next_property_offset(globalResourceDtb, offset);
-       if (offset >= 0) {
-           retVal = parseResourceProperty(globalResourceDtb, offset, propertyInfo);
-       }
-        else if (offset != -FDT_ERR_NOTFOUND) {
-            /* Error returned by LIBFDT */
-            retVal = offset;
-        }
-    }
-    return (retVal);
-}
-
-/* FUNCTION PURPOSE: Recursively parses GRL resource nodes
- ***********************************************************************
- * DESCRIPTION: Recursively parses GRL resource nodes looking for
- *              resource properties to create the resource allocators.
- *              The LIBFDT APIs are used to parse the GRL.
- */
-static int32_t parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t nodeOffset, int32_t depth,
-                                 void *linuxDtb)
-{
-       const char            *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);
-    Rm_ResourceProperties  resourceProperties;
-       int32_t                retVal = RM_OK;
-       int32_t                offset;
-
-    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));
-    /* Get properties of resource node */
-       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
-       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
-               retVal =  parseResourceProperty(globalResourceDtb, offset, &resourceProperties);
-        if (retVal < -FDT_ERR_NOTFOUND) {
-            return (retVal);
-        }
-        if (retVal = createAndInitAllocator(rmInst, resourceName, &resourceProperties, linuxDtb) < RM_OK) {
-            return (retVal);
-        }
-       }
-    else if (offset != -FDT_ERR_NOTFOUND) {
-               /* Error returned by LIBFDT */
-        return (offset);
-    }
-    
-       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);
-    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
-        retVal = parseResourceNode(rmInst, globalResourceDtb, offset, depth, linuxDtb);
-        if (retVal < -FDT_ERR_NOTFOUND) {
-            return (retVal);
-        }
-    }
-    else if (offset != -FDT_ERR_NOTFOUND) {
-        /* Error returned by LIBFDT */
-        return (offset);
-    }
-    return (retVal);
-}
-
-/* FUNCTION PURPOSE: Initializes server allocators
- ***********************************************************************
- * DESCRIPTION: Creates and initializes a server instance's
- *              resource allocators using the GRL and, if
- *              provided, Linux DTB.
- */
-static int32_t initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *linuxDtb)
-{
-    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
-    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;
-    int32_t result = RM_OK;
-
-    /* Recursively parse the Global Resource List, creating an allocator for
-     * each resource as specified in the node */
-    result = parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth, linuxDtb);
-
-    return(result);
-}
-
 /**********************************************************************
  ********************** Internal Functions ****************************
  **********************************************************************/
@@ -1774,23 +579,6 @@ int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)
     return (retVal);
 }
 
-/* FUNCTION PURPOSE: Finds an allocator
- ***********************************************************************
- * DESCRIPTION: Returns a pointer to an allocator that matches the 
- *              provided resource name.
- */
-Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
-{
-    while (allocatorList) {
-        if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
-            break;             
-        }
-        allocatorList = allocatorList->nextAllocator;
-    }
-
-    return (allocatorList);
-}
-
 /* FUNCTION PURPOSE: Processes a transaction
  ***********************************************************************
  * DESCRIPTION: Processes transactions created from services
@@ -2149,7 +937,7 @@ Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
         globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
         fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));
 
-        if ((*result = initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  
+        if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {  
             *result = rmPolicyValidatePolicyResourceNames(rmInst->policy, (void *)rmInst->allocators);
         }
         if (*result < RM_OK) {
diff --git a/src/rm_allocator.c b/src/rm_allocator.c
new file mode 100644 (file)
index 0000000..d87d00d
--- /dev/null
@@ -0,0 +1,1287 @@
+/**
+ *   @file  rm_allocator.c
+ *
+ *   @brief   
+ *      This is the Resource Manager allocator source.
+ *
+ *  \par
+ *  ============================================================================
+ *  @n   (C) Copyright 2012-2013, Texas Instruments, Inc.
+ * 
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met:
+ *
+ *    Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *    Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the   
+ *    distribution.
+ *
+ *    Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  \par
+*/
+
+/* RM external includes */
+#include <ti/drv/rm/rm.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
+#include <ti/drv/rm/include/rm_dtb_utilloc.h>
+#include <ti/drv/rm/include/rm_policyloc.h>
+#include <ti/drv/rm/include/rm_treeloc.h>
+
+/* RM LIBFDT includes */
+#include <ti/drv/rm/util/libfdt/libfdt.h>
+
+/* Tree algorithm includes */
+#include <ti/drv/rm/util/tree.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/**********************************************************************
+ ************************ Local Functions *****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Creates a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Returns a newly Created and initialized resource
+ *              The allocator is also stored in the RM instance
+ *              allocator list.            
+ */
+static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
+{
+    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator *allocators   = rmInst->allocators;
+    Rm_Allocator *newAllocator = NULL;
+
+    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));
+
+    if (newAllocator) {
+        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));
+        strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);
+        newAllocator->allocatorRootEntry = NULL;
+        newAllocator->nextAllocator = NULL;  
+
+        /* Add allocator to end of list */
+        if (allocators) {
+            while (allocators->nextAllocator) {
+                allocators = allocators->nextAllocator;
+            }
+            allocators->nextAllocator = newAllocator;
+        }
+        else {
+            rmInst->allocators = newAllocator;
+        }
+    }
+    return (newAllocator);
+}
+
+/* FUNCTION PURPOSE: Deletes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator based on the given
+ *              resource name.  The resource allocator will be
+ *              removed from the RM instance allocator list.
+ */
+static int32_t allocatorDelete(Rm_Handle rmHandle, char *resourceName)
+{
+    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;    
+    Rm_Allocator *allocator = rmInst->allocators;
+    Rm_Allocator *prevAllocator = NULL;
+    int32_t       retVal = RM_OK;
+
+    while (allocator) {
+        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        prevAllocator = allocator;
+        allocator = allocator->nextAllocator;
+    }
+
+    if (allocator) {
+        if (prevAllocator == NULL) {
+            rmInst->allocators = allocator->nextAllocator;
+        }
+        else {
+            prevAllocator->nextAllocator = allocator->nextAllocator;
+        }
+        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));
+    }
+    else {
+        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Creates a new resource tree
+ ***********************************************************************
+ * DESCRIPTION: Creates and populates a new resource tree allocator
+ *              using the provided resource name and value range.  The
+ *              name and value originate from the GRL.
+ */
+static int32_t allocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
+{
+    Rm_Allocator    *allocator = NULL;
+    Rm_ResourceTree *treeRootEntry = NULL;
+    Rm_ResourceNode *treeNode = NULL;
+    Rm_ResourceNode *collidingNode = NULL;
+
+    allocator = allocatorAdd(rmHandle, resourceName);
+    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));
+    RB_INIT(treeRootEntry);
+
+    while (range != NULL) {
+        treeNode = rmResourceNodeNew(range->base, range->length);
+        collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
+
+        if (collidingNode) {
+            Rm_ResourceNode *nextNode = NULL;
+            
+            /* Node that was inserted collides with existing node.  Destroy tree and return error */
+            for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {
+                       nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
+                       RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);
+                rmResourceNodeFree(treeNode);
+               }
+            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));
+            allocatorDelete(rmHandle, allocator->resourceName);
+            return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);
+        }
+        range = range->nextRange;
+    }
+    
+    allocator->allocatorRootEntry = treeRootEntry;
+    return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Adds an owner to an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Adds a RM instance node to a resource node's
+ *              list of owners.
+ */
+static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *ownerList = node->ownerList;
+    Rm_Owner *newOwner = NULL;
+
+    newOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+
+    if (newOwner) {
+        newOwner->instNameNode = serviceInstNode;
+        newOwner->nextOwner = NULL;  
+
+        /* Add owner entry to end of list */
+        if (ownerList) {
+            while (ownerList->nextOwner) {
+                ownerList = ownerList->nextOwner;
+            }
+            ownerList->nextOwner = newOwner;
+        }
+        else {
+            node->ownerList = newOwner;
+        }
+
+        node->allocationCount++;
+        newOwner->instNameNode->allocRefCount++;
+    }
+}
+
+/* FUNCTION PURPOSE: Compares two resource node's owners
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the owners of two resource nodes 
+ *              are equivalent.  Otherwise, returns FALSE.
+ */
+static bool allocatorResNodeOwnerCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+{
+    Rm_Owner *node1Owners = node1->ownerList;
+    Rm_Owner *node2Owners = node2->ownerList;
+    bool      matchedInst;
+
+    if (node1->allocationCount == node2->allocationCount) {
+        while (node1Owners) {
+            matchedInst = false;
+            while (node2Owners) {
+                if (node1Owners->instNameNode == node2Owners->instNameNode) {
+                    matchedInst = true;
+                    break;
+                }
+                node2Owners = node2Owners->nextOwner;
+            }
+
+            if (matchedInst) {
+                node2Owners = node2->ownerList;
+                node1Owners = node1Owners->nextOwner;
+            }
+            else {
+                return(false);
+            }                
+        }
+    }
+    else {
+        return(false);
+    }  
+    
+    return(true);
+}
+
+/* FUNCTION PURPOSE: Deletes an owner from an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Removes a RM instance node from a resource node's
+ *              list of owners.
+ */
+static void allocatorResNodeOwnerDelete(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *owner = node->ownerList;
+    Rm_Owner *prevOwner = NULL;
+
+    while (owner) {
+        if (owner->instNameNode == serviceInstNode) {
+            break;             
+        }
+        prevOwner = owner;
+        owner = owner->nextOwner;
+    }
+
+    if (prevOwner == NULL) {
+        node->ownerList = owner->nextOwner;
+    }
+    else {
+        prevOwner->nextOwner = owner->nextOwner;
+    }
+    
+    node->allocationCount--;
+    owner->instNameNode->allocRefCount--;
+    Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+}
+
+/* FUNCTION PURPOSE: Copies the owners of a resource node
+ ***********************************************************************
+ * DESCRIPTION: Creates a list of resource owners for the destination
+ *              resource node that is equivalent to the the 
+ *              source resource node's owners
+ */
+static void allocatorResNodeOwnerCopy(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
+{
+    Rm_Owner *srcOwnerList = srcNode->ownerList;
+    Rm_Owner *dstNewOwner;
+    Rm_Owner *dstPrevOwner;
+
+    dstNode->allocationCount = srcNode->allocationCount;
+
+    while (srcOwnerList) {
+        dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+        dstNewOwner->instNameNode = srcOwnerList->instNameNode;
+        dstNewOwner->nextOwner = NULL;
+
+        if (dstNode->ownerList == NULL) {
+            dstNode->ownerList = dstNewOwner;
+        }
+        else {
+            dstPrevOwner->nextOwner = dstNewOwner;
+        }
+        dstPrevOwner = dstNewOwner;
+        srcOwnerList = srcOwnerList->nextOwner;
+    }
+}
+
+/* FUNCTION PURPOSE: Clears a resource node's owners
+ ***********************************************************************
+ * DESCRIPTION: Deletes all owners from the owners list of a 
+ *              resource node.
+ */
+static void allocatorResNodeOwnerClear(Rm_ResourceNode *node)
+{
+    Rm_Owner *owner = node->ownerList;
+    Rm_Owner *nextOwner;
+
+    while (owner) {
+        nextOwner = owner->nextOwner;
+        node->allocationCount--;
+        Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+        owner = nextOwner;
+    }
+}
+
+/* FUNCTION PURPOSE: Checks a resource node's ownership
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the provided instance node is
+ *              in the list of resource node owners.  Otherwise,
+ *              returns FALSE.
+ */
+static bool allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)
+{
+    Rm_Owner *owner = node->ownerList;
+
+    while (owner) {
+        if (owner->instNameNode == serviceInstNode) {
+            return(true);           
+        }
+        owner = owner->nextOwner;
+    }
+    return(false);
+}
+
+/* FUNCTION PURPOSE: Preallocates an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Called when an allocate request is made but the base 
+ *              is unspecified.  The preallocation algorithm looks at 
+ *              available resources as well as policy permissions to 
+ *              determine a resource range that satisfies the request.
+ *              If a valid range is found it will be returned for the 
+ *              treeAllocate algorithm to handle.
+ */
+static int32_t allocatorPreAllocate(Rm_Allocator *allocator, int32_t resourcePolicy, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode    findNode;
+    Rm_ResourceNode   *matchingNode = NULL;
+    uint32_t           matchingEnd;
+    uint32_t           rangeIndex;
+    bool               resourceFound = false;
+    Rm_PolicyCheckType policyCheckType;
+    Rm_PolicyCheckCfg  policyCheckCfg;
+    bool               nodePassesPolicy;
+    int32_t            retVal = RM_SERVICE_PROCESSING;    
+
+    opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode, 
+                                                         resourcePolicy, opInfo->allocType, 
+                                                         &retVal);
+    if (retVal != RM_SERVICE_PROCESSING) {
+        return (retVal);
+    }
+
+    if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {  
+        /* Get alignment from policy */
+        opInfo->resourceInfo->alignment = rmPolicyGetResourceAlignment(opInfo->policy, resourcePolicy);
+    }
+    
+    if (opInfo->resourceInfo->alignment == 0) {
+        opInfo->resourceInfo->alignment = 1;
+    }    
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+
+    /* Configure policy checking structure */
+    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+    policyCheckCfg.policyDtb = opInfo->policy;
+    policyCheckCfg.resourceOffset = resourcePolicy;
+    
+    do {
+        matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+        
+        if (matchingNode) {
+            nodePassesPolicy = false;
+            policyCheckCfg.type = policyCheckType;
+            policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+            policyCheckCfg.resourceBase = findNode.base;
+            policyCheckCfg.resourceLength = findNode.length;
+            nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);    
+            
+            if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
+                /* Check exclusive privileges of instance requesting resource.  Requesting
+                 * instance with exclusive privileges can't reserve resource if already owned*/
+                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+            }
+            
+            if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {
+                /* Check exclusive privileges of instance that currently owns resource */
+                policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
+                nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+            }
+
+            if (retVal != RM_SERVICE_PROCESSING) {
+                break;
+            }
+
+            if (nodePassesPolicy) {
+                matchingEnd = matchingNode->base + matchingNode->length - 1;
+                /* Initialize indexer to be first resource value that alignment */
+                rangeIndex = findNode.base;
+                if (rangeIndex % opInfo->resourceInfo->alignment) {
+                    rangeIndex += (opInfo->resourceInfo->alignment -
+                                  (rangeIndex % opInfo->resourceInfo->alignment));
+                }
+                
+                if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd) {
+                    /* Block of unallocated resources within matchingNode that satisfies
+                     * allocate requirements */
+                    opInfo->resourceInfo->base = rangeIndex;
+                    resourceFound = true;
+                }     
+            }
+            
+            if (!resourceFound) {
+                /* Check next resource node for available resources */
+                findNode.base = matchingNode->base + matchingNode->length;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;
+        }
+    } while ((!resourceFound) && 
+             (retVal != RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET));
+
+    return(retVal); 
+}
+
+/* FUNCTION PURPOSE: Allocates an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Will attempt to allocate the resource with specified
+ *              base and length from the resource's allocator.  The
+ *              allocation algorithm will verify the allocation against
+ *              the policy permissions for the instance requesting the
+ *              allocation.  If the policy allows the allocation the 
+ *              algorithm will allocate the resource then combine any
+ *              resource nodes that may have become equivalent (in terms
+ *              of ownership) after the allocation.
+ */
+static int32_t allocatorAllocate(Rm_Allocator *allocator, int32_t resourcePolicy, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode     findNode;
+    Rm_ResourceNode    *matchingNode = NULL;
+    Rm_ResourceNode    *leftNode = NULL;
+    Rm_ResourceNode    *rightNode = NULL;
+    Rm_PolicyCheckType  policyCheckType;    
+    Rm_PolicyCheckCfg   policyCheckCfg;
+    bool                allocPassesPolicy;
+    bool                combineLeft = false;
+    bool                combineRight = false;    
+    uint32_t            findEnd;
+    uint32_t            matchingEnd;  
+    int32_t             retVal = RM_SERVICE_PROCESSING;
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    /* Prepare privilege checks */
+    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+
+    if (matchingNode) {
+        findEnd = findNode.base + findNode.length - 1;
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+            if (opInfo->LinuxKernelBypass) {
+                /* Bypass policy checks since Linux Kernel has full privileges */
+                allocPassesPolicy = true;
+            }
+            else {
+                policyCheckCfg.policyDtb = opInfo->policy;
+                policyCheckCfg.resourceOffset = resourcePolicy;    
+                policyCheckCfg.type = policyCheckType;
+                policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                policyCheckCfg.resourceBase = findNode.base;
+                policyCheckCfg.resourceLength = findNode.length;
+                allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                if (!allocPassesPolicy) {
+                    if (policyCheckType == Rm_policyCheck_INIT) {
+                        retVal = RM_SERVICE_DENIED_INIT_PERM_NOT_GIVEN;
+                    }
+                    else {
+                        retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;
+                    }
+                }
+
+                if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    /* Perform exclusive checks if requesting instance does not already an
+                     * owner of the resource */
+                    if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
+                        /* Check exclusive privileges of instance requesting resource.  Requesting
+                         * instance with exclusive privileges can't reserve resource if already owned*/
+                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                        policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                        if (!allocPassesPolicy) {
+                            retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;
+                        }
+                    }
+                    if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {
+                        /* Check exclusive privileges of instance that currently owns resource */
+                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
+                        policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
+                        allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+                        if (!allocPassesPolicy) {
+                            retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;
+                        }                
+                    }  
+                }
+            }
+            
+            if (allocPassesPolicy) {
+                if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    /* Handle any possible node combinations if requesting instance is
+                     * not already in resource's owner list.  Automatic approval if requesting
+                     * instance is already in owner list. */
+                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
+                        /* findNode range matches matchingNode range
+                         *
+                         *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
+                         *                    |<--alloc request-->|  => requested resources
+                         */                     
+                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+
+                        if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            combineLeft = true;
+                        }
+                        if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            combineRight = true;
+                        }
+
+                        if (combineLeft && combineRight) {
+                            /* Combine all three nodes into matchingNode */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
+
+                            allocatorResNodeOwnerClear(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            allocatorResNodeOwnerClear(rightNode);
+                            rmResourceNodeFree(rightNode);                        
+                        }
+                        else if (combineLeft) {
+                            /* Combine left and matching nodes.  Reinsert right. */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length += leftNode->length;
+
+                            allocatorResNodeOwnerClear(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                        }
+                        else if (combineRight) {
+                            /* Combine right and matching nodes.  Reinsert left. */
+                            matchingNode->length += rightNode->length;
+
+                            allocatorResNodeOwnerClear(rightNode);
+                            rmResourceNodeFree(rightNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else {
+                            /* No combine. */
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Always reinsert matchingNode */                
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);   
+                    }   
+                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
+                        /* findNode range is subset of matchingNode range and neither boundary is
+                         * equivalent.
+                         *
+                         * |<----------matched node---------->|
+                         *        |<---alloc request--->|
+                         */ 
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
+                        allocatorResNodeOwnerCopy(leftNode, matchingNode);
+                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
+                        allocatorResNodeOwnerCopy(rightNode, matchingNode);
+
+                        matchingNode->base = findNode.base;                                    
+                        matchingNode->length = findNode.length;
+                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+
+                        /* Insert all the nodes */
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                    }  
+                    else {    
+                        if (findNode.base == matchingNode->base) {
+                            /* findNode base and matchingNode base are equivalent.  May be combine
+                             * possibilities to the left
+                             *
+                             * |<---left node (alloc'd)--->||<----------matched node---------->|
+                             *                              |<---findNode (alloc req)--->|
+                             */                         
+                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Add allocating instance to owner list for compare with leftNode */
+                            allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                                /* Combine leftNode and findNode */
+                                leftNode->length += findNode.length;
+                            }
+                            else {
+                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                allocatorResNodeOwnerCopy(leftNode, matchingNode);
+                            }
+
+                            /* Account for leftNode in matchingNode */
+                            matchingNode->base = findNode.base + findNode.length;
+                            matchingNode->length = matchingEnd - findEnd;  
+
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else if (findEnd == matchingEnd) {
+                            /* findNode end and matchingNode end are equivalent.  May be combine
+                             * possibilities to the right
+                             *
+                             * |<----------matched node---------->||<---right node (alloc'd)--->|
+                             *       |<---findNode (alloc req)--->| 
+                             */                        
+                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Add allocating instance to owner list for compare with rightNode */
+                            allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                                /* Combine rightNode and findNode */
+                                rightNode->base = findNode.base;
+                                rightNode->length += findNode.length;
+                            }
+                            else {
+                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                allocatorResNodeOwnerCopy(rightNode, matchingNode);
+                            }
+
+                            /* Account for rightNode in matchingNode */
+                            matchingNode->length -= findNode.length;  
+
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+                        /* Remove allocating instance from leftover matchingNode */
+                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+                }
+                retVal = RM_SERVICE_APPROVED;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_ALLOCATION;
+        }
+    }
+    else {
+        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
+    }
+
+    return(retVal);        
+}
+
+/* FUNCTION PURPOSE: Frees an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Will attempt to free the resource with specified
+ *              base and length from the resource's allocator.  The
+ *              free algorithm will verify the free request parameters
+ *              match an allocated range for the resource and that the
+ *              range is owned by the instance requesting the free. If
+ *              the free is validated the algorithm will free the 
+ *              resource then combine any resource nodes that may have
+ *              become equivalent (in terms of ownership) after the
+ *              allocation.
+ */
+static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode = NULL;
+    Rm_ResourceNode *leftNode = NULL;
+    Rm_ResourceNode *rightNode = NULL;
+    bool             combineLeft = false;
+    bool             combineRight = false;
+    uint32_t         findEnd;
+    uint32_t         matchingEnd;
+    int32_t          retVal;
+
+    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    if (matchingNode) {
+        findEnd = findNode.base + findNode.length - 1;
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {  
+            if (matchingNode->allocationCount) {
+                if (allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
+                    {
+                        /* Case 1: Free range equals allocated matched node exactly. Attempt to combine 
+                         *         freed node with nodes to left and right.
+                         *
+                         * |<--left node-->||<---matched node--->||<--right node-->|
+                         *                  |<---free request--->|
+                         */ 
+                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+
+                        if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            combineLeft = true;
+                        }
+                        if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            combineRight = true;
+                        }
+
+                        if (combineLeft && combineRight) {
+                            /* Combine all three nodes into matchingNode */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
+
+                            allocatorResNodeOwnerClear(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            allocatorResNodeOwnerClear(rightNode);
+                            rmResourceNodeFree(rightNode);                        
+                        }
+                        else if (combineLeft) {
+                            /* Combine left and matching nodes.  Reinsert right. */
+                            matchingNode->base = leftNode->base;
+                            matchingNode->length += leftNode->length;
+
+                            allocatorResNodeOwnerClear(leftNode);
+                            rmResourceNodeFree(leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                        }
+                        else if (combineRight) {
+                            /* Combine right and matching nodes.  Reinsert left. */
+                            matchingNode->length += rightNode->length;
+
+                            allocatorResNodeOwnerClear(rightNode);
+                            rmResourceNodeFree(rightNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else {
+                            /* No combine. */
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Always reinsert matchingNode */
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);                    
+                    }
+                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
+                        /* Case 2: Free range is less than range in matched node. Split
+                         *         matched node into three nodes.
+                         *
+                         * |<----------matched node---------->|
+                         *        |<---free request--->|
+                         *
+                         * Remove instance from AllocatedTo list then add it back in for side nodes for
+                         * proper accounting of allocations in validInstance list
+                         */ 
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                        
+                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
+                        allocatorResNodeOwnerCopy(leftNode, matchingNode);
+                        allocatorResNodeOwnerAdd(leftNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        
+                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
+                        allocatorResNodeOwnerCopy(rightNode, matchingNode);
+                        allocatorResNodeOwnerAdd(rightNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+
+                        matchingNode->base = findNode.base;                                    
+                        matchingNode->length = findNode.length;
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+                    else {                        
+                        if (findNode.base == matchingNode->base) {
+                            /* Case 3: Free range is on left boundary of matched node. Try to 
+                             *         combine free range with left node.
+                             *
+                             * |<---left node (free)--->||<----------matched node---------->|
+                             *                           |<---findNode (free req)--->|
+                             */ 
+
+                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            /* Remove freeing instance from owner list for compare with leftNode */
+                            allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                                /* Combine leftNode and findNode */
+                                leftNode->length += findNode.length;
+                            }
+                            else {
+                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                allocatorResNodeOwnerCopy(leftNode, matchingNode);
+                            }
+
+                            /* Remove leftNode range from matchingNode */
+                            matchingNode->base = findNode.base + findNode.length;
+                            matchingNode->length = matchingEnd - findEnd;  
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        else if (findEnd == matchingEnd) {
+                            /* Case 4: Free range is on right boundary of matched node. Try to 
+                             *         combine free range with right node.
+                             *
+                             * |<----------matched node---------->||<---right node (free)--->|
+                             *        |<---findNode (free req)--->|
+                             */ 
+                            
+                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); 
+                            /* Remove freeing instance from owner list for compare with rightNode */
+                            allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                            
+                            if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                                /* Combine rightNode and findNode */
+                                rightNode->base = findNode.base;
+                                rightNode->length += findNode.length;
+                            }
+                            else {
+                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
+                                allocatorResNodeOwnerCopy(rightNode, matchingNode);
+                            }
+
+                            /* Remove rightNode range from matchingNode */
+                            matchingNode->length -= findNode.length;  
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        }
+
+                        /* Add freeing instance back into matchingNode allocations */
+                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    }
+
+                    retVal = RM_SERVICE_APPROVED;
+                }
+                else {
+                    retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
+                }
+            }
+            else {
+                retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
+            }
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_FREE;
+        }
+    }
+    else {
+        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
+    }
+    return(retVal);  
+}
+
+/* FUNCTION PURPOSE: Reserves a Linux resource
+ ***********************************************************************
+ * DESCRIPTION: Reserves resources for Linux using the base and length
+ *              values retrieved from the Linux DTB via the
+ *              "linux-dtb-alias" properties within the GRL.
+ */
+static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle, Rm_LinuxAlias *linuxAlias, 
+                                             Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
+    int32_t   retVal = RM_OK;
+    bool      baseFound = false;
+    bool      lengthFound = false;
+    uint32_t  valueIndex = 0;
+
+    while ((linuxValues) && (!baseFound || !lengthFound)) {
+        if (linuxAlias->baseOffset == valueIndex) {
+            opInfo->resourceInfo->base = linuxValues->value;
+            baseFound = true;
+
+            if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
+                opInfo->resourceInfo->length = 1;
+                lengthFound = true;
+            }
+        }
+        else if (linuxAlias->lengthOffset == valueIndex) {
+            opInfo->resourceInfo->length = linuxValues->value;
+            lengthFound = true;
+        }
+
+        linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;
+        valueIndex++;
+    }
+
+    if (!baseFound || !lengthFound) {
+        retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
+    }
+    else {
+        /* Allocate resource to Linux */
+        retVal = rmAllocatorOperation(rmInst->allocators, opInfo);
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Finds and reserves Linux resources
+ ***********************************************************************
+ * DESCRIPTION: Parses the Linux DTB for resources consumed by the
+ *              Linux kernel.  If the resource is found via the
+ *              "linux-dtb-alias" property defined in the GRL it is 
+ *              reserved.
+ */
+static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resourceName, void *linuxDtb, 
+                                          Rm_LinuxAlias *linuxAlias)
+{
+    Rm_Inst            *rmInst = (Rm_Inst *)rmHandle;
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_ResourceInfo     resourceInfo;
+    uint32_t            pathOffset;
+    uint32_t            pathSize;
+    char               *spacePtr;
+    int32_t             propOffset;
+    int32_t             nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+    int32_t             prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
+    int32_t             depth;
+    int32_t             propertyLen;
+    const char         *propertyName;
+    const void         *propertyData; 
+    Rm_LinuxValueRange *linuxValueRange;
+    int32_t             retVal = RM_OK; 
+
+    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));
+
+    strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
+    opInfo.policy = rmInst->policy;
+    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->validInstances);
+    opInfo.LinuxKernelBypass = true;
+    opInfo.operation = Rm_allocatorOp_ALLOCATE;
+    opInfo.resourceInfo = &resourceInfo;    
+
+    while(linuxAlias) {
+        /* Reset parsing variables */
+        pathOffset = 0;
+        pathSize = strlen(linuxAlias->path) + 1;
+        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+        prevDepth = RM_DTB_UTIL_STARTING_DEPTH;   
+        resourceInfo.base = 0;
+        resourceInfo.length = 0;
+
+        spacePtr = strpbrk(linuxAlias->path, " ");
+        if (spacePtr) {
+            *spacePtr = '\0';
+        }       
+        
+        while(pathOffset < pathSize) {
+            /* Move through DTB nodes until next alias path node found */
+            if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {
+                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);
+
+                if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {
+                    /* Returning from subnode that matched part of alias path without finding
+                     * resource values */
+                    retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
+                    break;
+                }
+            }
+            else {
+                /* Found next alias path node.  Move to next node name in path string. */
+                pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
+                spacePtr = strpbrk(linuxAlias->path + pathOffset, " ");
+                if (spacePtr) {
+                    *spacePtr = '\0';
+                }       
+                
+                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);
+               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);
+                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
+                       (pathOffset < pathSize)) {
+                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, 
+                                                         &propertyName, &propertyLen);
+
+                    if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0) {
+                        /* Found resource at end of alias path */
+                        pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);
+                        linuxValueRange = rmDtbUtilLinuxExtractValues(propertyData, propertyLen);
+                        retVal = allocatorReserveLinuxResource(rmHandle, linuxAlias, 
+                                                               linuxValueRange, &opInfo);
+                        rmDtbUtilLinuxFreeValues(linuxValueRange);
+                    }
+                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);
+                } 
+
+                if (propOffset < -FDT_ERR_NOTFOUND) {
+                    retVal = propOffset;
+                    break;
+                }
+            }
+        }
+
+        if (retVal < RM_OK) {
+            break;
+        }
+        linuxAlias = linuxAlias->nextLinuxAlias;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Creates and initializes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Creates a resource allocator for the provided
+ *              resource name and resource properties retrieved
+ *              from the GRL.  Resources will be reserved for 
+ *              the Linux kernel if the Linux DTB is provided
+ *              and there are "linux-dtb-alias" properties
+ *              specified in the GRL.
+ */
+static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resourceName, 
+                                           Rm_ResourceProperties *resourceProperties, void *linuxDtb)
+{
+    Rm_Inst             *rmInst = (Rm_Inst *)rmHandle;
+    Rm_ResourceRange    *range = NULL;
+    Rm_ResourceRange    *rangeBasePtr = NULL;
+    Rm_NsAssignment     *nsAssignments = NULL;
+    Rm_NsAssignment     *nsAssignmentBasePtr = NULL;
+    Rm_LinuxAlias       *linuxAlias = NULL;
+    Rm_NameServerObjCfg  nameServerObjCfg;      
+    int32_t              retVal = RM_OK;
+
+    if (resourceProperties->rangeData && (resourceProperties->rangeLen > 0)) {
+        range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, 
+                                                        resourceProperties->rangeLen);
+        
+        if ((retVal = allocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
+            if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
+                if (linuxDtb) {
+                    linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
+                                                               resourceProperties->linuxAliasLen, &retVal);
+                    if (linuxAlias) {
+                        retVal = allocatorFindLinuxResource(rmHandle, resourceName, linuxDtb, linuxAlias);            
+                    }
+                }
+                else {
+                    retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;
+                }
+            }
+        }
+    }
+    
+    if (retVal >= RM_OK) {
+        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen) {
+            nsAssignments = rmDtbUtilResExtractNsAssignment(resourceProperties->nsAssignData, 
+                                                            resourceProperties->nsAssignLen, &retVal);
+            if (nsAssignments) {
+                nsAssignmentBasePtr = nsAssignments;
+                while (nsAssignments) {
+                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                    nameServerObjCfg.nameServerTree = rmInst->nameServer;
+                    nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
+                    nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
+                    nameServerObjCfg.nodeCfg.resourceBase= nsAssignments->resourceBase;
+                    nameServerObjCfg.nodeCfg.resourceLength = nsAssignments->resourceLength;                
+                    rmNameServerAddObject(&nameServerObjCfg);
+                    nsAssignments = nsAssignments->nextNsAssignment;
+                }
+                rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
+            }
+        }
+    }
+
+    rmDtbUtilResFreeRange(rangeBasePtr);
+    if (linuxAlias) {
+        rmDtbUtilResFreeLinuxAlias(linuxAlias);
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Recursively parses GRL resource properties
+ ***********************************************************************
+ * DESCRIPTION: Recursively parses and stores GRL resource node 
+ *              properties using the LIBFDT APIs
+ */
+static int32_t allocatorParseGrlResProp(void *globalResourceDtb, int32_t offset, 
+                                        Rm_ResourceProperties *propertyInfo)
+{
+       int32_t              propertyLen;
+       const char          *propertyName;
+       const void          *propertyData;
+    Rm_ResourcePropType  propertyType;
+    int32_t              retVal = RM_OK;
+
+       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);
+    propertyType = rmDtbUtilResGetPropertyType(propertyName);
+    if (propertyType == Rm_resourcePropType_RESOURCE_RANGE) {
+        propertyInfo->rangeData = propertyData;
+        propertyInfo->rangeLen = propertyLen;
+    }
+    else if (propertyType == Rm_resourcePropType_NSASSIGNMENT) {
+        propertyInfo->nsAssignData = propertyData;
+        propertyInfo->nsAssignLen = propertyLen;
+    }
+    else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS) {
+        propertyInfo->linuxAliasData = propertyData;
+        propertyInfo->linuxAliasLen = propertyLen;
+    }        
+    else {
+        retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;
+    }
+
+    if (retVal == RM_OK) {
+        offset = fdt_next_property_offset(globalResourceDtb, offset);
+       if (offset >= 0) {
+           retVal = allocatorParseGrlResProp(globalResourceDtb, offset, propertyInfo);
+       }
+        else if (offset != -FDT_ERR_NOTFOUND) {
+            /* Error returned by LIBFDT */
+            retVal = offset;
+        }
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Recursively parses GRL resource nodes
+ ***********************************************************************
+ * DESCRIPTION: Recursively parses GRL resource nodes looking for
+ *              resource properties to create the resource allocators.
+ *              The LIBFDT APIs are used to parse the GRL.
+ */
+static int32_t allocatorParseGrlResNode(Rm_Handle rmHandle, void *globalResourceDtb, int32_t nodeOffset,
+                                        int32_t depth, void *linuxDtb)
+{
+       const char            *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);
+    Rm_ResourceProperties  resourceProperties;
+       int32_t                retVal = RM_OK;
+       int32_t                offset;
+
+    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));
+    /* Get properties of resource node */
+       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
+       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+               retVal =  allocatorParseGrlResProp(globalResourceDtb, offset, &resourceProperties);
+        if (retVal < -FDT_ERR_NOTFOUND) {
+            return (retVal);
+        }
+        if (retVal = allocatorExtractGrlResProps(rmHandle, resourceName, &resourceProperties, linuxDtb) < RM_OK) {
+            return (retVal);
+        }
+       }
+    else if (offset != -FDT_ERR_NOTFOUND) {
+               /* Error returned by LIBFDT */
+        return (offset);
+    }
+    
+       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);
+    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+        retVal = allocatorParseGrlResNode(rmHandle, globalResourceDtb, offset, depth, linuxDtb);
+        if (retVal < -FDT_ERR_NOTFOUND) {
+            return (retVal);
+        }
+    }
+    else if (offset < -FDT_ERR_NOTFOUND) {
+        /* Error returned by LIBFDT */
+        return (offset);
+    }
+    return (retVal);
+}
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Finds an allocator
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to an allocator that matches the 
+ *              provided resource name.
+ */
+Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
+{
+    while (allocatorList) {
+        if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        allocatorList = allocatorList->nextAllocator;
+    }
+
+    return (allocatorList);
+}
+
+/* FUNCTION PURPOSE: Issues an allocator operation
+ ***********************************************************************
+ * DESCRIPTION: Issues an allocator preallocate, allocate, or free
+ *              for an RM resource.
+ */
+int32_t rmAllocatorOperation(Rm_Allocator *allocatorList, Rm_AllocatorOpInfo *opInfo)
+{
+    Rm_Allocator *allocator = NULL;
+    int32_t       resourceOffsetInPolicy;
+    int32_t       retVal;
+    
+    resourceOffsetInPolicy = rmPolicyGetResourceOffset(opInfo->policy, opInfo->resourceInfo->name);
+    allocator = rmAllocatorFind(allocatorList, opInfo->resourceInfo->name);
+    
+    if ((resourceOffsetInPolicy > 0) && allocator) {
+        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {
+            retVal = allocatorPreAllocate(allocator, resourceOffsetInPolicy, opInfo);
+        }               
+        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {
+            retVal = allocatorAllocate(allocator, resourceOffsetInPolicy, opInfo);
+        }
+        else if (opInfo->operation == Rm_allocatorOp_FREE) {
+            retVal = allocatorFree(allocator, opInfo);
+        }         
+    }
+    else {
+        /* Resource could not be found in policy and/or allocator */
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+    }
+    return(retVal);
+}
+
+/* FUNCTION PURPOSE: Initializes server allocators
+ ***********************************************************************
+ * DESCRIPTION: Creates and initializes a server instance's
+ *              resource allocators using the GRL and, if
+ *              provided, Linux DTB.
+ */
+int32_t rmAllocatorInitializeResources(Rm_Handle rmHandle, void *globalResourceDtb, void *linuxDtb)
+{
+    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;
+    int32_t result = RM_OK;
+
+    /* Recursively parse the Global Resource List, creating an allocator for
+     * each resource as specified in the node */
+    result = allocatorParseGrlResNode(rmHandle, globalResourceDtb, nodeOffset, startDepth, linuxDtb);
+
+    return(result);
+}
+
index 356ea165986a90e69aa0fa6bb9200f937e7bd29d..75b1c3b1f46b8419f08edff7fc5cb0c853715400 100644 (file)
@@ -47,7 +47,7 @@
 #include <ti/drv/rm/rm.h>
 
 /* RM internal API includes */
-#include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
 #include <ti/drv/rm/include/rm_policyloc.h>
 #include <ti/drv/rm/include/rm_dtb_utilloc.h>