]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm.c
Completed and tested routines that automatically reserve linux resources
[keystone-rtos/rm-lld.git] / src / rm.c
index 607eab17b6ed8d8788bbbcd02cf1abd76bd12e61..3947f68b1c8faf2024bf54703fe3026b4eb2a65c 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
-/**
- *   @file  rm.c
- *
- *   @brief   
- *      This is the Resource Manager Low Level Driver file.
- *
- *  \par
- *  ============================================================================
- *  @n   (C) Copyright 2012, 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
-*/
-
-/* c99 include */
-#include <stdint.h>
-#include <stdlib.h>
-
-/* RM includes */
-#include <ti/drv/rm/rm.h>
-#include <ti/drv/rm/rm_public_lld.h>
-#include <ti/drv/rm/resource_table_defs.h>
-#include <ti/drv/rm/include/rm_pvt.h>
-
-/* RM OSAL layer */
-#include <rm_osal.h>
-
-/* CSL includes */
-#include <ti/csl/csl_qm_queue.h>
-
-/**********************************************************************
- ************************** Globals ***********************************
- **********************************************************************/
-
-/* Place QMSS PDSP permissions array */
-#pragma DATA_SECTION (rmQmssPdspFirmwarePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssPdspFirmwarePerms, 128)
-Rm_Perms rmQmssPdspFirmwarePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_FIRMWARE_PDSPS, Rm_Perms)];
-
-/* Place QMSS queue permissions array */
-#pragma DATA_SECTION (rmQmssQueuePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQueuePerms, 128)
-Rm_Perms rmQmssQueuePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QUEUES, Rm_Perms)];
-
-/* Place QMSS memory region permissions array */
-#pragma DATA_SECTION (rmQmssMemRegionPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssMemRegionPerms, 128)
-Rm_Perms rmQmssMemRegionPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_MEM_REGIONS, Rm_Perms)];
-
-/* Place QMSS Linking RAM permissions array */
-#pragma DATA_SECTION (rmQmssLinkingRamPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssLinkingRamPerms, 128)
-Rm_qmssLinkingRamPerms rmQmssLinkingRamPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_LINKING_RAM_RANGES, Rm_qmssLinkingRamPerms)];
-
-/* Place QMSS accumulator channel permissions array */
-#pragma DATA_SECTION (rmQmssAccumChPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssAccumChPerms, 128)
-Rm_Perms rmQmssAccumChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_ACCUM_CH, Rm_Perms)];
-
-/* Place QMSS QOS cluster permissions array */
-#pragma DATA_SECTION (rmQmssQosClusterPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQosClusterPerms, 128)
-Rm_Perms rmQmssQosClusterPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QOS_CLUSTER, Rm_Perms)];
-
-/* Place QMSS QOS queue permissions array */
-#pragma DATA_SECTION (rmQmssQosQueuePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQosQueuePerms, 128)
-Rm_Perms rmQmssQosQueuePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QOS_QUEUES, Rm_Perms)];
-
-/* Place CPPI SRIO TX channel permissions array */
-#pragma DATA_SECTION (rmCppiSrioTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioTxChPerms, 128)
-Rm_Perms rmCppiSrioTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_TX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF TX channel permissions array */
-#pragma DATA_SECTION (rmCppiAifTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifTxChPerms, 128)
-Rm_Perms rmCppiAifTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcATxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcATxChPerms, 128)
-Rm_Perms rmCppiFftcATxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcBTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBTxChPerms, 128)
-Rm_Perms rmCppiFftcBTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS TX channel permissions array */
-#pragma DATA_SECTION (rmCppiPassTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassTxChPerms, 128)
-Rm_Perms rmCppiPassTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_TX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS TX channel permissions array */
-#pragma DATA_SECTION (rmCppiQmssTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssTxChPerms, 128)
-Rm_Perms rmCppiQmssTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_TX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcCTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCTxChPerms, 128)
-Rm_Perms rmCppiFftcCTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP TX channel permissions array */
-#pragma DATA_SECTION (rmCppiBcpTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpTxChPerms, 128)
-Rm_Perms rmCppiBcpTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_TX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI SRIO RX channel permissions array */
-#pragma DATA_SECTION (rmCppiSrioRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioRxChPerms, 128)
-Rm_Perms rmCppiSrioRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_RX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF RX channel permissions array */
-#pragma DATA_SECTION (rmCppiAifRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifRxChPerms, 128)
-Rm_Perms rmCppiAifRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcARxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcARxChPerms, 128)
-Rm_Perms rmCppiFftcARxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcBRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBRxChPerms, 128)
-Rm_Perms rmCppiFftcBRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS RX channel permissions array */
-#pragma DATA_SECTION (rmCppiPassRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassRxChPerms, 128)
-Rm_Perms rmCppiPassRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_RX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS RX channel permissions array */
-#pragma DATA_SECTION (rmCppiQmssRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssRxChPerms, 128)
-Rm_Perms rmCppiQmssRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_RX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcCRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCRxChPerms, 128)
-Rm_Perms rmCppiFftcCRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP RX channel permissions array */
-#pragma DATA_SECTION (rmCppiBcpRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpRxChPerms, 128)
-Rm_Perms rmCppiBcpRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_RX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI SRIO flow permissions array */
-#pragma DATA_SECTION (rmCppiSrioFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioFlowPerms, 128)
-Rm_Perms rmCppiSrioFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_FLOW, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF flow permissions array */
-#pragma DATA_SECTION (rmCppiAifFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifFlowPerms, 128)
-Rm_Perms rmCppiAifFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcAFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcAFlowPerms, 128)
-Rm_Perms rmCppiFftcAFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcBFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBFlowPerms, 128)
-Rm_Perms rmCppiFftcBFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS flow permissions array */
-#pragma DATA_SECTION (rmCppiPassFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassFlowPerms, 128)
-Rm_Perms rmCppiPassFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_FLOW, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS flow permissions array */
-#pragma DATA_SECTION (rmCppiQmssFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssFlowPerms, 128)
-Rm_Perms rmCppiQmssFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_FLOW, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcCFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCFlowPerms, 128)
-Rm_Perms rmCppiFftcCFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP flow permissions array */
-#pragma DATA_SECTION (rmCppiBcpFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpFlowPerms, 128)
-Rm_Perms rmCppiBcpFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_FLOW, Rm_Perms)];
-#endif
-
-/* Place PA lookup table permissions array */
-#pragma DATA_SECTION (rmPaLutPerms, ".rm");
-#pragma DATA_ALIGN (rmPaLutPerms, 128)
-Rm_Perms rmPaLutPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_PA_LUT, Rm_Perms)];
-
-/* Rm_init/Rm_start synchronization object.  Initialized to 0. */
-#pragma DATA_SECTION (rmGSyncObj, ".rm");
-#pragma DATA_ALIGN (rmGSyncObj, 128)
-Rm_Sync_Obj rmGSyncObj = 
-{
-    {
-        RM_PERMISSION_TABLE_NOT_VALID,
-    }
-};
-
-/* Create, populate, and place RM global permissions object */
-#pragma DATA_SECTION (rmGPermsObj, ".rm");
-#pragma DATA_ALIGN (rmGPermsObj, 128)
-Rm_GlobalPermissionsObj rmGPermsObj = 
-{
-    {
-        /* qmssPdspFirmwarePerms */
-        &rmQmssPdspFirmwarePerms[0],  
-        /* Pointer: qmssQueuePerms */
-        &rmQmssQueuePerms[0],
-        /* Pointer: qmssMemRegionPerms */
-        &rmQmssMemRegionPerms[0],
-        /* qmssLinkRamControlPerms */
-        {
-            0u,
-            0u,
-        },  
-        /* Pointer: qmssLinkRamPerms */
-        &rmQmssLinkingRamPerms[0],
-        /* Pointer: qmssAccumChPerms */
-        &rmQmssAccumChPerms[0], 
-        /* qmssQosPdspTimerPerms */
-        {
-            0u,
-            0u,
-        },  
-        /* Pointer: qmssQosClusterPerms */
-        &rmQmssQosClusterPerms[0],
-        /* Pointer: qmssQosQueuePerms */
-        &rmQmssQosQueuePerms[0],
-        /* Pointer array: cppiTxChPerms - Must be in same order as DMA objects */
-        {
-            { &rmCppiSrioTxChPerms[0], 
-#ifdef QMSS_MAX_AIF_QUEUE          
-               &rmCppiAifTxChPerms[0],
-#endif           
-#ifdef QMSS_MAX_FFTC_A_QUEUE           
-               &rmCppiFftcATxChPerms[0],
-#endif           
-#ifdef QMSS_MAX_FFTC_B_QUEUE           
-               &rmCppiFftcBTxChPerms[0],   
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
-               &rmCppiPassTxChPerms[0],
-#endif               
-               &rmCppiQmssTxChPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-               &rmCppiFftcCTxChPerms[0],
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-               &rmCppiBcpTxChPerms[0]
-#endif           
-            }
-        },
-        /* Pointer array: cppiRxChPerms - Must be in same order as DMA objects  */
-        {
-            { &rmCppiSrioRxChPerms[0], 
-#ifdef QMSS_MAX_AIF_QUEUE          
-               &rmCppiAifRxChPerms[0], 
-#endif           
-#ifdef QMSS_MAX_FFTC_A_QUEUE           
-               &rmCppiFftcARxChPerms[0],
-#endif           
-#ifdef QMSS_MAX_FFTC_B_QUEUE           
-               &rmCppiFftcBRxChPerms[0], 
-#endif           
-#ifdef QMSS_MAX_PASS_QUEUE
-               &rmCppiPassRxChPerms[0], 
-#endif               
-               &rmCppiQmssRxChPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-               &rmCppiFftcCRxChPerms[0],
-#endif              
-#ifdef QMSS_MAX_BCP_QUEUE
-               &rmCppiBcpRxChPerms[0]
-#endif           
-            }
-        },    
-        /* Pointer array: cppiFlowPerms - Must be in same order as DMA objects  */
-        {
-            { &rmCppiSrioFlowPerms[0], 
-#ifdef QMSS_MAX_AIF_QUEUE          
-               &rmCppiAifFlowPerms[0], 
-#endif           
-#ifdef QMSS_MAX_FFTC_A_QUEUE           
-               &rmCppiFftcAFlowPerms[0],
-#endif           
-#ifdef QMSS_MAX_FFTC_B_QUEUE           
-               &rmCppiFftcBFlowPerms[0],    
-#endif           
-#ifdef QMSS_MAX_PASS_QUEUE
-               &rmCppiPassFlowPerms[0], 
-#endif               
-               &rmCppiQmssFlowPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-               &rmCppiFftcCFlowPerms[0],
-#endif                     
-#ifdef QMSS_MAX_BCP_QUEUE
-               &rmCppiBcpFlowPerms[0]
-#endif           
-            }
-        },
-        /* paFirmwarePerms */
-        {
-            0u,
-            0u,
-        },  
-        /* Pointer: paLutPerms */
-        &rmPaLutPerms[0],
-    }
-};
-
-/** @brief Global Variable (should be local per DSP) containing LLD RM permission checkers */
-Rm_LldPermCallouts rmPermissionCheckers = 
-{
-    Rm_initPermissionChecker,
-    Rm_usePermissionChecker,
-};
-
-/** @brief Global Variable which describes the RM LLD Version Information */
-const char   rmLldVersionStr[] = RM_LLD_VERSION_STR ":" __DATE__  ":" __TIME__;
-
-/**********************************************************************
- ********************** Internal Functions *********************************
- **********************************************************************/
-
-/**
- *  @b Description
- *  @n  
- *      Initialize the permission tables.  All resources are intialized to deny all initialization
- *      and usage permissions.
- *
- */
-void Rm_permissionTableInit(void)
-{
-    uint16_t resourceIndex;
-    Rm_Perms *resArrayPtr;
-    uint16_t dmaNum;
-    uint16_t dmaTxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_TX_CH, 
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                          RM_CPPI_AIF_TX_CH,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                          RM_CPPI_FFTC_A_TX_CH, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                          RM_CPPI_FFTC_B_TX_CH, 
-#endif    
-#ifdef QMSS_MAX_PASS_QUEUE
-                                          RM_CPPI_PASS_TX_CH, 
-#endif
-                                          RM_CPPI_QMSS_TX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                          RM_CPPI_FFTC_C_TX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                          RM_CPPI_BCP_TX_CH
-#endif                                                                       
-                                         };
-    uint16_t dmaRxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_RX_CH,
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                          RM_CPPI_AIF_RX_CH,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                          RM_CPPI_FFTC_A_RX_CH, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                          RM_CPPI_FFTC_B_RX_CH, 
-#endif                                                               
-#ifdef QMSS_MAX_PASS_QUEUE
-                                          RM_CPPI_PASS_RX_CH, 
-#endif                                          
-                                          RM_CPPI_QMSS_RX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                          RM_CPPI_FFTC_C_RX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                          RM_CPPI_BCP_RX_CH
-#endif       
-                                         };
-    uint16_t dmaFlow[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_FLOW, 
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                          RM_CPPI_AIF_FLOW,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                          RM_CPPI_FFTC_A_FLOW, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                          RM_CPPI_FFTC_B_FLOW, 
-#endif                                                         
-#ifdef QMSS_MAX_PASS_QUEUE
-                                          RM_CPPI_PASS_FLOW, 
-#endif                                          
-                                          RM_CPPI_QMSS_FLOW,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                          RM_CPPI_FFTC_C_FLOW,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                          RM_CPPI_BCP_FLOW
-#endif       
-                                         };
-
-    /* QMSS Linking RAM Control */
-    rmGPermsObj.obj.qmssLinkRamControlPerms.initPerms = 0;
-    rmGPermsObj.obj.qmssLinkRamControlPerms.usePerms = 0;
-
-    /* QMSS QOS PDSP Timer */
-    rmGPermsObj.obj.qmssQosPdspTimerPerms.initPerms = 0;
-    rmGPermsObj.obj.qmssQosPdspTimerPerms.usePerms = 0;
-
-    /* PA Firmware */
-    rmGPermsObj.obj.paFirmwarePerms.initPerms = 0;
-    rmGPermsObj.obj.paFirmwarePerms.usePerms = 0;
-
-    /* Writeback the values that were initialized in the global object itself */
-    Rm_osalEndMemAccess ((void *) &rmGPermsObj, sizeof (Rm_GlobalPermissionsObj));
-
-    /* QMSS PDSP Firmware */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_FIRMWARE_PDSPS; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssPdspFirmwarePerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssPdspFirmwarePerms, sizeof (Rm_Perms)*RM_QMSS_FIRMWARE_PDSPS);
-
-    /* QMSS queues */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_QUEUES; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssQueuePerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssQueuePerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssQueuePerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQueuePerms, sizeof (Rm_Perms)*RM_QMSS_QUEUES);
-
-    /* QMSS memory regions */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_MEM_REGIONS; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssMemRegionPerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssMemRegionPerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssMemRegionPerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssMemRegionPerms, sizeof (Rm_Perms)*RM_QMSS_MEM_REGIONS);
-
-    /* QMSS Linking RAM */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_LINKING_RAM_RANGES; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].startIndex = RM_QMSS_LINKING_RAM_RANGE_INIT;
-        rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].endIndex = RM_QMSS_LINKING_RAM_RANGE_INIT;
-        rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].rangePerms.initPerms = 0;
-        rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].rangePerms.usePerms = 0;
-    }
-    /* Writeback the qmssLinkRamPerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssLinkRamPerms, sizeof (Rm_Perms)*RM_QMSS_LINKING_RAM_RANGES);
-
-    /* QMSS accumulator channels */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_ACCUM_CH; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssAccumChPerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssAccumChPerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssAccumChPerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssAccumChPerms, sizeof (Rm_Perms)*RM_QMSS_ACCUM_CH);
-
-    /* QMSS QOS Clusters */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_QOS_CLUSTER; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssQosClusterPerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssQosClusterPerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssQosClusterPerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQosClusterPerms, sizeof (Rm_Perms)*RM_QMSS_QOS_CLUSTER);    
-
-    /* QMSS QOS Queues */
-    for (resourceIndex = 0; resourceIndex < RM_QMSS_QOS_QUEUES; resourceIndex++)
-    {
-        rmGPermsObj.obj.qmssQosQueuePerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.qmssQosQueuePerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the qmssQosQueuePerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQosQueuePerms, sizeof (Rm_Perms)*RM_QMSS_QOS_QUEUES);      
-
-    /* CPPI DMA transmit channels */
-    for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
-    {
-        resArrayPtr = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[dmaNum];
-        
-        for (resourceIndex = 0; resourceIndex < dmaTxCh[dmaNum]; resourceIndex++)
-        {
-            resArrayPtr[resourceIndex].initPerms = 0;
-            resArrayPtr[resourceIndex].usePerms = 0;
-        }
-
-        /* Writeback each of the transmit channel arrays  */
-        Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaTxCh[dmaNum]);
-    }
-
-    /* CPPI DMA receive channels */
-    for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
-    {
-        resArrayPtr = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[dmaNum];
-        
-        for (resourceIndex = 0; resourceIndex < dmaRxCh[dmaNum]; resourceIndex++)
-        {
-            resArrayPtr[resourceIndex].initPerms = 0;
-            resArrayPtr[resourceIndex].usePerms = 0;
-        }
-
-        /* Writeback each of the receive channel arrays */
-        Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaRxCh[dmaNum]);
-    }    
-
-    /* CPPI DMA flows */
-    for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
-    {
-        resArrayPtr = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[dmaNum];
-        
-        for (resourceIndex = 0; resourceIndex < dmaFlow[dmaNum]; resourceIndex++)
-        {
-            resArrayPtr[resourceIndex].initPerms = 0;
-            resArrayPtr[resourceIndex].usePerms = 0;
-        }
-
-        /* Writeback each of the flow arrays */
-        Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaFlow[dmaNum]);
-    }       
-
-    /* PA Lookup tables */
-    for (resourceIndex = 0; resourceIndex < RM_PA_LUT; resourceIndex++)
-    {
-        rmGPermsObj.obj.paLutPerms[resourceIndex].initPerms = 0;
-        rmGPermsObj.obj.paLutPerms[resourceIndex].usePerms = 0;
-    }
-    /* Writeback the paLutPerms array */
-    Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.paLutPerms, sizeof (Rm_Perms)*RM_PA_LUT);
-    
-}
-
-/**
- *  @b Description
- *  @n  
- *      Sets a list of entries in a permissions array to the specified permissions
- *
- *  @param[in]  resourceEntry
- *      The resource entry from the application defined resource table containing
- *      a range of resources and the permissions to assign to them.
- *
- *  @param[in]  rmPermsArray
- *      The permissions array for the resource specified in the resourceEntry.
- *     
- *  @param[in]  len
- *      Full length of permissions array for writeback after the permissions have been
- *      transferred.
- */
-void Rm_setTablePermissions (const Rm_Resource *resourceEntry, Rm_Perms *rmPermsArray, uint32_t len)
-{
-    uint32_t index;
-
-    /* Scan through the resource range filling in the specified permission */
-    for (index = resourceEntry->resourceStart; index < resourceEntry->resourceEnd + 1; index++)
-    {
-        rmPermsArray[index].initPerms = resourceEntry->resourceInitFlags;
-        rmPermsArray[index].usePerms  = resourceEntry->resourceUseFlags;
-    }
-
-    Rm_osalEndMemAccess ((void *)rmPermsArray, sizeof (Rm_Perms)* len);
-}
-
-/**
- *  @b Description
- *  @n  
- *      Takes an application specified resource table as input and transfers all
- *      resource permissions specified within into the internal resource
- *      permission tables.  Upon completion of permission transfer a global
- *      synchronization object is written to sync with slave cores.
- *
- *  @param[in]  rmResourceTable
- *      Application defined resource table containing all resources that should
- *      have permissions set for the DSPs
- *
- *  @retval
- *      Success -   RM_OK
- *  @retval
- *      Failure -   RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED
- */
-Rm_Result Rm_populatePermissionTable(const Rm_Resource *rmResourceTable)
-{
-    const Rm_Resource *resourceEntry;
-    uint16_t linkRamIndex;
-
-    /* Verify resource table can be read by verifying magic number is contained
-     * in first entry of the resource table */
-    resourceEntry = rmResourceTable;
-    
-    /* Invalidate the resource */
-    Rm_osalBeginMemAccess ((void *) resourceEntry, sizeof (Rm_Resource));
-    if (resourceEntry->resourceId != RM_RESOURCE_MAGIC_NUMBER)
-    {
-        return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
-    }
-
-    /* Magic number is visible start parsing the resource table and transferring
-      * permissions to the internal permissions tables */
-
-    /* Parse resource table until last entry field is encountered */
-    while (resourceEntry->resourceId != RM_RESOURCE_FINAL_ENTRY)
-    {
-        /* Invalidate the resource */
-        Rm_osalBeginMemAccess ((void *) resourceEntry, sizeof (Rm_Resource));
-
-        /* Populate a permission table based on the resourceId */
-        switch (resourceEntry->resourceId)
-        {
-            case RM_RESOURCE_MAGIC_NUMBER:
-                break;     
-                
-            case RM_RESOURCE_QMSS_FIRMWARE_PDSP:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_FIRMWARE_PDSPS, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssPdspFirmwarePerms, RM_QMSS_FIRMWARE_PDSPS);
-                 break;
-
-            case RM_RESOURCE_QMSS_QUEUE:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QUEUES, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQueuePerms, RM_QMSS_QUEUES);
-                 break;
-
-            case RM_RESOURCE_QMSS_MEMORY_REGION:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_MEM_REGIONS, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssMemRegionPerms, RM_QMSS_MEM_REGIONS);
-                 break;
-                
-            case RM_RESOURCE_QMSS_LINKING_RAM_CONTROL:
-                rmGPermsObj.obj.qmssLinkRamControlPerms.initPerms = resourceEntry->resourceInitFlags;
-                rmGPermsObj.obj.qmssLinkRamControlPerms.usePerms  = resourceEntry->resourceUseFlags;
-                 break;
-                
-            case RM_RESOURCE_QMSS_LINKING_RAM:
-                /* Expect Linking RAM ranges to be presented in order */
-
-                /* Find next available unused Linking RAM permissions entry */
-                for (linkRamIndex = 0; linkRamIndex < RM_QMSS_LINKING_RAM_RANGES; linkRamIndex++)
-                {
-                    if ((rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].startIndex == RM_QMSS_LINKING_RAM_RANGE_INIT) &&
-                         (rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].endIndex == RM_QMSS_LINKING_RAM_RANGE_INIT))
-                    {
-                        RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_LINKING_RAM_RANGE_INIT, 
-                                        RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                        /* Populate the entry with the Linking RAM resource data */
-                        rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].startIndex = resourceEntry->resourceStart;
-                        rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].endIndex = resourceEntry->resourceEnd;
-                        rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].rangePerms.initPerms = resourceEntry->resourceInitFlags;
-                        rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].rangePerms.usePerms  = resourceEntry->resourceUseFlags;
-
-                        Rm_osalEndMemAccess ((void *)&rmGPermsObj.obj.qmssLinkRamPerms[0], sizeof (Rm_Perms)* RM_QMSS_LINKING_RAM_RANGES);
-                        
-                        /* Leave search loop */
-                        break;
-                    }
-                }
-                 break;
-
-            case RM_RESOURCE_QMSS_ACCUMULATOR_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_ACCUM_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssAccumChPerms, RM_QMSS_ACCUM_CH);
-                 break;
-
-            case RM_RESOURCE_QMSS_QOS_PDSP_TIMER:
-                rmGPermsObj.obj.qmssQosPdspTimerPerms.initPerms = resourceEntry->resourceInitFlags;
-                rmGPermsObj.obj.qmssQosPdspTimerPerms.usePerms  = resourceEntry->resourceUseFlags;
-                 break;
-
-            case RM_RESOURCE_QMSS_QOS_CLUSTER:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QOS_CLUSTER, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQosClusterPerms, RM_QMSS_QOS_CLUSTER);
-                 break;             
-                
-            case RM_RESOURCE_QMSS_QOS_QUEUE:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QOS_QUEUES, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQosQueuePerms, RM_QMSS_QOS_QUEUES);
-                 break;                    
-
-            case RM_RESOURCE_CPPI_SRIO_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_SRIO_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_SRIO_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_FLOW);
-                 break;
-
-#ifdef QMSS_MAX_AIF_QUEUE
-            case RM_RESOURCE_CPPI_AIF_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_AIF_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_AIF_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_FLOW);
-                 break;            
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-            case RM_RESOURCE_CPPI_FFTC_A_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_A_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_A_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_FLOW);
-                 break;     
-#endif    
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-            case RM_RESOURCE_CPPI_FFTC_B_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_B_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_B_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_FLOW);
-                 break;       
-#endif                
-
-#ifdef QMSS_MAX_PASS_QUEUE
-            case RM_RESOURCE_CPPI_PASS_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_PASS_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_PASS_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_FLOW);
-                 break;
-#endif                
-
-            case RM_RESOURCE_CPPI_QMSS_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_QMSS_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_QMSS_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_FLOW);
-                 break;
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-            case RM_RESOURCE_CPPI_FFTC_C_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_C_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_FFTC_C_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_FLOW);
-                 break;          
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-            case RM_RESOURCE_CPPI_BCP_TX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_TX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_BCP_RX_CH:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_RX_CH);
-                 break;
-
-            case RM_RESOURCE_CPPI_BCP_FLOW:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_FLOW);
-                 break;      
-#endif                
-
-            case RM_RESOURCE_PA_FIRMWARE:
-                rmGPermsObj.obj.paFirmwarePerms.initPerms = resourceEntry->resourceInitFlags;
-                rmGPermsObj.obj.paFirmwarePerms.usePerms  = resourceEntry->resourceUseFlags;
-                 break;
-
-            case RM_RESOURCE_PA_LUT_ENTRY:
-                RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_PA_LUT, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
-                Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.paLutPerms, RM_PA_LUT);
-                 break;
-
-            default:
-                return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
-
-        }
-
-        resourceEntry++;
-    };
-
-    /* Write synchronization object so that slave cores know permissions table is
-      * populated and valid */
-    rmGSyncObj.obj.globalSyncObj = RM_PERMISSION_TABLE_VALID;
-    
-    /* Writeback Sync Object */
-    Rm_osalEndMemAccess ((void *) &rmGSyncObj, sizeof (Rm_Sync_Obj));
-
-    return RM_OK;
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function is called on slave DSPs after the master DSP has populated
- *      the internal permission tables.  This function invalidates all internal
- *      global permission tables so that no further invalidates are required
- *      when LLDs perform resource permission checks
- *
- */
-void Rm_updatePermissionTables(void)
-{
-    uint16_t dmaIndex;
-    const uint16_t dmaTxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_TX_CH, 
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                                RM_CPPI_AIF_TX_CH,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                                RM_CPPI_FFTC_A_TX_CH, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                                RM_CPPI_FFTC_B_TX_CH, 
-#endif                                          
-#ifdef QMSS_MAX_PASS_QUEUE
-                                                RM_CPPI_PASS_TX_CH, 
-#endif                                                
-                                                RM_CPPI_QMSS_TX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                                RM_CPPI_FFTC_C_TX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                                RM_CPPI_BCP_TX_CH
-#endif                                                                       
-                                               };
-    const uint16_t dmaRxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_RX_CH, 
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                                RM_CPPI_AIF_RX_CH,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                                RM_CPPI_FFTC_A_RX_CH, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                                RM_CPPI_FFTC_B_RX_CH, 
-#endif                                                       
-#ifdef QMSS_MAX_PASS_QUEUE
-                                                RM_CPPI_PASS_RX_CH, 
-#endif                                                
-                                                RM_CPPI_QMSS_RX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                                RM_CPPI_FFTC_C_RX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                                RM_CPPI_BCP_RX_CH
-#endif                                                                       
-                                               };
-    const uint16_t dmaFlow[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_FLOW, 
-#ifdef QMSS_MAX_AIF_QUEUE      
-                                                RM_CPPI_AIF_FLOW,
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_A_QUEUE                                                                       
-                                                RM_CPPI_FFTC_A_FLOW, 
-#endif                                                                       
-#ifdef QMSS_MAX_FFTC_B_QUEUE                                                                       
-                                                RM_CPPI_FFTC_B_FLOW, 
-#endif                                                                
-#ifdef QMSS_MAX_PASS_QUEUE
-                                                RM_CPPI_PASS_FLOW, 
-#endif                                                
-                                                RM_CPPI_QMSS_FLOW,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-                                                RM_CPPI_FFTC_C_FLOW,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
-                                                RM_CPPI_BCP_FLOW
-#endif                                                                       
-                                               }; 
-    
-    /* Invalidate all permission tables so no further invalidates are required
-      * on slave cores */
-
-    /* Global permissions object */
-    Rm_osalBeginMemAccess ((void *) &rmGPermsObj, sizeof (Rm_GlobalPermissionsObj));
-    
-    /* QMSS Permission Tables */
-
-    /* QMSS PDSPs */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssPdspFirmwarePerms, sizeof (Rm_Perms) * RM_QMSS_FIRMWARE_PDSPS);
-    /* QMSS Queues */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQueuePerms, sizeof (Rm_Perms) * RM_QMSS_QUEUES);
-    /* QMSS Memory Regions */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssMemRegionPerms, sizeof (Rm_Perms) * RM_QMSS_MEM_REGIONS);    
-    /* QMSS Linking RAM */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssLinkRamPerms, sizeof (Rm_qmssLinkingRamPerms) * RM_QMSS_LINKING_RAM_RANGES);
-    /* QMSS Accumulator Channels */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssAccumChPerms, sizeof (Rm_Perms) * RM_QMSS_ACCUM_CH);   
-    /* QMSS QOS Clusters */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQosClusterPerms, sizeof (Rm_Perms) * RM_QMSS_QOS_CLUSTER);   
-    /* QMSS QOS Queues */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQosQueuePerms, sizeof (Rm_Perms) * RM_QMSS_QOS_QUEUES);       
-
-    /* CPPI Permission Tables */
-    
-    /* CPPI DMA Transmit Channels */
-    for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
-    {
-        Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaTxCh[dmaIndex]); 
-    }
-    /* CPPI DMA Receive Channels */
-    for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
-    {
-        Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaRxCh[dmaIndex]); 
-    }
-    /* CPPI DMA Receive Flows */
-    for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
-    {
-        Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaFlow[dmaIndex]); 
-    }
-
-    /* PA permission tables */
-
-    /* PA Firmware invalidated as part of global permissions object invalidate */
-    /* PA LUTs */
-    Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.paLutPerms, sizeof (Rm_Perms) * RM_PA_LUT);   
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function extracts the initialization permission for a DSP from a resource
- *      permission element.
- *
- *  @param[in]  resourcePermissions
- *      A permissions structure element to extract the per DSP initialization permission
- *
- *  @retval
- *      Success -   RM_INIT_PERMISSION_APPROVED
- *  @retval
- *      Failure -   RM_INIT_PERMISSION_DENIED
- */
-Rm_Result Rm_getInitPermissions (Rm_Perms *resourcePermissions)
-{
-    /* Check the init permissions for the calling DSP */
-    if (!(RM_GET_PERMISSIONS(resourcePermissions->initPerms)))
-    {
-        return RM_INIT_PERMISSION_DENIED;
-    }
-  
-    return RM_INIT_PERMISSION_APPROVED;
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function extracts the usage permission for a DSP from a resource
- *      permission element.
- *
- *  @param[in]  resourcePermissions
- *      A permissions structure element to extract the per DSP usage permission
- *
- *  @retval
- *      Success -   RM_INIT_PERMISSION_APPROVED
- *  @retval
- *      Failure -   RM_INIT_PERMISSION_DENIED
- */
-Rm_Result Rm_getUsePermissions (Rm_Perms *resourcePermissions)
-{
-    /* Check the use permissions for the calling DSP */
-    if (!(RM_GET_PERMISSIONS(resourcePermissions->usePerms)))
-    {
-        return RM_USE_PERMISSION_DENIED;
-    }
-  
-    return RM_USE_PERMISSION_APPROVED;
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function searches the list of linking RAM address ranges to find one that has
- *      the requested linking RAM address within it.  If found the function returns the permissions
- *      for this range.  Otherwise it returns denied.
- *
- *  @param[in]  isInitCheck
- *      True - Permissions check is for initialization
- *      False - Permissions check is for usage
- *
- *  @param[in]  linkRamPermArray
- *      Internal array of linking RAM ranges and their permissions
- *
- *  @param[in]  linkRamResData
- *      Linking RAM addresses to check for initialization or usage permissions
- *
- *  @retval
- *      Success -   RM_INIT_PERMISSION_APPROVED
- *  @retval
- *      Failure -   RM_INIT_PERMISSION_DENIED
- */
-Rm_Result Rm_getLinkRamPermissions (Bool isInitCheck, Rm_qmssLinkingRamPerms *linkRamPermArray, Rm_ResourceInfo *linkRamResData)
-{
-    Rm_Result retVal;
-    uint16_t linkRamIndex;
-
-    /* Initialize the return value based on type of check boolean */
-    if (isInitCheck)
-    {
-        retVal = RM_INIT_PERMISSION_DENIED;
-    }
-    else
-    {
-        retVal = RM_USE_PERMISSION_DENIED;
-    }
-    
-    for (linkRamIndex = 0; linkRamIndex < RM_QMSS_LINKING_RAM_RANGES; linkRamIndex++)
-    {
-        if ((linkRamResData->res_info.linkRamData.linkRamStartIndex >= linkRamPermArray[linkRamIndex].startIndex) &&
-             (linkRamResData->res_info.linkRamData.linkRamEndIndex <= linkRamPermArray[linkRamIndex].endIndex))
-        {
-            /* Check the use permissions for the calling DSP */
-            if (isInitCheck)
-            {
-                if (RM_GET_PERMISSIONS(linkRamPermArray[linkRamIndex].rangePerms.initPerms))
-                {
-                    retVal = RM_USE_PERMISSION_APPROVED;
-                }
-            }
-            else
-            {
-                if (RM_GET_PERMISSIONS(linkRamPermArray[linkRamIndex].rangePerms.usePerms))
-                {
-                    retVal = RM_USE_PERMISSION_APPROVED;
-                }
-            }
-            break;
-        }
-    }
-
-    return (retVal);
-}
-
-/**********************************************************************
- **********APIs visible to other LLDs internally via call table *******************
- **********************************************************************/
-
-/**
- *  @b Description
- *  @n  
- *      This function is used by LLDs to check initialization permissions for a resource
- *
- *  @param[in]  resourceData
- *      Structure containing resource information such as resource type and the
- *      resource value to be checked
- *
- *  @retval
- *      Success -   RM_INIT_PERMISSION_APPROVED
- *  @retval
- *      Failure -   RM_INIT_PERMISSION_DENIED
- */
-Rm_Result Rm_initPermissionChecker (Rm_ResourceInfo *resourceData)
-{
-    switch (resourceData->resourceType)
-    {
-        case Rm_resource_QMSS_FIRMWARE_PDSP:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceData->res_info.pdspNum]));
-            
-        case Rm_resource_QMSS_QUEUE:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQueuePerms[resourceData->res_info.queNum]));
-            
-        case Rm_resource_QMSS_MEMORY_REGION:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssMemRegionPerms[resourceData->res_info.memRegion]));
-
-        case Rm_resource_QMSS_LINKING_RAM_CONTROL:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssLinkRamControlPerms));   
-            
-        case Rm_resource_QMSS_LINKING_RAM:
-            return (Rm_getLinkRamPermissions (TRUE, &rmGPermsObj.obj.qmssLinkRamPerms[0], resourceData));
-            
-        case Rm_resource_QMSS_ACCUM_CH:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssAccumChPerms[resourceData->res_info.accumCh]));  
-
-        case Rm_resource_QMSS_QOS_TIMER:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosPdspTimerPerms));   
-
-        case Rm_resource_QMSS_QOS_CLUSTER:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosClusterPerms[resourceData->res_info.qosCluster]));           
-
-        case Rm_resource_QMSS_QOS_QUEUE:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosQueuePerms[resourceData->res_info.qosQueue]));                
-            
-        case Rm_resource_CPPI_TX_CH:
-            {
-                Rm_Perms *txChPermsArray = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getInitPermissions(&txChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
-            }
-            
-        case Rm_resource_CPPI_RX_CH:
-            {
-                Rm_Perms *rxChPermsArray = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getInitPermissions(&rxChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
-            }
-            
-        case Rm_resource_CPPI_RX_FLOW:
-            {
-                Rm_Perms *flowPermsArray = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getInitPermissions(&flowPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));       
-            }
-            
-        case Rm_resource_PA_FIRMWARE:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.paFirmwarePerms));    
-            
-        case Rm_resource_PA_LUT:
-            return (Rm_getInitPermissions(&rmGPermsObj.obj.paLutPerms[resourceData->res_info.lutEntry]));   
-     
-        default:
-            return (RM_INIT_PERMISSION_DENIED);
-    }
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function is used by LLDs to check usage permissions for a resource
- *
- *  @param[in]  resourceData
- *      Structure containing resource information such as resource type and the
- *      resource value to be checked
- *
- *  @retval
- *      Success -   RM_INIT_PERMISSION_APPROVED
- *  @retval
- *      Failure -   RM_INIT_PERMISSION_DENIED
- */
-Rm_Result Rm_usePermissionChecker (Rm_ResourceInfo *resourceData)
-{
-    switch (resourceData->resourceType)
-    {
-        case Rm_resource_QMSS_FIRMWARE_PDSP:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceData->res_info.pdspNum]));
-            
-        case Rm_resource_QMSS_QUEUE:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQueuePerms[resourceData->res_info.queNum]));
-            
-        case Rm_resource_QMSS_MEMORY_REGION:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssMemRegionPerms[resourceData->res_info.memRegion]));
-
-        case Rm_resource_QMSS_LINKING_RAM_CONTROL:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssLinkRamControlPerms));   
-            
-        case Rm_resource_QMSS_LINKING_RAM:
-            return (Rm_getLinkRamPermissions(FALSE, &rmGPermsObj.obj.qmssLinkRamPerms[0], resourceData));
-            
-        case Rm_resource_QMSS_ACCUM_CH:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssAccumChPerms[resourceData->res_info.accumCh]));     
-
-        case Rm_resource_QMSS_QOS_TIMER:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosPdspTimerPerms));   
-
-        case Rm_resource_QMSS_QOS_CLUSTER:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosClusterPerms[resourceData->res_info.qosCluster]));           
-
-        case Rm_resource_QMSS_QOS_QUEUE:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosQueuePerms[resourceData->res_info.qosQueue]));                
-            
-        case Rm_resource_CPPI_TX_CH:
-            {
-                Rm_Perms *txChPermsArray = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getUsePermissions(&txChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
-            }
-            
-        case Rm_resource_CPPI_RX_CH:
-            {
-                Rm_Perms *rxChPermsArray = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getUsePermissions(&rxChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
-            }
-            
-        case Rm_resource_CPPI_RX_FLOW:
-            {
-                Rm_Perms *flowPermsArray = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
-                return (Rm_getUsePermissions(&flowPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));       
-            }
-            
-        case Rm_resource_PA_FIRMWARE:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.paFirmwarePerms));    
-            
-        case Rm_resource_PA_LUT:
-            return (Rm_getUsePermissions(&rmGPermsObj.obj.paLutPerms[resourceData->res_info.lutEntry]));  
-     
-        default:
-            return (RM_USE_PERMISSION_DENIED);
-    }
-}
-
-/*  */
-
-/**********************************************************************
- *********************** Application visible APIs ***************************
- **********************************************************************/
-
-/** @addtogroup RM_LLD_FUNCTION
-@{ 
-*/
-
-/**
- *  @b Description
- *  @n  
- *      This function initializes the Resource Manager low level driver
- *      This function is called once in the system to setup the Resource Manager 
- *      low level driver by mapping the application defined resource table to internal
- *      permission tables.  After mapping is complete a global synchronization object
- *      is written to sync with slave cores
- *
- *  @param[in]  rmResourceTable
- *      Resource table defined by application.  Used to populate internal permission
- *      tables.
- *
- *  @post  
- *      RM LLD global permissions are set.
- *
- *  @retval
- *      Success -   RM_OK
- *  @retval
- *      Failure -   RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED
- */
-Rm_Result Rm_init (const Rm_Resource *rmResourceTable)
-{
-    void *key;
-    Rm_Result ret_val = RM_ERROR;
-
-    /* Check permission structure sizes to make sure they're evenly
-      * divisible into a cache line.  This generates no object code when
-      * optimizer is on.  If failes, assert will occur at compile time */
-    RM_COMPILE_TIME_SIZE_CHECK((RM_MAX_CACHE_ALIGN/sizeof(Rm_Perms)) * sizeof(Rm_Perms) == RM_MAX_CACHE_ALIGN);
-    RM_COMPILE_TIME_SIZE_CHECK((RM_MAX_CACHE_ALIGN/sizeof(Rm_qmssLinkingRamPerms)) * \
-                                                          sizeof(Rm_qmssLinkingRamPerms) == RM_MAX_CACHE_ALIGN);
-
-    /* Begin Critical Section before accessing shared resources. */
-    key = Rm_osalCsEnter ();
-    
-    /* Initialize the permissions table */
-    Rm_permissionTableInit();
-
-    if (!rmResourceTable)
-    {
-        /* End Critical Section */
-        Rm_osalCsExit (key);
-        return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
-    }
-
-    ret_val = Rm_populatePermissionTable(rmResourceTable);
-
-    /* End Critical Section */
-    Rm_osalCsExit (key);
-    return ret_val;
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function waits for the Resource Manager master to populate the 
- *      global permissions table based on a global sync object.  Once the
- *      global sync object has been written by the master core this function
- *      will invalidate all permissions tables.  Since the permissions table are
- *      static, and will not change through the system up-time, a single
- *      invalidation at the start will suffice.
- *      
- *      This function can be called on all core besides that which called
- *      Rm_init.  Calling this function on said cores will act as a blocking
- *      synchronization point.
- *
- *  @retval
- *      Success -   RM_OK
- *  @retval
- *      Failure -   RM_FAILURE
- */
-Rm_Result Rm_start (void)
-{
-    /* Loop until the global sync object signals the permissions table has been
-      * populated and valid */
-    do
-    {
-        /* Invalidate the global sync object */
-        Rm_osalBeginMemAccess ((void *) &rmGSyncObj, sizeof (Rm_Sync_Obj));
-    } while (rmGSyncObj.obj.globalSyncObj != RM_PERMISSION_TABLE_VALID);
-
-    /* Master core finished populating the permission tables.  Must invalidate
-      * all tables to see latest permissions */
-    Rm_updatePermissionTables();
-
-    return RM_OK;
-}
-
-/**
- *  @b Description
- *  @n  
- *      This function returns an RM handle to the application to provide
- *      to LLDs that want to use the RM.
- *
- *  @retval
- *      Success -   RM Handle.  Used an an input parameter for LLD startCfg functions.
- *  @retval
- *      Failure -   NULL
- */
-Rm_Handle Rm_getHandle(void)
-{
-   return ((void *) &rmPermissionCheckers);
-}
-
-/**
- *  @b Description
- *  @n  
- *      The function is used to get the version information of the RM LLD.
- *
- *  @retval
- *      Version Information.
- */
-uint32_t Rm_getVersion (void)
-{
-    return RM_LLD_VERSION_ID;
-}
-
-/**
- *  @b Description
- *  @n  
- *      The function is used to get the version string for the RM LLD.
- *
- *  @retval
- *      Version String.
- */
-const char* Rm_getVersionStr (void)
-{
-    return rmLldVersionStr;
-}
-
-/**
-@}
-*/
+/**\r
+ *   @file  rm.c\r
+ *\r
+ *   @brief   \r
+ *      This is the Resource Manager source.\r
+ *\r
+ *  \par\r
+ *  ============================================================================\r
+ *  @n   (C) Copyright 2012, Texas Instruments, Inc.\r
+ * \r
+ *  Redistribution and use in source and binary forms, with or without \r
+ *  modification, are permitted provided that the following conditions \r
+ *  are met:\r
+ *\r
+ *    Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its contributors may be used to endorse or promote products derived\r
+ *    from this software without specific prior written permission.\r
+ *\r
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ *  \par\r
+*/\r
+\r
+/* RM Types */\r
+#include <ti/drv/rm/rm_types.h>\r
+\r
+/* RM external includes */\r
+#include <ti/drv/rm/rm.h>\r
+#include <ti/drv/rm/rm_services.h>\r
+#include <ti/drv/rm/rm_transport.h>\r
+#include <ti/drv/rm/rm_policy.h>\r
+\r
+/* RM internal includes */\r
+#include <ti/drv/rm/include/rm_loc.h>\r
+#include <ti/drv/rm/include/rm_transportloc.h>\r
+#include <ti/drv/rm/include/rm_servicesloc.h>\r
+#include <ti/drv/rm/include/rm_nameserverloc.h>\r
+#include <ti/drv/rm/include/rm_dtb_utilloc.h>\r
+\r
+/* RM LIBFDT includes */\r
+#include <ti/drv/rm/src/libfdt/libfdt.h>\r
+\r
+/* AVL BBST includes */\r
+#include <ti/drv/rm/include/tree.h>\r
+\r
+/* RM OSAL layer */\r
+#include <rm_osal.h>\r
+\r
+/**********************************************************************\r
+ ************************** Globals ***********************************\r
+ **********************************************************************/\r
+char rmIntegerAllocator[] = "integer";\r
+char rmTreeAllocator[] = "tree";\r
+\r
+extern char rmDtbStartingNode[];\r
+\r
+/** @brief Global Variable which describes the RM Version Information */\r
+const char   rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;\r
+\r
+/**********************************************************************\r
+ ************** Red-Black BBST Tree Allocator Functions ***************\r
+ **********************************************************************/\r
+\r
+/* Prototype for function that allocates new tree nodes */\r
+Rm_ResourceTreeNode *Rm_newResourceTreeNode(uint32_t resourceBase, uint32_t resourceLength, \r
+                                            char *allocatedTo)\r
+{\r
+    Rm_ResourceTreeNode *newNode = NULL;\r
+\r
+    newNode = Rm_osalMalloc(sizeof(Rm_ResourceTreeNode));\r
+\r
+    /* Populate the RM relevant fields */\r
+    newNode->base = resourceBase;\r
+    newNode->length = resourceLength;\r
+    strcpy(newNode->allocatedTo, allocatedTo);\r
+\r
+    return(newNode);\r
+}\r
+\r
+/* Prototype for function that frees new tree nodes */\r
+void Rm_freeResourceTreeNode(Rm_ResourceTreeNode *treeNode)\r
+{\r
+    /* Free the memory associated with the tree node. */\r
+    Rm_osalFree((void *)treeNode, sizeof(Rm_ResourceTreeNode));\r
+}\r
+\r
+/* Prototype for tree node comparison function\r
+ * element1 < element2 --> return < 0\r
+ * element1 = element2 --> return 0\r
+ * element1 > element2 --> return > 0 */\r
+int Rm_ResourceTreeNodeCompare(Rm_ResourceTreeNode *element1, Rm_ResourceTreeNode *element2)\r
+{\r
+    uint32_t element1End = element1->base + element1->length - 1;\r
+    uint32_t element2End = element2->base + element2->length - 1;\r
+\r
+    if (element1End < element2->base)\r
+    {\r
+        /* End of element1 range is less than the start of element2's range.  Return a negative\r
+         * value */\r
+        return (-1);\r
+    }\r
+    else if (element1->base > element2End)\r
+    {\r
+        /* Start of element1 range is after end of element2's range.  Return a positive value */\r
+        return (1);\r
+    }\r
+    else\r
+    {\r
+        /* If neither of the latter conditions were satisfied there is some overlap between\r
+         * element1 and element2.  Return 0 since the application must handle this overlap. */\r
+        return (0);\r
+    }\r
+}\r
+\r
+/* Generate the red-black tree manipulation functions */\r
+RB_GENERATE(_Rm_ResourceTree, _Rm_ResourceTreeNode, linkage, Rm_ResourceTreeNodeCompare);\r
+\r
+/**********************************************************************\r
+ ********************** Internal Functions ****************************\r
+ **********************************************************************/\r
+\r
+Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst)\r
+{\r
+    Rm_Transaction *transactionQueue = (Rm_Transaction *)rmInst->transactionQueue;\r
+    Rm_Transaction *newTransaction = NULL;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's transaction queue */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Get memory for a new transaction from local memory */\r
+    newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));\r
+\r
+    /* Return if the memory allocated for the transaction entry is NULL */\r
+    if (newTransaction == NULL)\r
+    {\r
+        /* Clear the transaction */\r
+        memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
+\r
+        /* Create an ID for the new transaction.  The ID will be used for two purposes:\r
+         * 1) Matching responses from higher level RM agents to requests\r
+         * 2) Provided to the component that requested the service so that it can match its\r
+         *    request with the response it receives via its callback function it provided */\r
+        newTransaction->localId = Rm_transactionGetSequenceNum(rmInst);\r
+        /* New transaction's nextTransaction pointer will always be NULL */\r
+        newTransaction->nextTransaction = NULL;  \r
+\r
+        /* Check if there are any transactions in the transaction queue */\r
+        if (transactionQueue)\r
+        {\r
+            /* At least one transaction in the transaction queue.  Add the new entry to the \r
+             * end of the transaction queue */\r
+            while (transactionQueue->nextTransaction != NULL)\r
+            {\r
+                /* Traverse the list until arriving at the last transaction */\r
+                transactionQueue = transactionQueue->nextTransaction;\r
+            }\r
+\r
+            /* Add the new transaction to the end of the queue */\r
+            transactionQueue->nextTransaction = newTransaction;\r
+        }\r
+        else\r
+        {\r
+            /* The transaction queue does not currently exist.  The new transaction is the \r
+             * first transaction */\r
+            rmInst->transactionQueue = newTransaction;\r
+        }\r
+    }\r
+\r
+    Rm_osalMtCsExit(key);\r
+    return (newTransaction);\r
+}\r
+\r
+Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)\r
+{\r
+    Rm_Transaction *transaction = (Rm_Transaction *)rmInst->transactionQueue;\r
+\r
+    /* Make sure there is at least one transaction in the transaction queue */\r
+    if (transaction != NULL)\r
+    {\r
+        /* Find the transaction ID within the specified RM instance's transaction queue.\r
+         * If the end of the transaction queue is reached without finding the transaction the \r
+         * transaction pointer will be NULL */\r
+        while (transaction != NULL)\r
+        {\r
+            if (transaction->localId == transactionId)\r
+            {\r
+                /* Match: break out of loop and return the transaction */\r
+                break;             \r
+            }\r
+            transaction = transaction->nextTransaction;\r
+        }\r
+    }\r
+\r
+    return (transaction);\r
+}\r
+\r
+int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
+{\r
+    Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
+    Rm_Transaction *prevTransaction = NULL;\r
+    int32_t retVal = RM_SERVICE_STATE_OKAY;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's transaction queue */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Find the transaction ID within the specified RM instance's transaction queue. */\r
+    while (transaction != NULL)\r
+    {\r
+        if (transaction->localId == transactionId)\r
+        {\r
+            /* Match: break out of loop and delete the transaction */\r
+            break;             \r
+        }\r
+\r
+        prevTransaction = transaction;\r
+        transaction = transaction->nextTransaction;\r
+    }\r
+\r
+    /* Traversed entire queue but did not find transaction */\r
+    if (transaction == NULL)\r
+    {\r
+        retVal = RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST;\r
+    }\r
+    else\r
+    {\r
+        /* Delete the transaction */\r
+        if ((prevTransaction == NULL) && transaction->nextTransaction)\r
+        {\r
+            /* Transaction to be deleted exists at start of transaction queue.  Map second\r
+             * transaction to be start of transaction queue as long as there are more than\r
+             * one transactions. */\r
+            rmInst->transactionQueue = transaction->nextTransaction;\r
+        }\r
+        else\r
+        {\r
+            /* Transaction to be deleted is in the middle or at end of the queue.  Adjust \r
+             * adjacent transaction pointers.  This covers the case where the transaction to be \r
+             * removed is at the end of the queue. */\r
+            prevTransaction->nextTransaction = transaction->nextTransaction;\r
+        }\r
+\r
+        /* Free the memory associated with the transaction. */\r
+        Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));\r
+    }\r
+\r
+    Rm_osalMtCsExit(key);\r
+    return (retVal);\r
+}\r
+\r
+uint32_t Rm_transactionInitSequenceNum(void)\r
+{\r
+    /* Sequence number can never have a value of zero so that there are no conflicts\r
+     * with transactions that have a remoteOriginatingId of zero */\r
+    return (1);\r
+}\r
+\r
+uint32_t Rm_transactionGetSequenceNum(Rm_Inst *rmInst)\r
+{\r
+    uint32_t sequenceNum = 0;\r
+\r
+    /* Get the next sequence number and then increment.  If there's an overflow\r
+     * assign the initial value instead of incrementing. */\r
+    if (rmInst->transactionSeqNum + 1 < rmInst->transactionSeqNum)\r
+    {\r
+        /* Overflow */\r
+        sequenceNum = rmInst->transactionSeqNum;\r
+        rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
+    }\r
+    else\r
+    {\r
+        sequenceNum = rmInst->transactionSeqNum++;\r
+    }    \r
+\r
+    return (sequenceNum);\r
+}\r
+\r
+/* Function used to send RM response transactions to lower level agents */\r
+void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    Rm_TransportNode *dstTransportNode = NULL;\r
+    Rm_Packet *rmPkt = NULL;\r
+\r
+    /* Find the transport for the RM instance that sent the request. */\r
+    dstTransportNode = Rm_transportNodeFindRemoteName(rmInst, transaction->sourceInstName);\r
+\r
+    /* Create a RM packet using the service information */\r
+    switch (transaction->type)\r
+    {\r
+        case Rm_service_RESOURCE_ALLOCATE:\r
+        case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+        case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+        case Rm_service_RESOURCE_FREE:\r
+        case Rm_service_RESOURCE_BLOCK_FREE:\r
+        case Rm_service_RESOURCE_FREE_BY_NAME:\r
+            rmPkt = Rm_transportCreateResourceResponsePkt(rmInst, dstTransportNode, \r
+                                                          transaction);\r
+            break;\r
+        case Rm_service_RESOURCE_MAP_TO_NAME:\r
+        case Rm_service_RESOURCE_UNMAP_NAME:\r
+            rmPkt = Rm_transportCreateNsResponsePkt(rmInst, dstTransportNode,\r
+                                                    transaction);\r
+            break;\r
+        default:\r
+            /* Invalid service type.  Flag the error and return */\r
+            transaction->state = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+            break;\r
+    }\r
+\r
+    if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
+    {\r
+        /* Delete the transaction and return immediately because an error occurred \r
+         * allocating the packet */\r
+        Rm_transactionQueueDelete(rmInst, transaction->localId);\r
+        return;\r
+    }\r
+\r
+    /* Send the RM packet to the application transport */\r
+    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
+    {\r
+        /* Negative value returned by transport send.  An error occurred\r
+         * in the transport while attempting to send the packet.*/\r
+        transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+        /* Clean up the packet */\r
+        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
+        {\r
+            /* Non-NULL value returned by transport packet free. Flag the\r
+             * error */\r
+            transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
+        }\r
+        return;\r
+    }\r
+\r
+    /* NEED TO DO SOMETHING IF GET AN ERROR IN THE transaction->state FIELD.  CREATE\r
+     * NEW TRANSACTION WITH DATA FROM ORIGINAL?  THEN TRY TO SEND FAILED REQUEST BACK\r
+     * TO REQUESTER???  KEEP RETRYING SEND OF RESPONSE??? */\r
+\r
+    /* Delete the transaction */\r
+    Rm_transactionQueueDelete(rmInst, transaction->localId);\r
+}\r
+\r
+Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName, Rm_AllocatorType type)\r
+{\r
+    Rm_Allocator *allocators = (Rm_Allocator *)rmInst->allocators;\r
+    Rm_Allocator *newAllocator = NULL;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's allocator list */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Get memory for a new allocator from local memory */\r
+    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));\r
+\r
+    /* Return if the memory allocated for the allocator is NULL */\r
+    if (newAllocator != NULL)\r
+    {\r
+        /* Clear the allocator */\r
+        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
+\r
+        /* Populate the allocator */\r
+        newAllocator->type = type;\r
+        strcpy(newAllocator->resourceName, resourceName);\r
+        /* allocator's root entry will be created by the invoking function */\r
+        newAllocator->allocatorRootEntry = NULL;\r
+        /* New allocator's nextAllocator pointer will always be NULL */\r
+        newAllocator->nextAllocator = NULL;  \r
+\r
+        /* Check if there are any allocators in the allocator list */\r
+        if (allocators)\r
+        {\r
+            /* At least one allocator in the allocator list.  Add the new allocator to the \r
+             * end of the allocator list */\r
+            while (allocators->nextAllocator != NULL)\r
+            {\r
+                /* Traverse the list until arriving at the last allocator */\r
+                allocators = allocators->nextAllocator;\r
+            }\r
+\r
+            /* Add the new allocator to the end of the list */\r
+            allocators->nextAllocator = newAllocator;\r
+        }\r
+        else\r
+        {\r
+            /* The allocator list does not currently exist.  The new allocator is the \r
+             * first allocator */\r
+            rmInst->allocators = newAllocator;\r
+        }\r
+    }\r
+\r
+    Rm_osalMtCsExit(key);\r
+    return (newAllocator);\r
+}\r
+\r
+Rm_Allocator *Rm_allocatorFind(Rm_Inst *rmInst, char *resourceName)\r
+{\r
+    Rm_Allocator *allocator = (Rm_Allocator *)rmInst->allocators;\r
+\r
+    /* Make sure there is at least one allocator in the allocator list */\r
+    if (allocator != NULL)\r
+    {\r
+        /* Find the resource name within the allocator list.  If the end of the\r
+         * allocator list is reached without finding the resource name the \r
+         * allocator pointer will be NULL */\r
+        while (allocator != NULL)\r
+        {\r
+            if (strcmp(allocator->resourceName, resourceName) == 0)\r
+            {\r
+                /* Match: break out of loop and return the allocator */\r
+                break;             \r
+            }\r
+            allocator = allocator->nextAllocator;\r
+        }\r
+    }\r
+\r
+    return (allocator);\r
+}\r
+\r
+int32_t Rm_allocatorDelete(Rm_Inst *rmInst, char *resourceName)\r
+{\r
+    Rm_Allocator *allocator = (Rm_Allocator *) rmInst->allocators;\r
+    Rm_Allocator *prevAllocator = NULL;\r
+    int32_t retVal = RM_SERVICE_STATE_OKAY;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's allocator list */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Find the resource within the specified RM instance's allocator list. */\r
+    while (allocator != NULL)\r
+    {\r
+        if (strcmp(allocator->resourceName, resourceName) == 0)\r
+        {\r
+            /* Match: break out of loop and delete the transaction */\r
+            break;             \r
+        }\r
+\r
+        prevAllocator = allocator;\r
+        allocator = allocator->nextAllocator;\r
+    }\r
+\r
+    /* Traversed entire list but did not find allocator. */\r
+    if (allocator == NULL)\r
+    {\r
+        retVal = -22; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+    }\r
+    else\r
+    {\r
+        /* Delete the allocator */\r
+        if ((prevAllocator == NULL) && allocator->nextAllocator)\r
+        {\r
+            /* Allocator to be deleted exists at start of allocator list.  Map second\r
+             * allocator to be start of allocator list as long as there are more than\r
+             * one allocators. */\r
+            rmInst->allocators = allocator->nextAllocator;\r
+        }\r
+        else\r
+        {\r
+            /* Allocator to be deleted is in the middle or at end of the list.  Adjust \r
+             * adjacent allocator pointers.  This covers the case where the allocator to be \r
+             * removed is at the end of the list. */\r
+            prevAllocator->nextAllocator = allocator->nextAllocator;\r
+        }\r
+\r
+        /* Free the memory associated with the allocator. */\r
+        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));\r
+    }\r
+\r
+    Rm_osalMtCsExit(key);\r
+    return (retVal);\r
+}\r
+\r
+int32_t Rm_createIntegerAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
+{\r
+    Rm_Allocator *allocator = NULL;\r
+    Rm_ResourceRange *rangeBasePtr = range;\r
+    Rm_IntegerAllocatorRootEntry *intRootEntry = NULL;\r
+    uint16_t i, entryIndex;\r
+\r
+    /* Create the new base integer allocator */\r
+    allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_INTEGER);\r
+\r
+    /* Construct the integer allocator root entry */\r
+    intRootEntry = Rm_osalMalloc(sizeof(Rm_IntegerAllocatorRootEntry));\r
+    intRootEntry->numResourceElements = 0;\r
+\r
+    /* Get the number of entries to allocate based on the lengths in the ranges */\r
+    while (range != NULL)\r
+    {\r
+        intRootEntry->numResourceElements += range->length;\r
+        range = range->nextRange;\r
+    }\r
+\r
+    /* Initialize the entries using the range information */\r
+    if (intRootEntry->numResourceElements)\r
+    {\r
+        intRootEntry->resourceArrayBase = Rm_osalMalloc(sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
+        memset((void *)intRootEntry->resourceArrayBase, 0, sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
+\r
+        /* Reset the range pointer */\r
+        range = rangeBasePtr;\r
+        entryIndex = 0;\r
+\r
+        while (range != NULL)\r
+        {\r
+            /* Initialize each entry */\r
+            for (i = range->base; i < (range->base + range->length); i++, entryIndex++)\r
+            {\r
+                intRootEntry->resourceArrayBase[entryIndex].value = i;\r
+                /* Initialize the allocatedTo field to the NOT_ALLOCATED string */\r
+                strcpy(intRootEntry->resourceArrayBase[entryIndex].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+            }\r
+            \r
+            range = range->nextRange;\r
+        }\r
+        \r
+        allocator->allocatorRootEntry = intRootEntry;\r
+    }\r
+    else\r
+    {\r
+        /* No resource entries were created.  Free the memory associated with the\r
+         * allocator and the root entry */\r
+        Rm_osalFree((void *)intRootEntry, sizeof(Rm_IntegerAllocatorRootEntry));\r
+        Rm_allocatorDelete(rmInst, allocator->resourceName);\r
+    }\r
+\r
+    return(0);  /* TODO: FIX THIS RETURN */\r
+}\r
+\r
+/* Called when an allocate request is made but the base is unspecified.  RM must preallocate\r
+ * resources which then must be checked against the RM policy for the instance.  If the\r
+ * policy does not agree another resource(s) must be preallocated and tested against the \r
+ * policy.  Policy will provide initialize the preallocate with the base that it allows\r
+ * for the rm instance for the specified resource. */\r
+int32_t Rm_integerPreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
+    Rm_IntegerEntry *resourceArray = root->resourceArrayBase;\r
+    uint16_t index, i;\r
+    bool resourcesValidated;\r
+    int32_t retVal = RM_SERVICE_PROCESSING;\r
+\r
+    /* Find the specified resource base within the allocator */\r
+    for (index = 0; index < root->numResourceElements; index++)\r
+    {\r
+        if (resourceArray[index].value == opInfo->resourceInfo->base)\r
+        {\r
+            /* Found the resource base in the allocator.  Break from the loop */\r
+            break;\r
+        }\r
+    } \r
+\r
+    /* Only execute the allocate operation if the resource base was found in the allocator\r
+     * and the base+length does not exceed the number of entries in the allocator */\r
+    if ((index + opInfo->resourceInfo->length) <= root->numResourceElements)\r
+    {\r
+        /* Search for a contiguous block of unallocated resources of length "length"\r
+         * and with the alignment specified */\r
+        while ((index + opInfo->resourceInfo->length) <= root->numResourceElements)\r
+        {\r
+            resourcesValidated = FALSE;            \r
+            \r
+            /* Does the resource base value satisfy the alignment? */\r
+            if ((resourceArray[index].value % opInfo->resourceInfo->alignment) == 0)\r
+            {\r
+                /* Check to see all the resource values in the requested range are free */\r
+                resourcesValidated = TRUE;\r
+                for (i = index; i < opInfo->resourceInfo->length; i++)\r
+                {\r
+                    if (strcmp(resourceArray[i].allocatedTo, RM_NOT_ALLOCATED_STRING) != 0)\r
+                    {\r
+                        /* A resource within the range was already allocated.  Update the\r
+                         * index to the resource after the allocated resource and continue \r
+                         * looking. */\r
+                        index = i + 1;\r
+                        resourcesValidated = FALSE;\r
+                        /* Break out of the for loop */\r
+                        break;\r
+                    }\r
+                }\r
+\r
+                if (resourcesValidated)\r
+                {\r
+                    /* Found a set of resources that satisfies the request requirements.  Return\r
+                     * the results to be tested against the policy.  If the policy approves the\r
+                     * resources will be allocated via the Rm_integerAllocate API. */\r
+                    opInfo->resourceInfo->base = resourceArray[index].value;\r
+                    /* Break out of the while loop */\r
+                    break;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                /* Jump to the next resource value that satisfies the alignment */\r
+                for (; index < root->numResourceElements; index++)\r
+                {\r
+                    if ((resourceArray[index].value % opInfo->resourceInfo->alignment) == 0)\r
+                    {\r
+                        /* Found the next resource value that satisfies the alignment */\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        if (!resourcesValidated)\r
+        {\r
+            retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal);     \r
+}\r
+\r
+/* Assumes resource range for allocation has already been approved by the policy */\r
+int32_t Rm_integerAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
+    uint16_t resourceIndex, i, j;\r
+    bool resourcesValidated = TRUE;\r
+    int32_t retVal;\r
+\r
+    /* Find the specified resource base within the allocator */\r
+    for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
+    {\r
+        if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
+        {\r
+            /* Found the resource base in the allocator.  Break from the loop */\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Only execute the allocate operation if the resource base was found in the allocator\r
+     * and the base+length does not exceed the number of entries in the allocator */\r
+    if ((resourceIndex + opInfo->resourceInfo->length) <= root->numResourceElements)\r
+    {\r
+        /* Verify all resource values from base to base+length exist in the allocator and\r
+         * are not allocated to another instance. */\r
+        for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
+             i < (resourceIndex + opInfo->resourceInfo->length);\r
+             i++, j++)\r
+        {\r
+            if (root->resourceArrayBase[i].value != j)\r
+            {\r
+                /* A value in the range did not match. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+                resourcesValidated = FALSE;\r
+                break;\r
+            }\r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) != 0)\r
+            {\r
+                /* A value in the range is already allocated. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
+                resourcesValidated = FALSE;\r
+                break;            \r
+            }\r
+        }\r
+\r
+        if (resourcesValidated)\r
+        {\r
+            /* Allocate all resources from base to base+length */\r
+            for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->length); i++)\r
+            {\r
+                strcpy(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName);\r
+            }\r
+            retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal); \r
+}\r
+\r
+/* Assumes resource range for free has already been approved by the policy */\r
+int32_t Rm_integerFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
+    uint16_t resourceIndex, i, j;\r
+    bool resourcesValidated = TRUE;\r
+    int32_t retVal;\r
+\r
+    /* Find the specified resource base within the allocator */\r
+    for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
+    {\r
+        if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
+        {\r
+            /* Found the resource base in the allocator.  Break from the loop */\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Only execute the free operation if the resource base was found in the allocator\r
+     * and the base+length does not exceed the number of entries in the allocator */\r
+    if ((resourceIndex + opInfo->resourceInfo->length) <= root->numResourceElements)\r
+    {\r
+        /* Verify all resource values from base to base+length exist in the allocator,\r
+         * were not already free and were allocated to the instance that is the source\r
+         * of the free request. */\r
+        for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
+             i < (resourceIndex + opInfo->resourceInfo->length);\r
+             i++, j++)\r
+        {\r
+            if (root->resourceArrayBase[i].value != j)\r
+            {\r
+                /* A value in the range did not match. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+                resourcesValidated = FALSE;\r
+                break;\r
+            }\r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
+            {\r
+                /* A value in the range is already free. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
+                resourcesValidated = FALSE;\r
+                break;            \r
+            }            \r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName) != 0)\r
+            {\r
+                /* A value in the range was not allocated to the source of\r
+                 * the free request */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
+                resourcesValidated = FALSE;\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (resourcesValidated)\r
+        {\r
+            /* Free all resources from base to base+length */\r
+            for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->length); i++)\r
+            {\r
+                strcpy(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+            }\r
+            retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal);\r
+}\r
+\r
+int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
+{\r
+    Rm_Allocator *allocator = NULL;\r
+    Rm_ResourceTree *treeRootEntry = NULL;\r
+    Rm_ResourceTreeNode *treeNode = NULL;\r
+    Rm_ResourceTreeNode *collidingNode = NULL;\r
+\r
+    /* Create the new base integer allocator */\r
+    allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_TREE);\r
+\r
+    /* Create the tree root entry and initialize it */\r
+    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
+    RB_INIT(treeRootEntry);\r
+\r
+    /* Create a node in the tree for resource range and insert them into the tree. */\r
+    while (range != NULL)\r
+    {\r
+        treeNode = Rm_newResourceTreeNode(range->base, range->length, RM_NOT_ALLOCATED_STRING);\r
+\r
+        /* Insert the node into the tree */\r
+        collidingNode = RB_INSERT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
+\r
+        if (collidingNode)\r
+        {\r
+            Rm_ResourceTreeNode *nextNode = NULL;\r
+            \r
+            /* Node that was inserted colliding with an existing node.  Clean up the tree\r
+             * that's been allocated thus far and return an error since there should be no\r
+             * collisions */\r
+            for (treeNode = RB_MIN(_Rm_ResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode)\r
+            {\r
+                       nextNode = RB_NEXT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
+                       RB_REMOVE(_Rm_ResourceTree, treeRootEntry, nextNode);\r
+                Rm_freeResourceTreeNode(treeNode);\r
+               }\r
+            /* Delete the tree root entry and the allocator */\r
+            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));\r
+            Rm_allocatorDelete(rmInst, allocator->resourceName);\r
+            return (-24); /* TODO FIX RETURN */\r
+        }\r
+\r
+        range = range->nextRange;\r
+    }\r
+\r
+    /* Assign the tree's root to the allocator */\r
+    allocator->allocatorRootEntry = treeRootEntry;\r
+\r
+    return(0);   /* TODO: FIX THIS RETURN */\r
+}\r
+\r
+/* Called when an allocate request is made but the base is unspecified.  RM must preallocate\r
+ * resources which then must be checked against the RM policy for the instance.  If the\r
+ * policy does not agree another resource(s) must be preallocated and tested against the \r
+ * policy.  Policy will provide initialize the preallocate with the base that it allows\r
+ * for the rm instance for the specified resource. */\r
+int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_ResourceTreeNode findNode;\r
+    Rm_ResourceTreeNode *matchingNode = NULL;\r
+    uint32_t policyRangeEnd = opInfo->policyBase + opInfo->policyLength - 1;\r
+    uint32_t index;\r
+    bool resourceFound = FALSE;\r
+    int32_t retVal = RM_SERVICE_PROCESSING;\r
+\r
+    /* Find the tree node that contains the first value in the specified policy range. */\r
+    findNode.base = opInfo->policyBase;\r
+    findNode.length = 1;\r
+    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
+\r
+    if (matchingNode != NULL)\r
+    {\r
+        /* Begin searching for an available range of resources starting from the\r
+         * matching node */\r
+        for (index = matchingNode->base; index <= policyRangeEnd;)\r
+        {\r
+            /* Is the matchingNode free? */\r
+            if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
+            {\r
+                uint32_t matchEnd = matchingNode->base + matchingNode->length - 1;\r
+\r
+                /* Move index to the first resource satisfying the alignment property */\r
+                if ((index % opInfo->policyAlignment) != 0)\r
+                {\r
+                    index += (opInfo->policyAlignment - (index % opInfo->policyAlignment));\r
+                }\r
+                \r
+                /* Move through the node's resource range looking for a contiguous set of resources\r
+                 * that satisfy the request. */\r
+                while ((index <= matchEnd) && (index <= policyRangeEnd))\r
+                {\r
+                    if (((index + opInfo->resourceInfo->length - 1) <= matchEnd) &&\r
+                        ((index + opInfo->resourceInfo->length - 1) <= policyRangeEnd))\r
+                    {\r
+                        /* Found a resource range in the node that satisfies the requirements */\r
+                        opInfo->resourceInfo->base = index;\r
+                        resourceFound = TRUE;\r
+                        break;\r
+                    }\r
+\r
+                    /* Move index to the next resource value that satisfies the alignment property */\r
+                    index += (opInfo->policyAlignment - (index % opInfo->policyAlignment));\r
+                }\r
+            }\r
+            \r
+            if (!resourceFound)\r
+            {\r
+                /* Move to the next tree node */\r
+                matchingNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                if (matchingNode == NULL)\r
+                {\r
+                    /* Reached end of tree.  Resource range does not exist.  Leave the search\r
+                     * loop */\r
+                    break;\r
+                }\r
+                else\r
+                {\r
+                    index = matchingNode->base;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                /* Found a resource range that satisfies the request properties.  Break out of the\r
+                 * search loop */\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (!resourceFound)\r
+        {\r
+            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal); \r
+}\r
+\r
+/* Assume the policy has already approved of the allocation */\r
+int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_ResourceTreeNode findNode;\r
+    Rm_ResourceTreeNode *matchingNode = NULL;\r
+    Rm_ResourceTreeNode *leftNode = NULL;\r
+    Rm_ResourceTreeNode *rightNode = NULL;  \r
+    uint32_t findEnd, matchingEnd;\r
+    int32_t retVal;\r
+\r
+    /* Find the tree node that contains the specified resource range */\r
+    findNode.base = opInfo->resourceInfo->base;\r
+    findNode.length = opInfo->resourceInfo->length;\r
+    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
+\r
+    if (matchingNode != NULL)\r
+    {\r
+        findEnd = findNode.base + findNode.length - 1;\r
+        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
+        \r
+        /* Does the request range fit within the matching nodes entire range? */\r
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
+        {\r
+            /* Handle node create, combine, deletion based on the request range if\r
+             * resources are available. */\r
+            if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
+            {\r
+                /* Handle case where the findNode range matches the matchingNode\r
+                 * range exactly.\r
+                 *\r
+                 * base0                                  base0+length0-1\r
+                 *   |<---------------length0------------------->|  => existing node\r
+                 *   |<---------------length1------------------->|  => requested resources\r
+                 * base1                                  base1+length1-1\r
+                 */    \r
+                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
+                {\r
+                    /* Can reserve matchingNode's resources in-place */\r
+                    strcpy(matchingNode->allocatedTo, opInfo->srcInstName);\r
+                }\r
+                /* Handle case where the findNode range is a subset of the matchingNode\r
+                 * range and neither of the boundaries of the two ranges are equivalent.\r
+                 *\r
+                 * base0                                  base0+length0-1\r
+                 *   |<---------------length0------------------->|  => existing node\r
+                 *         |<---------length1---------->|  => requested resources\r
+                 *       base1                   base1+length1-1\r
+                 */    \r
+                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
+                {\r
+                    /* Split the matching node into three nodes:\r
+                     * left node - free resources to left of newly allocated resources\r
+                     * middle node - newly allocated resources that satisfy the request\r
+                     * right node - free resources to the right of newly allocated resources */\r
+\r
+                    /* Remove the matching node from the tree for modification. */\r
+                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+\r
+                    /* New left node attributes:\r
+                     * base: base of the matching node\r
+                     * length: base of requested resources - base of matching node */\r
+                    leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base,\r
+                                                      RM_NOT_ALLOCATED_STRING);\r
+                    /* New right node attributes:\r
+                     * base: base of the requested resources + length of requested resources\r
+                     * length: right bound of matching node - right bound of request resources */\r
+                    rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length,\r
+                                                       matchingEnd - findEnd, RM_NOT_ALLOCATED_STRING);\r
+\r
+                    /* Base and length of matching node become the base and length of the\r
+                     * requested resources */\r
+                    matchingNode->base = findNode.base;                                    \r
+                    matchingNode->length = findNode.length;\r
+                    /* Reserve the resources */\r
+                    strcpy(matchingNode->allocatedTo, opInfo->srcInstName);\r
+\r
+                    /* Insert all the nodes */\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+                }\r
+                /* Handle cases where one of findNode range boundaries is equivalent to\r
+                 * one of the matchingNode range boundaries.\r
+                 *\r
+                 * base0                                  base0+length0-1\r
+                 *   |<---------------length0------------------->|  => existing node\r
+                 *   |<---------length1---------->|  => requested resources\r
+                 * base1                   base1+length1-1\r
+                 *\r
+                 * OR\r
+                 *\r
+                 * base0                                  base0+length0-1\r
+                 *   |<---------------length0------------------->|  => existing node\r
+                 *                  |<---------length1---------->|  => requested resources\r
+                 *                base1                   base1+length1-1                 \r
+                 */    \r
+                else\r
+                {     \r
+                    /* Remove the matchingNode from the tree since it will be edited */\r
+                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                    \r
+                    if (findNode.base == matchingNode->base)\r
+                    {\r
+                        /* There may be a combine possibility to the left. Extract leftNode to check */\r
+                        leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                        \r
+                        /* Can the node to the left of the matchingNode be combined with the \r
+                         * findNode's range? */\r
+                        if (leftNode && (strcmp(leftNode->allocatedTo, opInfo->srcInstName) == 0))\r
+                        {\r
+                            /* Remove the leftNode from the tree for editing */\r
+                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+\r
+                            /* Combine the leftNode and the findNode */\r
+                            leftNode->length += findNode.length;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Allocate a new leftNode that will take the place of the findNode\r
+                             * range in tree. */\r
+                            leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
+                                                              opInfo->srcInstName);\r
+                        }\r
+\r
+                        /* Account for the leftNode in the matchingNode */\r
+                        matchingNode->base = findNode.base + findNode.length;\r
+                        matchingNode->length = matchingEnd - findEnd;  \r
+\r
+                        /* Insert the left node */\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                    }\r
+                    else if (findEnd == matchingEnd)\r
+                    {\r
+                        /* There may be a combine possibility to the right. Extract rightNode to check */\r
+                        rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                        \r
+                        /* Can the node to the right of the matchingNode be combined with the \r
+                         * findNode's range? */\r
+                        if (rightNode && (strcmp(rightNode->allocatedTo, opInfo->srcInstName) == 0))\r
+                        {\r
+                            /* Remove the rightNode from the tree for editing */\r
+                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+\r
+                            /* Combine the rightNode and the findNode */\r
+                            rightNode->base = findNode.base;\r
+                            rightNode->length += findNode.length;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Allocate a new rightNode that will take the place of the findNode\r
+                             * range in tree. */\r
+                            rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
+                                                               opInfo->srcInstName);\r
+                        }\r
+\r
+                        /* Account for the rightNode in the matchingNode */\r
+                        matchingNode->length -= findNode.length;  \r
+\r
+                        /* Insert the right node */\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+                    }\r
+\r
+                    /* Reinsert the edited matching node */\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                }\r
+                \r
+                retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+            }\r
+            else\r
+            {\r
+                /* A resource superset containing the requested range has\r
+                 * already been allocated. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* Request ranges that span multiple nodes signify resources are\r
+             * not available because nodes are combined into larger contiguous ranges\r
+             * on resource free operations. */\r
+            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* The requested resources could not be found in the allocator */\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal);        \r
+}\r
+\r
+/* Assume policy has already approved of the free */\r
+int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_ResourceTreeNode findNode;\r
+    Rm_ResourceTreeNode *matchingNode = NULL;\r
+    Rm_ResourceTreeNode *leftNode = NULL;\r
+    Rm_ResourceTreeNode *rightNode = NULL;\r
+    bool combineLeft = FALSE;\r
+    bool combineRight = FALSE;\r
+    uint32_t findEnd, matchingEnd;\r
+    int32_t retVal;\r
+\r
+    /* Find the tree node that contains the specified resource range */\r
+    findNode.base = opInfo->resourceInfo->base;\r
+    findNode.length = opInfo->resourceInfo->length;\r
+    matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
+\r
+    if (matchingNode != NULL)\r
+    {\r
+        findEnd = findNode.base + findNode.length - 1;\r
+        matchingEnd = matchingNode->base + matchingNode->length - 1;\r
+        \r
+        /* Does the free range fit within the matching nodes entire range?  It should\r
+         * either be the entire range or a subset set of the found range. (the latter\r
+         * satisfies the case where an entity allocated a contiguous block of resources\r
+         * then attempts to free a contiguous subset of the allocated block. */\r
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
+        {            \r
+            if (strcmp(matchingNode->allocatedTo, opInfo->srcInstName) == 0)\r
+            {\r
+                /* Resources can be freed */\r
+\r
+                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
+                {\r
+                    /* Case 1: free range equals allocated matched node exactly. Attempt to combine \r
+                     *         the range to be freed with the resource nodes to the left and\r
+                     *         right of the free range.\r
+                     *\r
+                     * |<--left node-->||<---matched node--->||<--right node-->|\r
+                     *                  |<---free request--->|\r
+                     */ \r
+\r
+                    leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                    rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+\r
+                    /* Remove the matching node from the tree and the nodes to the left and\r
+                     * right of the matching node.  Removing from tree will not\r
+                     * wipe any of the base+length data in the node.  Can reuse since they won't\r
+                     * be freed */\r
+                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+\r
+                    /* See if the left or right or both nodes can be combined with the matching\r
+                     * node that will be freed. */\r
+                    if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
+                    {\r
+                        /* Combine the left node and the matching node */\r
+                        RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                        combineLeft = TRUE;\r
+                    }\r
+                    if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
+                    {\r
+                        /* Combine the right node and the matching node */\r
+                        RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+                        combineRight = TRUE;\r
+                    }\r
+\r
+                    /* Perform any combines, insert the leftover nodes, and free any memory associated\r
+                     * with any nodes that weren't reinserted into the tree */\r
+                    if (combineLeft && combineRight)\r
+                    {\r
+                        /* Combine all three nodes into the matchingNode.  Insert the freed cumulative\r
+                         * matching node and delete the memory for the old left and right nodes */\r
+                        matchingNode->base = leftNode->base;\r
+                        matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
+\r
+                        Rm_freeResourceTreeNode(leftNode);\r
+                        Rm_freeResourceTreeNode(rightNode);                        \r
+                    }\r
+                    else if (combineLeft)\r
+                    {\r
+                        /* Combine the left and matching nodes.  Reinsert the right. */\r
+                        matchingNode->base = leftNode->base;\r
+                        matchingNode->length += leftNode->length;\r
+                        \r
+                        Rm_freeResourceTreeNode(leftNode);\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);                        \r
+                    }\r
+                    else if (combineRight)\r
+                    {\r
+                        /* Combine the right and matching nodes.  Reinsert the left. */\r
+                        matchingNode->length += rightNode->length;\r
+                        \r
+                        Rm_freeResourceTreeNode(rightNode);\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                    }\r
+                    else\r
+                    {\r
+                        /* Combine cannot be performed.  Reinsert the left and right nodes then\r
+                         * free the matching node and reinsert it */\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+                    }\r
+\r
+                    /* No matter the combine route taken the matching node will always be declared\r
+                     * free and reinserted */\r
+                    strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);                    \r
+                }\r
+                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
+                {\r
+                    /* Case 2: free range is less than range in matched node. Need to split\r
+                     *         the matched node into three nodes.\r
+                     *\r
+                     * |<----------matched node---------->|\r
+                     *        |<---free request--->|\r
+                     */ \r
+\r
+                    /* Remove matching node for editing. */\r
+                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+\r
+                    /* New left node attributes:\r
+                     * base: base of the matching node\r
+                     * length: base of requested resources - base of matching node */\r
+                    leftNode = Rm_newResourceTreeNode(matchingNode->base, findNode.base - matchingNode->base,\r
+                                                      matchingNode->allocatedTo); \r
+                    /* New right node attributes:\r
+                     * base: base of the requested resources + length of requested resources\r
+                     * length: right bound of matching node - right bound of request resources */\r
+                    rightNode = Rm_newResourceTreeNode(findNode.base + findNode.length,\r
+                                                       matchingEnd - findEnd, matchingNode->allocatedTo);\r
+\r
+                    /* Insert the left and right nodes into the tree. */\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+\r
+                    /* Base and length of matching node become the base and length of the freed resources */\r
+                    matchingNode->base = findNode.base;                                    \r
+                    matchingNode->length = findNode.length;\r
+                    /* Free the resources and insert them into the tree */\r
+                    strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                }\r
+                else\r
+                {\r
+                    /* Remove the matchingNode from the tree since it will be edited */\r
+                    RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                    \r
+                    if (findNode.base == matchingNode->base)\r
+                    {\r
+                        /* Case 3: Free range is on left boundary of matched node. Try to \r
+                         *         combine the free range with the left node if free.\r
+                         *\r
+                         * |<---left node (free)--->||<----------matched node---------->|\r
+                         *                           |<---findNode (free req)--->|\r
+                         */ \r
+                   \r
+                        /* There may be a combine possibility to the left. Extract leftNode to check */\r
+                        leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                        \r
+                        /* Can the node to the left of the matchingNode be combined with the \r
+                         * findNode's range? */\r
+                        if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
+                        {\r
+                            /* Remove the leftNode from the tree for editing */\r
+                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+\r
+                            /* Combine the leftNode and the findNode */\r
+                            leftNode->length += findNode.length;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Allocate a new leftNode that will take the place of the findNode\r
+                             * range in tree. */\r
+                            leftNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
+                                                              RM_NOT_ALLOCATED_STRING);\r
+                        }\r
+\r
+                        /* Account for the leftNode in the matchingNode */\r
+                        matchingNode->base = findNode.base + findNode.length;\r
+                        matchingNode->length = matchingEnd - findEnd;  \r
+\r
+                        /* Insert the left node */\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+                    }\r
+                    else if (findEnd == matchingEnd)\r
+                    {\r
+                        /* Case 4: Free range is on right boundary of matched node. Try to \r
+                         *         combine the free range with the right node if free.\r
+                         *\r
+                         * |<----------matched node---------->||<---right node (free)--->|\r
+                         *        |<---findNode (free req)--->|\r
+                         */ \r
+                        \r
+                        /* There may be a combine possibility to the right. Extract rightNode to check */\r
+                        rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                        \r
+                        /* Can the node to the right of the matchingNode be combined with the \r
+                         * findNode's range? */\r
+                        if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
+                        {\r
+                            /* Remove the rightNode from the tree for editing */\r
+                            RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+\r
+                            /* Combine the rightNode and the findNode */\r
+                            rightNode->base = findNode.base;\r
+                            rightNode->length += findNode.length;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* Allocate a new rightNode that will take the place of the findNode\r
+                             * range in tree. */\r
+                            rightNode = Rm_newResourceTreeNode(findNode.base, findNode.length,\r
+                                                               RM_NOT_ALLOCATED_STRING);\r
+                        }\r
+\r
+                        /* Account for the rightNode in the matchingNode */\r
+                        matchingNode->length -= findNode.length;  \r
+\r
+                        /* Insert the right node */\r
+                        RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+                    }\r
+\r
+                    /* Reinsert the edited matching node */\r
+                    RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+                }\r
+\r
+                retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+            }\r
+            else\r
+            {\r
+                /* The matching allocated range to be freed was allocated to a different instance. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* Free resource range crosses over node boundaries.  This signifies a\r
+             * free of both allocated and unallocated resources since nodes are combined\r
+             * on allocate and free operations if possible. */\r
+            retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* The free resources could not be found in the allocator */\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal);  \r
+}\r
+\r
+int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_Allocator *allocator = NULL;\r
+    int32_t retVal;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's transaction queue */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Get the specified resource's allocator */\r
+    allocator = Rm_allocatorFind(rmInst, opInfo->resourceInfo->name);\r
+\r
+    if (allocator)\r
+    {\r
+        /* Call the allocator's type-based allocation function */\r
+        if(allocator->type == Rm_allocatorType_INTEGER)\r
+        {\r
+            if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
+            {\r
+                retVal = Rm_integerPreAllocate(allocator, opInfo);\r
+            }            \r
+            else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
+            {\r
+                retVal = Rm_integerAllocate(allocator, opInfo);\r
+            }\r
+            else if (opInfo->operation == Rm_allocatorOp_FREE)\r
+            {\r
+                retVal = Rm_integerFree(allocator, opInfo);\r
+            }\r
+        }\r
+        else if (allocator->type == Rm_allocatorType_TREE)\r
+        {\r
+            if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
+            {\r
+                retVal = Rm_treePreAllocate(allocator, opInfo);\r
+            }               \r
+            else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
+            {\r
+                retVal = Rm_treeAllocate(allocator, opInfo);\r
+            }\r
+            else if (opInfo->operation == Rm_allocatorOp_FREE)\r
+            {\r
+                retVal = Rm_treeFree(allocator, opInfo);\r
+            }  \r
+        }        \r
+    }\r
+    else\r
+    {\r
+        /* Allocator could not be found for resource */\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    Rm_osalMtCsExit(key);\r
+    return(retVal);\r
+}\r
+\r
+void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+    {\r
+#if 0        \r
+        if (resourceBase is unspecified)\r
+        {\r
+           while (policy does not approve)\r
+           {\r
+               Rm_policy check get allowed base as starting point for prealloc\r
+               preallocate resource based on the range and alignment\r
+               Rm_policy...check\r
+           }\r
+        }\r
+        else\r
+        {\r
+            /* Check local policy to see if the request can be satisfied with the\r
+             * resources stored locally */\r
+            Rm_policy...API()\r
+\r
+            if (policy check approves the resource)\r
+            {\r
+                /* call the allocator to allocate the resource */\r
+                if (allocator returns resource)\r
+                {\r
+                    /* Populate the transaction with the allocated resources and the result */\r
+                    transaction->state = approve reason;\r
+                    return ...\r
+                }\r
+                else\r
+                {\r
+                    /* allocator ran out of resources, need to contact Server for more\r
+                     * resources */\r
+                    Rm_resourcePoolModRequest(...);\r
+                }\r
+            }\r
+            else if (policy check denies resource)\r
+            {\r
+                /* Policy check denied resource. */\r
+                transaction->state= deny reason;\r
+                return ...\r
+            }\r
+            else if (policy check says forward to Server for validation)\r
+            {\r
+                /* Forward the transaction to the Server */\r
+                Rm_transactionForwarder(rmInst, transaction);\r
+            }\r
+        }\r
+#endif         \r
+    }\r
+    else if (rmInst->instType == Rm_instType_SERVER)\r
+    {\r
+#if 0       \r
+        if (resourceBase is unspecified)\r
+        {\r
+           while (policy does not approve)\r
+           {\r
+               Rm_policy check get allowed base as starting point for prealloc\r
+               preallocate resource based on the range and alignment\r
+               Rm_policy...check\r
+           }\r
+        }\r
+        else\r
+        {\r
+            /* Check global policy to see if resource can be allocated. return result\r
+             * no matter what */\r
+            Rm_policy...API()\r
+\r
+            if (policy approves)\r
+            {\r
+                /* call allocator to allocate resource */\r
+            }\r
+\r
+            transaction->state = approve or deny reason;\r
+            transaction->resourceInfo.base = ...;\r
+            transaction->resourceInfo.length = ...;\r
+\r
+            /* If source instance name does not match the current instance\r
+             * name the allocation request came from a Client.  The result\r
+             * must be sent back to the Client */\r
+            if (strcmp(transaction->sourceInstName, rmInst->name))\r
+            {\r
+                /* Names don't match.  Send the transaction back to the Client */\r
+                Rm_transactionResponder(rmInst, transaction);\r
+            }\r
+            else\r
+            {\r
+                /* Resource allocation request originated locally on the active\r
+                 * instance. Send the response via the service responder. */          \r
+                Rm_serviceResponder(rmInst, transaction);                            \r
+            }\r
+        }\r
+#endif        \r
+    }   \r
+}\r
+\r
+void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+    {\r
+#if 0        \r
+        /* Check local policy to see if the request can be satisfied with the\r
+         * resources stored locally */\r
+        Rm_policy...API()\r
+\r
+        if (policy check approves the free)\r
+        {\r
+            /* call the allocator to free the resource */\r
+            /* Run a resource pool check to see if the free combined a resource block\r
+             * that can be returned to the server */\r
+            if (resource block has been combined)\r
+            {\r
+                  /* allocator ran out of resources, need to contact Server for more\r
+                 * resources */\r
+                Rm_resourcePoolModRequest(free pool block to server...);\r
+            }\r
+            else\r
+            {\r
+                /* Populate the receipt with the freed resources and the result */\r
+                transaction->state = approve reason;\r
+                return ...\r
+            }\r
+        }\r
+        else if (policy check denies resource free)\r
+        {\r
+            /* Policy check denied resource. */\r
+            transaction->state = deny reason;\r
+            return ...\r
+        }\r
+        else if (policy check says forward to Server for validation)\r
+        {\r
+            /* Forward the transaction to the Server */\r
+            Rm_transactionForwarder(rmInst, transaction);\r
+        }\r
+#endif         \r
+    }\r
+    else if (rmInst->instType == Rm_instType_SERVER)\r
+    {\r
+#if 0        \r
+        /* Check global policy to see if resource can be freed. return result\r
+         * no matter what */\r
+        Rm_policy...API()\r
+        if (policy approves)\r
+        {\r
+            /* call allocator to free resources */\r
+        }\r
+            \r
+        transaction->state = approve or deny reason;\r
+        transaction->resourceInfo.base = ...;\r
+        transaction->resourceInfo.length = ...;\r
+\r
+        /* If source instance name does not match the current instance\r
+         * name the allocation request came from a client.  The result\r
+         * must be sent back to the Client */\r
+        if (strcmp(transaction->sourceInstName, rmInst->name))\r
+        {\r
+            /* Names don't match.  Send the transaction back to the Client Delegate or Client */\r
+            Rm_transactionResponder(rmInst, transaction);\r
+        }\r
+        else\r
+        {\r
+            /* Resource allocation request originated locally on the active\r
+             * instance. Send the response via the service responder. */\r
+            Rm_serviceResponder(rmInst, transaction);                            \r
+        }\r
+#endif        \r
+    }   \r
+}\r
+\r
+/* Function used to forward RM transactions to higher level agents */\r
+void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    Rm_TransportNode *dstTransportNode = NULL;\r
+    Rm_Packet *rmPkt = NULL;\r
+\r
+    /* Make sure the RM instance has a transport registered with a higher level agent */\r
+    if (rmInst->registeredWithDelegateOrServer == false)\r
+    {\r
+        transaction->state = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
+        return;\r
+    }\r
+\r
+    /* Find the transport for the higher level agent.  Check for a connection to a Client Delegate\r
+     * or a Server.  Clients will be connected to either a Client Delegate or a Server.  Client\r
+     * Delegates will be connected to a Server. */\r
+    if (rmInst->instType == Rm_instType_CLIENT)\r
+    {\r
+        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
+    } \r
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+    {\r
+        dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
+    }\r
+\r
+    /* Create a RM packet using the service information */\r
+    switch (transaction->type)\r
+    {\r
+        case Rm_service_RESOURCE_ALLOCATE:\r
+        case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+        case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+        case Rm_service_RESOURCE_FREE:\r
+        case Rm_service_RESOURCE_BLOCK_FREE:\r
+        case Rm_service_RESOURCE_FREE_BY_NAME:\r
+            rmPkt = Rm_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
+                                                     transaction);\r
+            break;\r
+        case Rm_service_RESOURCE_MAP_TO_NAME:\r
+        case Rm_service_RESOURCE_UNMAP_NAME:\r
+            rmPkt = Rm_transportCreateNsRequestPkt(rmInst, dstTransportNode,\r
+                                                   transaction);\r
+            break;\r
+        default:\r
+            /* Invalid service type.  Flag the error and return */\r
+            transaction->state = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;\r
+            break;\r
+    }\r
+\r
+    if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
+    {\r
+        /* Return immediately because an error occurred allocating the packet */\r
+        return;\r
+    }\r
+\r
+    /* Send the RM packet to the application transport */\r
+    if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
+    {\r
+        /* Negative value returned by transport send.  An error occurred\r
+         * in the transport while attempting to send the packet.*/\r
+        transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
+        /* Clean up the packet */\r
+        if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
+        {\r
+            /* Non-NULL value returned by transport packet free. Flag the\r
+             * error */\r
+            transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
+        }\r
+        return;\r
+    }\r
+\r
+    /* Transaction is not deleted because it is awaiting a response from the higher level\r
+     * RM instance */\r
+}\r
+\r
+void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    /* Handle auto-forwarded transactions.  These transactions include:\r
+     * - All request transactions received on Clients are forwarded to the Client Delegate\r
+     * - NameServer requests received on the Client Delegate are forwarded to the Server */\r
+    if ((rmInst->instType == Rm_instType_CLIENT) ||\r
+        ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
+         (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||\r
+         (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))\r
+    {\r
+        /* Check if the transaction is a transaction that received a response to its\r
+         * request. */\r
+        if (transaction->state != RM_SERVICE_PROCESSING)\r
+        {\r
+\r
+            /* A transaction has received a response. Send the response to either the \r
+             * transaction or service responder based on the source instance */\r
+            if (strcmp(transaction->sourceInstName, rmInst->name))\r
+            {\r
+                /* Transaction originated from another instance.  Use the \r
+                 * transaction responder to send the result to the source instance.  This\r
+                 * is not possible on RM Clients since they can't forward RM services */\r
+                Rm_transactionResponder(rmInst, transaction);\r
+            }\r
+            else\r
+            {\r
+                /* Transaction originated on this instance.  Send to the\r
+                 * service responder */\r
+                Rm_serviceResponder(rmInst, transaction);\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* This is a new transaction that must be forwarded to a higher level RM instance. */\r
+            Rm_transactionForwarder(rmInst, transaction);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        /* Client Delegate and Server transaction processors. */\r
+        switch (transaction->type)\r
+        {\r
+            case Rm_service_RESOURCE_ALLOCATE:\r
+            case Rm_service_RESOURCE_BLOCK_ALLOCATE:\r
+            case Rm_service_RESOURCE_ALLOCATE_BY_NAME:\r
+            case Rm_service_RESOURCE_FREE:\r
+            case Rm_service_RESOURCE_BLOCK_FREE:\r
+            case Rm_service_RESOURCE_FREE_BY_NAME:                \r
+                /* Check if the transaction is fulfilled request */\r
+                if (transaction->state != RM_SERVICE_PROCESSING)\r
+                {\r
+                    /* If source instance name does not match the current instance\r
+                     * name the allocation request came from a client.  The result\r
+                     * must be sent back to the Client */\r
+                    if (strcmp(transaction->sourceInstName, rmInst->name))\r
+                    {\r
+                        Rm_transactionResponder(rmInst, transaction);\r
+                    }\r
+                    else\r
+                    {\r
+                        /* Resource allocation request originated locally.  Send the response\r
+                         * via the service responder. */\r
+                        Rm_serviceResponder(rmInst, transaction);      \r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    /* This is a new transaction request originating from an RM instance with fewer\r
+                     * allocate/free privileges.  Run the allocation or free handler to see if the resource\r
+                     * request can be handled locally or if it needs to be forwarded to a higher level\r
+                     * agent */\r
+                    if ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||\r
+                        (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||\r
+                        (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME))\r
+                    {\r
+                        Rm_allocationHandler(rmInst, transaction);\r
+                    }\r
+                    else\r
+                    {\r
+                        Rm_freeHandler(rmInst, transaction);\r
+                    }\r
+                }\r
+                break;\r
+            case Rm_service_RESOURCE_MAP_TO_NAME:\r
+            case Rm_service_RESOURCE_UNMAP_NAME:                \r
+                /* Server is the only RM instance capable of adding NameServer objects */\r
+                if (rmInst->instType == Rm_instType_SERVER)\r
+                {\r
+                    if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME)\r
+                    {\r
+                        /* Create a new NameServer object with the request transaction information.\r
+                         * Transaction will contain the state result of the NameServer addition. */\r
+                        if (Rm_nsAddObject(rmInst, transaction->resourceInfo.nsName,\r
+                                           transaction->resourceInfo.base) == RM_NS_ACTION_APPROVED)\r
+                        {\r
+                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* TEMP: UPDATE THIS STATE VALUE */\r
+                            transaction->state = RM_SERVICE_DENIED_BEGIN;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        /* Delete an existing NameServer object with the request transaction information\r
+                         * Transaction will contain the state result of the NameServer addition. */\r
+                        if (Rm_nsDeleteObject(rmInst, transaction->resourceInfo.nsName) == \r
+                            RM_NS_ACTION_APPROVED)\r
+                        {\r
+                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+                        }\r
+                        else\r
+                        {\r
+                            /* TEMP: UPDATE THIS STATE VALUE */\r
+                            transaction->state = RM_SERVICE_DENIED_BEGIN;\r
+                        }\r
+                    }\r
+\r
+                    /* If source instance name does not match the local instance\r
+                     * name the NameServer request came from a Client or Client Delegate.  The \r
+                     * result must be sent back to the Client or Client Delegate.  Just return if it does\r
+                     * match since the NameServer transaction result can be returned immediately by the\r
+                     * Rm_serviceHandler. */\r
+                    if (strcmp(transaction->sourceInstName, rmInst->name))\r
+                    {\r
+                        Rm_transactionResponder(rmInst, transaction);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    transaction->state = RM_SERVICE_ERROR_NAMESERVER_OBJECT_MOD_ON_INVALID_INSTANCE;\r
+                }\r
+                break;\r
+        }\r
+    }\r
+}\r
+\r
+int32_t Rm_reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, \r
+                                Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+    bool baseFound = FALSE;\r
+    bool lengthFound = FALSE;\r
+    uint32_t valueIndex = 0;\r
+\r
+    while ((linuxValues != NULL) && (!baseFound || !lengthFound))\r
+    {\r
+        if (linuxAlias->baseOffset == valueIndex)\r
+        {\r
+            /* Found the resource base.  Store it in the operation info structure */\r
+            opInfo->resourceInfo->base = linuxValues->value;\r
+            baseFound = TRUE;\r
+\r
+            /* length will always be 1 if there is no length specified in the Linux DTB */\r
+            if (linuxAlias->lengthOffset == RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET)\r
+            {\r
+                opInfo->resourceInfo->length = 1;\r
+                lengthFound = TRUE;\r
+            }\r
+        }\r
+        else if (linuxAlias->lengthOffset == valueIndex)\r
+        {\r
+            /* Found the resource length.  Store it in the operation info structure */\r
+            opInfo->resourceInfo->length = linuxValues->value;\r
+            lengthFound = TRUE;\r
+        }\r
+\r
+        linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;\r
+        valueIndex++;\r
+    }\r
+\r
+    if (!baseFound || !lengthFound)\r
+    {\r
+        retVal = -33; /* TODO: ERROR BASE OR LENGTH OFFSET IN LINUX DTB WAS INCORRECT */\r
+    }\r
+    else\r
+    {\r
+        /* Allocate the resource to Linux */\r
+        retVal = Rm_allocatorOperation(rmInst, opInfo);\r
+    }\r
+\r
+    return (retVal);\r
+}\r
+\r
+int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName, void *linuxDtb, \r
+                                       Rm_LinuxAlias *linuxAlias)\r
+{\r
+    Rm_AllocatorOpInfo opInfo;\r
+    Rm_ResourceInfo resourceInfo;\r
+    uint32_t pathOffset;\r
+    int32_t propOffset;\r
+    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+    int32_t prevDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
+    int32_t depth;\r
+    int32_t propertyLen;\r
+    const char *propertyName;\r
+    const void *propertyData; \r
+    Rm_LinuxValueRange *linuxValueRange;\r
+    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY; \r
+\r
+    /* Initialize the allocator opInfo and resourceInfo structures that will be used to \r
+     * reserve the resources taken by the Linux kernel */\r
+    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
+    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
+\r
+    strcpy(resourceInfo.name, resourceName);\r
+\r
+    /* Set the source instance name for allocation to be the Linux Kernel */\r
+    opInfo.srcInstName = RM_ALLOCATED_TO_LINUX;\r
+    opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
+    opInfo.resourceInfo = &resourceInfo;    \r
+\r
+    /* Find each resource specified in the Linux resource alias list and reserve that \r
+     * resource as used */\r
+    while(linuxAlias != NULL)\r
+    {\r
+        /* Reset the parsing variables */\r
+        pathOffset = 0;\r
+        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+        prevDepth = RM_DTB_UTIL_STARTING_DEPTH;   \r
+        resourceInfo.base = 0;\r
+        resourceInfo.length = 0;\r
+        \r
+        while(pathOffset < linuxAlias->pathListLenBytes)\r
+        {\r
+            /* Move through the DTB nodes until the next alias path node is found */\r
+            if (strcmp(linuxAlias->pathList + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL)))\r
+            {\r
+                nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);\r
+\r
+                if (depth < prevDepth)\r
+                {\r
+                    /* Returning from subnode that matched part of alias path without finding\r
+                     * the resource values */\r
+                    retVal = (-31); /* TODO: COULD NOT FIND RESOURCE AT ALIAS PATH */\r
+                    break;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                /* Found the next alias path node */\r
+                pathOffset += (strlen(linuxAlias->pathList + pathOffset) + 1);\r
+                prevDepth = fdt_node_depth(linuxDtb, nodeOffset);\r
+\r
+                /* Check the properties of the node to see if they match the next alias\r
+                 * path string */\r
+               propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);\r
+           \r
+                /* Search the properties for the next alias path string */\r
+                while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&\r
+                       (pathOffset < linuxAlias->pathListLenBytes))\r
+                {\r
+                    propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, \r
+                                                         &propertyName, &propertyLen);\r
+\r
+                    if (strcmp(linuxAlias->pathList + pathOffset, propertyName) == 0)\r
+                    {\r
+                        pathOffset += (strlen(linuxAlias->pathList + pathOffset) + 1);\r
+                        /* Found the alias property.  Extract the values that will\r
+                         * contain the resource information that must be reserved. */\r
+                        linuxValueRange = Rm_linuxExtractValues(propertyData, propertyLen);\r
+                        /* Use the values to reserve resources for the Linux kernel */\r
+                        retVal = Rm_reserveLinuxResource(rmInst, linuxAlias, \r
+                                                         linuxValueRange, &opInfo);\r
+                        \r
+                        /* Free the memory used to store the values */\r
+                        Rm_linuxFreeValues(linuxValueRange);\r
+                    }\r
+                    \r
+                    propOffset = fdt_next_property_offset(linuxDtb, propOffset);\r
+                } \r
+\r
+                if (propOffset < -FDT_ERR_NOTFOUND)\r
+                {\r
+                       /* Error was returned by LIBFDT when parsing the properties */\r
+                    retVal = propOffset;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+\r
+        if (retVal < RM_DTB_UTIL_RESULT_OKAY)\r
+        {\r
+            /* Error occurred during parsing of Linux DTB.  Return the error */\r
+            break;\r
+        }\r
+        linuxAlias = (Rm_LinuxAlias *) linuxAlias->nextLinuxAlias;\r
+    }\r
+\r
+    return (retVal);\r
+}\r
+\r
+int32_t Rm_createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, \r
+                                  Rm_ResourceProperties *resourceProperties, void *linuxDtb)\r
+{\r
+    char *allocatorType = NULL;\r
+    Rm_ResourceRange *range = NULL;\r
+    Rm_ResourceRange *rangeBasePtr = NULL;\r
+    Rm_NsAssignment *nsAssignments = NULL;\r
+    Rm_NsAssignment *nsAssignmentBasePtr = NULL;\r
+    Rm_LinuxAlias *linuxAlias = NULL;\r
+    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+    /* TODO: NEED CHECKS FOR VALIDITY OF ALL THE resourceProperties FIELDS */\r
+\r
+    /* Extract the resource properties from the DTB */\r
+    allocatorType = Rm_resourceExtractAllocator(resourceProperties->allocatorData, \r
+                                                resourceProperties->allocatorLen);\r
+    range = rangeBasePtr = Rm_resourceExtractRange(resourceProperties->rangeData, \r
+                                                   resourceProperties->rangeLen);\r
+\r
+    /* Create an allocator based on the allocator type specified */\r
+    if (strcmp(allocatorType, &rmIntegerAllocator[0]) == 0)\r
+    {\r
+        /* Create an integer allocator using the resource properties */\r
+        retVal = Rm_createIntegerAllocator(rmInst, resourceName, range);        \r
+    }\r
+    else if (strcmp(allocatorType, &rmTreeAllocator[0]) == 0)\r
+    {\r
+        /* Create a tree allocator using the resource properties */\r
+        retVal = Rm_createTreeAllocator(rmInst, resourceName, range); \r
+    }\r
+    else\r
+    {\r
+        /* Allocator type not recognized.  Free the resource properties and return */\r
+        retVal = -21; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+    }\r
+\r
+    if (retVal >= RM_DTB_UTIL_RESULT_OKAY)\r
+    {\r
+        if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen)\r
+        {\r
+            /* Reserve the resources taken by the Linux kernel specified in the Linux DTB */\r
+            linuxAlias = Rm_resourceExtractLinuxAlias(resourceProperties->linuxAliasData,\r
+                                                      resourceProperties->linuxAliasLen);\r
+\r
+            retVal = Rm_findAndReserveLinuxResource(rmInst, resourceName, linuxDtb, linuxAlias);            \r
+        }\r
+    }\r
+    \r
+    if (retVal >= RM_DTB_UTIL_RESULT_OKAY)\r
+    {\r
+        /* Create entries in the NameServer if any NameServer assignments were specified */\r
+        if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen)\r
+        {\r
+            nsAssignments = Rm_resourceExtractNsAssignment(resourceProperties->nsAssignData, \r
+                                                           resourceProperties->nsAssignLen);\r
+\r
+            /* Cycle through the list of assignments and add them to the NameServer */\r
+            nsAssignmentBasePtr = nsAssignments;\r
+            while (nsAssignments)\r
+            {\r
+                /* TODO: RETURN IF ANY OF THE ADDS FAIL??? */\r
+                Rm_nsAddObject(rmInst, nsAssignments->nsName, nsAssignments->resourceValue);\r
+                nsAssignments = nsAssignments->nextNsAssignment;\r
+            }\r
+            /* Free the memory allocated for the NameServer assignments */\r
+            Rm_resourceFreeNsAssignmentList(nsAssignmentBasePtr);\r
+        }\r
+    }\r
+\r
+    /* Free the memory allocated for the resource properties */\r
+    Rm_resourceFreeAllocator(allocatorType);\r
+    Rm_resourceFreeRange(rangeBasePtr);\r
+    Rm_resourceFreeLinuxAlias(linuxAlias);\r
+\r
+    return(retVal);\r
+}\r
+\r
+int32_t Rm_parseResourceProperty(void *globalResourceDtb, int32_t offset, Rm_ResourceProperties *propertyInfo)\r
+{\r
+       int32_t propertyLen;\r
+       const char *propertyName;\r
+       const void *propertyData;\r
+    Rm_ResourcePropType propertyType;\r
+    int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+    /* Get the property data and store it in the corresponding propertyInfo field */\r
+       propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);\r
+    if (propertyData)\r
+    {\r
+        propertyType = Rm_resourceGetPropertyType(propertyName);\r
+        if (propertyType == Rm_resourcePropType_RESOURCE_ALLOCATOR)\r
+        {\r
+            if (propertyInfo->allocatorData || propertyInfo->allocatorLen)\r
+            {\r
+                /* The allocator fields have already been populated.  Return an error.\r
+                 * The resource list has specified a property field more than once\r
+                 * for a resource node */\r
+                retVal = -17; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+            }\r
+            else\r
+            {\r
+                propertyInfo->allocatorData = propertyData;\r
+                propertyInfo->allocatorLen = propertyLen;\r
+            }\r
+        }\r
+        else if (propertyType == Rm_resourcePropType_RESOURCE_RANGE)\r
+        {\r
+            if (propertyInfo->rangeData || propertyInfo->rangeLen)\r
+            {\r
+                /* The range fields have already been populated.  Return an error.\r
+                 * The resource list has specified a property field more than once\r
+                 * for a resource node */\r
+                retVal = -18; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+            }\r
+            else\r
+            {\r
+                propertyInfo->rangeData = propertyData;\r
+                propertyInfo->rangeLen = propertyLen;\r
+            }\r
+        }\r
+        else if (propertyType == Rm_resourcePropType_NSASSIGNMENT)\r
+        {\r
+            if (propertyInfo->nsAssignData || propertyInfo->nsAssignLen)\r
+            {\r
+                /* The nsAssign fields have already been populated.  Return an error.\r
+                 * The resource list has specified a property field more than once\r
+                 * for a resource node */\r
+                retVal = -19; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+            }\r
+            else\r
+            {\r
+                propertyInfo->nsAssignData = propertyData;\r
+                propertyInfo->nsAssignLen = propertyLen;\r
+            }\r
+        }\r
+        else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS)\r
+        {\r
+            if (propertyInfo->linuxAliasData || propertyInfo->linuxAliasLen)\r
+            {\r
+                /* The linuxAlias fields have already been populated.  Return an error.\r
+                 * The resource list has specified a property field more than once\r
+                 * for a resource node */\r
+                retVal = -28; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+            }\r
+            else\r
+            {\r
+                propertyInfo->linuxAliasData = propertyData;\r
+                propertyInfo->linuxAliasLen = propertyLen;\r
+            }\r
+        }        \r
+        else\r
+        {\r
+            retVal = -20; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = -16; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+    }\r
+\r
+    /* Don't get anymore properties if error occurred */\r
+    if (retVal == RM_DTB_UTIL_RESULT_OKAY)\r
+    {\r
+        offset = fdt_next_property_offset(globalResourceDtb, offset);\r
+       if (offset >= 0)\r
+       {\r
+           retVal = Rm_parseResourceProperty(globalResourceDtb, offset, propertyInfo);\r
+       }\r
+        else if (offset != -FDT_ERR_NOTFOUND)\r
+        {\r
+            /* Error was returned by LIBFDT when parsing the properties */\r
+            retVal = offset;\r
+        }\r
+    }\r
+    \r
+    return (retVal);\r
+}\r
+\r
+int32_t Rm_parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t nodeOffset, int32_t depth,\r
+                             void *linuxDtb)\r
+{\r
+       const char *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);\r
+    Rm_ResourceProperties resourceProperties;\r
+       int32_t error = RM_DTB_UTIL_RESULT_OKAY;\r
+       int32_t offset;\r
+\r
+    /* Initialize the resource properties structure */\r
+    memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));\r
+\r
+    /* Ignore properties of the base node */\r
+    if (strcmp(resourceName, rmDtbStartingNode))\r
+    {\r
+        /* Get the properties for the resource node if any exist */\r
+       offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);\r
+       if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET)\r
+       {\r
+            /* Since at least one property exists attempt to parse the property nodes and \r
+             * use them to create and initialize a resource allocator */\r
+               error =  Rm_parseResourceProperty(globalResourceDtb, offset, &resourceProperties);\r
+            if (error < -FDT_ERR_NOTFOUND)\r
+            {\r
+                return (error);\r
+            }\r
+            \r
+            /* Initialize an allocator with the resource properties if no error was returned */\r
+            Rm_createAndInitAllocator(rmInst, resourceName, &resourceProperties, linuxDtb);\r
+       }\r
+        else if (offset != -FDT_ERR_NOTFOUND)\r
+        {\r
+               /* Error was returned by LIBFDT when parsing the properties */\r
+            return (offset);\r
+        }\r
+    }\r
+    \r
+    /* Get the next resource node */\r
+       offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);\r
+    /* Check the offset and depth of the next node to make sure the current node\r
+     * wasn't the last node in the Resource List.  A depth less than the depth set\r
+     * at the start of the recursion will signal the end of the resource list */\r
+    if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH))\r
+    {\r
+        error = Rm_parseResourceNode(rmInst, globalResourceDtb, offset, depth, linuxDtb);\r
+        if (error < -FDT_ERR_NOTFOUND)\r
+        {\r
+            return (error);\r
+        }\r
+    }\r
+    else if (offset != -FDT_ERR_NOTFOUND)\r
+    {\r
+        /* Error was returned by LIBFDT when parsing the nodes */\r
+        return (offset);\r
+    }\r
+\r
+    return (RM_DTB_UTIL_RESULT_OKAY);\r
+}\r
+\r
+int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *linuxDtb)\r
+{\r
+    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
+    int32_t result = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+    /* Recursively parse the Global Resource List, creating an allocator for\r
+     * each resource as specified in the node */\r
+    result = Rm_parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth, linuxDtb);\r
+\r
+    return(result);\r
+}\r
+\r
+void Rm_printResourceStatus(Rm_Inst *rmInst)\r
+{\r
+    Rm_Allocator *allocator = rmInst->allocators;\r
+    Rm_IntegerAllocatorRootEntry *integerRoot;\r
+    Rm_IntegerEntry *integerEntry;\r
+    Rm_ResourceTree *treeRoot;\r
+    Rm_ResourceTreeNode *treeNode;\r
+    uint32_t numLinuxResources;\r
+    uint32_t i;\r
+\r
+    while (allocator != NULL)\r
+    {\r
+        numLinuxResources = 0;\r
+\r
+        Rm_osalLog("Resource: %s\n", allocator->resourceName);\r
+\r
+        if (allocator->type == Rm_allocatorType_INTEGER)\r
+        {\r
+            integerRoot = allocator->allocatorRootEntry;\r
+            integerEntry = integerRoot->resourceArrayBase;\r
+\r
+            for (i = 0; i < integerRoot->numResourceElements; i++)\r
+            {\r
+                if (strcmp(integerEntry[i].allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
+                {\r
+                    Rm_osalLog("Value: %5d reserved for %s\n", integerEntry[i].value, \r
+                                                               integerEntry[i].allocatedTo);\r
+                    numLinuxResources++;\r
+                }\r
+            }\r
+        }\r
+        else if (allocator->type == Rm_allocatorType_TREE)\r
+        {\r
+            treeRoot = allocator->allocatorRootEntry;\r
+\r
+            RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot)\r
+            {               \r
+                Rm_osalLog("          %5d - %5d ", treeNode->base, \r
+                                                   treeNode->base + treeNode->length -1);\r
+                \r
+                if (strcmp(treeNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
+                {\r
+                    Rm_osalLog("NOT ALLOCATED\n");\r
+                }\r
+                else\r
+                {\r
+                    Rm_osalLog("allocated to %s\n", treeNode->allocatedTo);\r
+                }\r
+\r
+                if (strcmp(treeNode->allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
+                {\r
+                    numLinuxResources += treeNode->length;\r
+                }\r
+            }\r
+        }\r
+        else\r
+        {\r
+            Rm_osalLog("Error: Unknown allocator type\n");\r
+        }\r
+        \r
+        Rm_osalLog("Total allocated to Linux: %d\n", numLinuxResources);\r
+        \r
+        allocator = allocator->nextAllocator;\r
+    }\r
+}\r
+     \r
+/**********************************************************************\r
+ ********************** Application visible APIs **********************\r
+ **********************************************************************/\r
+\r
+Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
+{\r
+    Rm_Inst *rmInst;\r
+    void *globalResourceDtb = NULL;\r
+    void *linuxResourceDtb = NULL;\r
+\r
+    /* Instance creation checks.  Add one to strlen calculation for null character */\r
+    if ((strlen(initCfg->instName) + 1) > RM_INSTANCE_NAME_MAX_CHARS)\r
+    {\r
+        /* Failure: Instance name is too big */\r
+        return (NULL);\r
+    }\r
+    \r
+    /* Get memory for RM instance from local memory */\r
+    rmInst = Rm_osalMalloc (sizeof(Rm_Inst));\r
+    /* Populate instance based on input parameters */\r
+    strcpy (&rmInst->name[0], initCfg->instName);\r
+    rmInst->instType = initCfg->instType;\r
+    rmInst->registeredWithDelegateOrServer = false;\r
+    rmInst->policyDtb = NULL;\r
+\r
+    /* Initialize the transport routing map linked list pointer to NULL.  The linked list\r
+     * nodes will be created when the application registers transports */\r
+    rmInst->routeMap = NULL;\r
+\r
+    /* Initialize the allocators linked list pointer to NULL.  The linked list nodes will\r
+     * be created on the Server instance when the application reads in the resource list.\r
+     * Nodes will also be created on Client Delegates when blocks of resources are requested\r
+     * for allocation to clients. */\r
+    rmInst->allocators = NULL;\r
+\r
+    /* Initialize the transaction queue elements. */\r
+    rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
+    rmInst->transactionQueue= NULL;\r
+\r
+    /* RM Server specific actions */\r
+    if (rmInst->instType == Rm_instType_SERVER)\r
+    {\r
+        /* Open the ResourceList file and provide it to the resource initializer.  The Linux\r
+         * DTB will be parsed simultaneously for resource's consumed by the kernel.  The resources\r
+         * used by the kernel will be marked as used in the resource allocators. */\r
+        if (initCfg->globalResourceList)\r
+        {\r
+            globalResourceDtb = initCfg->globalResourceList;\r
+            fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));\r
+\r
+            if (initCfg->linuxDtb)\r
+            {\r
+                linuxResourceDtb = initCfg->linuxDtb;\r
+                fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));   \r
+            }\r
+            \r
+            Rm_initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb);\r
+\r
+            Rm_printResourceStatus(rmInst);\r
+        }\r
+    }\r
+\r
+    /* Instance startup policies are only used for Servers and Client Delegates */\r
+    if (rmInst->instType != Rm_instType_CLIENT)\r
+    {\r
+        /* Open the instance's policy and store it */\r
+        if (initCfg->startupPolicy)\r
+        {\r
+            rmInst->policyDtb = initCfg->startupPolicy;\r
+            fdt_open_into(rmInst->policyDtb, rmInst->policyDtb, fdt_totalsize(rmInst->policyDtb));  \r
+        }\r
+\r
+        /* Store policy via policy APIs ... */\r
+    }\r
+\r
+    /* Return the RM Handle */\r
+    return ((Rm_Handle) rmInst);\r
+}\r
+\r
+uint32_t Rm_getVersion (void)\r
+{\r
+    return RM_VERSION_ID;\r
+}\r
+\r
+\r
+const char* Rm_getVersionStr (void)\r
+{\r
+    return rmVersionStr;\r
+}\r
+\r
+/**\r
+@}\r
+*/\r