Rewriting policy definition feature
authorJustin Sobota <jsobota@ti.com>
Sat, 12 Jan 2013 00:23:48 +0000 (19:23 -0500)
committerJustin Sobota <jsobota@ti.com>
Sat, 12 Jan 2013 00:23:48 +0000 (19:23 -0500)
15 files changed:
device/global-policy.dtb [deleted file]
device/tci6614-global-resources-mixed.dts [deleted file]
device/tci6614-server-policy.dtb
device/tci6614-server-policy.dts
include/rm_dtb_utilloc.h
include/rm_loc.h
include/rm_nameserverloc.h
include/rm_policyloc.h
rm.h
rm_services.h
rm_types.h
src/rm.c
src/rm_dtb_util.c
src/rm_nameserver.c
src/rm_policy.c

diff --git a/device/global-policy.dtb b/device/global-policy.dtb
deleted file mode 100644 (file)
index 2d18b06..0000000
Binary files a/device/global-policy.dtb and /dev/null differ
diff --git a/device/tci6614-global-resources-mixed.dts b/device/tci6614-global-resources-mixed.dts
deleted file mode 100644 (file)
index d0df6f1..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/dts-v1/;
-
-/ {
-    device-name = "TCI6614";
-    
-    /* Device Resource Definitions */
-
-       /* TODO: where do following get defined in the linux DTB
-                        #define ARM_LINUX_CPPI_QMSS_TX_CH_NUM           12
-                        #define ARM_LINUX_CPPI_QMSS_RX_CH_NUM           12
-                        #define ARM_LINUX_CPPI_QMSS_FLOW                12
-       */
-       
-    qmss {
-        pdsps {
-               allocator = "integer";
-               resource-range = <0 2>;
-        };
-        memory-regions {
-                       allocator = "integer";
-                       resource-range = <0 20>;
-                       linux-dtb-alias = "hwqueue@2a00000", "regions", "region-12", "id", "end", <0>, "end";
-        };
-        link-ram {
-            allocator = "tree";
-            resource-range = <0x00000000 0xFFFFFFFF>;
-        };
-        accumulator-ch {
-            allocator = "integer";
-            resource-range = <0 48>;
-               /* Each new line specifies a different path.  The last string in the line
-                * must result in a property tied to a value */
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "accumulator", "end", <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-1", "accumulator", "end", <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-2", "accumulator", "end", <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-3", "accumulator", "end", <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-high", "accumulator", "end", <1>, "end";            
-        };
-        qos-cluster {
-                       allocator = "integer";
-                       resource-range = <0 8>;
-        };
-        qos-queue {
-                       allocator = "integer";
-                       resource-range = <0 64>;
-        };        
-
-        /* Queue definitions based on csl_qm_queue.h */
-        low-prio-queue {
-               allocator = "tree";
-               resource-range = <0 512>;
-               /* Each new line specifies a different path. */
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-low-0", "values", "end", <0>, <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-1", "values", "end", <0>, <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-2", "values", "end", <0>, <1>, "end",
-                                                 "hwqueue@2a00000", "queues", "accumulator-low-3", "values", "end", <0>, <1>, "end";
-        };
-        aif-queue {
-               allocator = "tree";
-               resource-range = <512 128>;
-        };
-        pass-queue {
-               allocator = "integer";
-               resource-range = <640 9>;
-        };     
-        intc-queue {
-               allocator = "integer";
-               resource-range = <662 10>;
-        };
-        srio-queue {
-               allocator = "integer";
-               resource-range = <672 16>;
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "riotx", "values", "end", <0>, <1>, "end";
-        }; 
-        fftc-a-queue {
-               allocator = "integer";
-               resource-range = <688 4>;
-        };
-        fftc-b-queue {
-               allocator = "integer";
-               resource-range = <692 4>;
-        };
-        bcp-queue {
-               allocator = "integer";
-               resource-range = <864 8>;
-        };
-        high-prio-queue {
-               allocator = "integer";
-               resource-range = <704 32>;
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "accumulator-high", "values", "end", <0>, <1>, "end";
-        };
-        starvation-queue {
-               allocator = "tree";
-               resource-range = <736 64>;
-        };
-        infra-queue {
-               allocator = "integer";
-               resource-range = <800 32>;
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "infradma", "values", "end", <0>, <1>, "end";
-        };
-        traffic-shaping-queue {
-               allocator = "integer";
-               resource-range = <832 32>;
-        };
-        gp-queue {
-               allocator = "tree";
-               resource-range = <896 7296>;
-               linux-dtb-alias = "hwqueue@2a00000", "queues", "general", "values", "end", <0>, <1>, "end";
-        };          
-    }; /* qmss */
-
-    /* CPPI channel and flow ID ranges based on tci6614 cppi_device.c */
-    cppi {
-        srio-rx-ch {
-               allocator = "integer";
-               resource-range = <0 16>;
-        };
-        srio-tx-ch {
-               allocator = "integer";
-               resource-range = <0 16>;
-        };
-        srio-rx-flow-id {
-               allocator = "integer";
-               resource-range = <0 20>;
-        };   
-
-        aif-rx-ch {
-               allocator = "tree";
-               resource-range = <0 129>;
-        };
-        aif-tx-ch {
-               allocator = "tree";
-               resource-range = <0 129>;
-        };
-        aif-rx-flow-id {
-               allocator = "tree";
-               resource-range = <0 129>;
-        };      
-
-        fftc-a-rx-ch {
-               allocator = "integer";
-               resource-range = <0 4>;
-        };
-        fftc-a-tx-ch {
-               allocator = "integer";
-               resource-range = <0 4>;
-        };
-        fftc-a-rx-flow-id {
-               allocator = "integer";
-               resource-range = <0 8>;
-        };   
-
-        fftc-b-rx-ch {
-               allocator = "integer";
-               resource-range = <0 4>;
-        };
-        fftc-b-tx-ch {
-               allocator = "integer";
-               resource-range = <0 4>;
-        };
-        fftc-b-rx-flow-id {
-               allocator = "integer";
-               resource-range = <0 8>;
-        };   
-
-        pass-rx-ch {
-               allocator = "integer";
-               resource-range = <0 23>;
-        };
-        pass-tx-ch {
-               allocator = "integer";
-               resource-range = <0 9>;
-        };
-        pass-rx-flow-id {
-               allocator = "integer";
-               resource-range = <0 32>;
-        };   
-
-        qmss-rx-ch {
-               allocator = "integer";
-               resource-range = <0 32>;
-        };
-        qmss-tx-ch {
-               allocator = "integer";
-               resource-range = <0 32>;
-        };
-        qmss-rx-flow-id {
-               allocator = "tree";
-               resource-range = <0 64>;
-        };   
-
-        bcp-rx-ch {
-               allocator = "integer";
-               resource-range = <0 8>;
-        };
-        bcp-tx-ch {
-               allocator = "integer";
-               resource-range = <0 8>;
-        };
-        bcp-rx-flow-id {
-               allocator = "tree";
-               resource-range = <0 64>;
-        };           
-    }; /* cppi */
-
-    pa-lut {
-        allocator = "integer";   
-        resource-range = <0 5>;
-    };    
-};
\ No newline at end of file
index ab0c887f21717a32ba5b9c03b645e2838aa2c1bb..84528859981a7f52ea9fb735be736e48537df0e9 100644 (file)
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
index d078f4b7a18412072dae9cfa7b8551a4dedd1f7a..773af792b40422b5c2b1ec3f1ecbf9b053b74f00 100644 (file)
@@ -3,78 +3,31 @@
 /* RM Server global policy */
 
 / {
-       /* RM will deny any resource requests for resources not defined in the policy. */
-       
-    /* Format for assigning resources to specific RM instances */
-
-       /* instance node name must match an instName provided to the Rm_init
-        * API when creating the RM instance */
-    RM_Server {  
-           qmss {
-               assigned-names = "Arm_Descriptors";
-               
-               pass-queue {
-                       assigned-names = "NETFP_Fail_Route_Queue_Num";
-               };          
-               qmss-gp-queues {
-                       assigned-names = "QOS_Ingress_Queue_Base";
-                   assigned-ranges = <2000 1000>;
-                   allocation-sizes = <32>;
-               };
-           };
-
-           cppi {
-               pass-rx-flow-id {
-                       assigned-names = "NETFP_Fail_Route_Flow_ID";
-               }; 
-           };
-    };
+       /* All RM instances expected to be resource assignees within the policy.  RM will fail at init if
+        * it finds a resource assignee that is not in the user-instances list */
+       valid-instances = "RM_Server", 
+                         "RM_Client_Delegate", 
+                         "RM_Client";
 
-    /* Format for assigning resources to specific RM instances */
-    RM_Client_Delegate {  
-           qmss {
-               pass-queue {
-                       assigned-names = "NETFP_Fail_Route_Queue_Num";
-               };                  
-               qmss-gp-queues {
-                       assigned-names = "QOS_Ingress_Queue_Base";
-                   assigned-ranges = <3000 1000>;
-                   allocation-sizes = <32>;
-               };
-               accumulator-ch {
-                   assigned-ranges = <0 48>;
-                   allocation-alignments = <4>;
-               };              
-           };
-
-           cppi {
-               pass-rx-flow-id {
-                       assigned-names = "NETFP_Fail_Route_Flow_ID";
-               }; 
-           };      
-    };  
+       /* RM will deny any resource requests for resources not defined in the policy. */
 
     /* Format for assigning resources to specific RM instances */
-    RM_Client {  
-           qmss {
-               pass-queue {
-                       assigned-names = "NETFP_Fail_Route_Queue_Num";
-               };                  
-               qmss-gp-queues {
-                   assigned-ranges = <4000 1000>;
-                   allocation-sizes = <32>;
-               };
-               accumulator-ch {
-                   assigned-ranges = <0 48>;
-                   allocation-alignments = <20>;
-               };                      
-           };
+    
+    qmss {
+        gp-queue {
+            assignments = <2000 1000>, "iu=(RM_Server RM_Client_Delegate RM_Client)",
+                          <3000 1>, "iux=(RM_Server) & iu=(RM_Client_Delegate RM_Client)";
+        };
+        accumulator-ch {
+            assignments = <0 48>, "iux=(*)";
+            alloc-alignments = <4>;
+        };              
+    };
 
-           cppi {
-               pass-rx-flow-id {
-                       assigned-names = "NETFP_Fail_Route_Flow_ID";
-               }; 
-           };      
+    cppi {
+        pass-rx-flow-id {
+            assignments = <0 20>, "iux=(*)";
+        }; 
     };    
 };
 
index 5770a64f9d86e0bdd8e4a33409656833e8c68f1b..5b1d4637e4967819d1a33e063ec04e6a2af65604 100644 (file)
@@ -131,30 +131,37 @@ void Rm_resourceFreeNsAssignmentList(Rm_NsAssignment *nsAssignmentList);
 typedef enum {
     /** Policy DTB unknown property type */
     Rm_policyPropType_UNKNOWN = 0,     
-    /** Policy DTB resource assigned ranges property type */
-    Rm_policyPropType_ASSIGNED_RANGES = 1,
+    /** Policy DTB resource assignments property type */
+    Rm_policyPropType_ASSIGNMENTS = 1,
     /** Policy DTB resource allocation sizes property type */
     Rm_policyPropType_ALLOCATION_SIZES = 2,
-    /** Policy DTB assigned NameServer names property type */
-    Rm_policyPropType_ASSIGNED_NAMES = 3,
     /** Policy DTB allocation alignments property type */
-    Rm_policyPropType_ALLOCATION_ALIGNMENTS = 4,
+    Rm_policyPropType_ALLOCATION_ALIGNMENTS = 3,
+    /** Policy DTB valid RM instances property type */
+    Rm_policyPropType_VALID_INSTANCES = 4,
 } Rm_PolicyPropType;
 
-typedef struct {
-    char *assignedName;
-    void *nextAssignedName;
-} Rm_AssignedNsNames;
+typedef struct Rm_PolicyAssignment_s {
+    uint32_t resourceBase;
+    uint32_t resourceLength;
+    char *permissionsList;
+    struct Rm_PolicyAssignment_s *nextAssignment;
+} Rm_PolicyAssignment;
+
+typedef struct Rm_PolicyValidInst_s {
+    char *instName;
+    struct Rm_PolicyValidInst_s *nextValidInst;
+} Rm_PolicyValidInst;
 
 Rm_PolicyPropType Rm_policyGetPropertyType(const char *propertyName);
-Rm_ResourceRange *Rm_policyExtractAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreeAssignedRanges(Rm_ResourceRange *rangeList);
+Rm_PolicyAssignment *Rm_policyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen);
+void Rm_policyFreeAssignments(Rm_PolicyAssignment *assignmentList);
 Rm_ResourceValue *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen);
 void Rm_policyFreeAllocationSizes(Rm_ResourceValue *allocationSizeList);
-Rm_AssignedNsNames *Rm_policyExtractAssignedNames(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreeAssignmentNames(Rm_AssignedNsNames *assignedNsNamesList);
 Rm_ResourceValue *Rm_policyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen);
 void Rm_policyFreeResourceAlignments (Rm_ResourceValue *alignmentList);
+Rm_PolicyValidInst *Rm_policyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen);
+void Rm_policyFreeValidInstances (Rm_PolicyValidInst *validInstList);
 
 /**********************************************************************
  ****************Linux DTB Parsing Defines and Functions***************
index 366a1788cc1821023fca60863a07e75020c938d3..f1d651341040cc1982dcad7c9b2fc468da4d5f89 100644 (file)
@@ -164,7 +164,7 @@ typedef struct {
     char name[RM_INSTANCE_NAME_MAX_CHARS];
     Rm_InstType instType;
     bool registeredWithDelegateOrServer;
-    Rm_Policy policyData;
+    Rm_Policy policy;
     Rm_Allocators allocators;
     Rm_NameServer nameServer;
     /* RM instance transport parameters */
@@ -183,6 +183,8 @@ Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)
 int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId);
 uint32_t Rm_transactionGetSequenceNum(Rm_Inst *rmInst);
 
+Rm_Allocator *Rm_allocatorFind(Rm_Inst *rmInst, char *resourceName);
+
 void Rm_transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction);
 void Rm_transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction);
 void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction);
index 2870bb40635957121ed1833c4b1c8d6db9a5deaf..9dda45653e10d504ce083aae7c56be50cb9eba76 100644 (file)
@@ -54,15 +54,7 @@ extern "C" {
 /* AVL BBST includes */
 #include <ti/drv/rm/include/tree.h>
 
-#define RM_NS_ACTION_APPROVED 0
-#define RM_NS_OBJECT_FOUND 1
-#define RM_NS_OBJECT_NOT_FOUND 2
-
-#define RM_NS_ACTION_DENIED -1
-#define RM_NS_ERROR_NAME_ALREADY_EXISTS -2
-#define RM_NS_ERROR_NAME_DOES_NOT_EXIST -3
-
-int32_t Rm_nsInit(Rm_Inst *rmInst);
+void Rm_nsInit(Rm_Inst *rmInst);
 int32_t Rm_nsAddObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo);
 void Rm_nsPrintObjects(Rm_Inst *rmInst);
 int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo);
index a1471b81a6983302935a84171bed58277d627d9c..a7592c252dc91448d5121642f7aae90dea07bb3f 100644 (file)
@@ -50,60 +50,54 @@ extern "C" {
 /* RM internal API includes */
 #include <ti/drv/rm/include/rm_loc.h>
 
-/* AVL BBST includes */
-#include <ti/drv/rm/include/tree.h>
-
-typedef struct {
-    Rm_PolicyHandle policyDtb;
-    void *instLookupTreeRoot;
-} Rm_PolicyData;
+/* Bit : Description
+ *-----------------------------
+ *  0  : Init      (iI) - RM instance has initialization permission for resource
+ *  1  : Use       (uU) - RM instance has usage permission for resource
+ *  2  : Exclusive (xX) - RM instance has exclusive allocation privilege for resource
+ *                        i.e. No other RM instance can reserve the resource if a RM
+ *                        instance with exclusive privilege reserves the resource
+ *  3 - 15 : UNUSED
+ */
+typedef uint16_t Rm_PermissionBits;
+
+#define RM_POLICY_PERM_INIT_LOWER 'i'
+#define RM_POLICY_PERM_INIT_UPPER 'I'
+#define RM_POLICY_PERM_INIT_SHIFT 0
+#define RM_POLICY_PERM_USE_LOWER 'u'
+#define RM_POLICY_PERM_USE_UPPER 'U'
+#define RM_POLICY_PERM_USE_SHIFT 1
+#define RM_POLICY_PERM_EXCLUSIVE_LOWER 'x'
+#define RM_POLICY_PERM_EXCLUSIVE_UPPER 'X'
+#define RM_POLICY_PERM_EXCLUSIVE_SHIFT 2
+
+#define RM_POLICY_PERM_SUBGROUP_START '('
+#define RM_POLICY_PERM_SUBGROUP_END ')'
+#define RM_POLICY_PERM_TERMINATOR '&'
+#define RM_POLICY_PERM_ASSIGNMENT '='
+
+#define RM_POLICY_SET_PERM(permBits, permTypeShift, val) \
+    permBits = ((permBits & (~(((Rm_PermissionBits) 0x1) << permTypeShift))) | \
+               ((((Rm_PermissionBits) val) & 0x1) << permTypeShift))
+#define RM_POLICY_GET_PERM(permBits, permTypeShift) \
+    ((permBits >> permTypeShift) & 0x1)
+
+typedef struct Rm_Permission_s {
+    char instName[RM_INSTANCE_NAME_MAX_CHARS];
+    Rm_PermissionBits permissionBits;
+    struct Rm_Permission_s *nextPermission;
+} Rm_PolicyPermission;
 
 typedef struct {
-    const void *rangeData;
-    int32_t rangeLen;
+    const void *assignmentData;
+    int32_t assignmentLen;
     const void *allocationSizeData;
     int32_t allocationSizeLen;
-    const void *assignedNamesData;
-    int32_t assignedNamesLen;
     const void *alignmentData;
     int32_t alignmentLen;
 } Rm_PolicyNodeProperties;
 
-typedef struct {
-    char *serviceSrcInstName;
-    /* Will contain the actual allocation/free values */
-    Rm_ResourceInfo *resourceInfo;
-} Rm_PolicyCheckInfo;
-
-int32_t Rm_policyCheck(Rm_PolicyHandle policyDtb, Rm_PolicyCheckInfo *checkInfo,
-                       Rm_PolicyNodeProperties *nodeProperties);
-int32_t Rm_policyCheckResource(Rm_Inst *rmInst, Rm_PolicyCheckInfo *checkInfo);
-void Rm_policyInit(Rm_Inst *rmInst, void *policyDtb);
-
-/**********************************************************************
- ******************* Red-Black Tree BBST Defines **********************
- **********************************************************************/
-
-/* Declare the tree structure nodes */
-typedef struct _Rm_PolicyInstNode {
-    RB_ENTRY(_Rm_PolicyInstNode) linkage;
-    char instName[RM_INSTANCE_NAME_MAX_CHARS];
-    int32_t nodeOffset;
-} Rm_PolicyInstNode;
-
-/* Declare the tree head structure. */
-typedef RB_HEAD(_Rm_PolicyInstLookupTree, _Rm_PolicyInstNode) Rm_PolicyInstLookupTree;
-
-Rm_PolicyInstNode *Rm_newPolicyInstNode(const char *instName, int32_t nodeOffset);
-void Rm_freePolicyInstNode(Rm_PolicyInstNode *node);
-/* Prototype for policy inst lookup node comparison function
- * element1 < element2 --> return < 0
- * element1 = element2 --> return 0
- * element1 > element2 --> return > 0 */
-int Rm_PolicyInstNodeCompare(Rm_PolicyInstNode *element1, Rm_PolicyInstNode *element2); 
-
-/* Generate the tree prototypes */
-RB_PROTOTYPE(_Rm_PolicyInstLookupTree, _Rm_PolicyInstNode, linkage, Rm_PolicyInstNodeCompare);
+int32_t Rm_policyInit(Rm_Inst *rmInst, void *policyDtb);
 
 #ifdef __cplusplus
 }
diff --git a/rm.h b/rm.h
index 832395d99a74dee5e3e22cb7ae14ac47ef176667..c9d08257e370a67a01379bd3c50ed932e09eb5ce 100644 (file)
--- a/rm.h
+++ b/rm.h
@@ -137,6 +137,15 @@ extern "C" {
 @ingroup RM_LLD_API
 */
 
+/* TODO: CANT CONFLICT WITH OTHER ERROR CODES INCLUDING LIBFDT */
+#define RM_INIT_OK 0
+#define RM_INIT_ERROR_INSTANCE_NAME_TOO_BIG -256
+#define RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED -257
+#define RM_INIT_ERROR_POLICY_UNKNOWN_VALID_INSTANCE -258
+#define RM_INIT_ERROR_POLICY_PERMISSION_SYNTAX_ERROR -259
+#define RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE -260
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR - 261
+
 /** 
  * @brief Maximum number of characters in a RM instance name
  */
@@ -222,12 +231,17 @@ void Rm_printResourceStatus(Rm_Handle *rmHandle);
  *      Pointer to structure containing the initialization information for
  *      this RM instance.
  *
+ *  @param[in]  *result
+ *      Pointer to a uint32_t that will contain the result of the RM 
+ *      intialization and handle creation.  Any errors encountered will be 
+ *      returned via this pointer.
+ *
  *  @retval
  *      Success - non-zero Rm_Handle returned.
  *  @retval
  *      Failure - NULL Rm_handle returned.
  */
-Rm_Handle Rm_init(Rm_InitCfg *initCfg);
+Rm_Handle Rm_init(Rm_InitCfg *initCfg, int32_t *result);
 
 /**
  *  @b Description
index 88eabc9923f40cfb18f8765a714fcc574c525939..ce45ff1528fe359db733a50879ba6251178f63a2 100644 (file)
@@ -101,8 +101,16 @@ extern "C" {
 #define RM_SERVICE_DENIED_ALLOCATION_ALIGNMENT_SPECIFICATION_ERROR (RM_SERVICE_DENIED_BEGIN+12)
 /** The resource node in the policy has an unknown property type */
 #define RM_SERVICE_DENIED_UNKNOWN_POLICY_PROPERTY (RM_SERVICE_DENIED_BEGIN+13)
+/** The policy does not approve of the resources requested by the RM instance in the service
+ *  request */
+#define RM_SERVICE_DENIED_POLICY_DENIAL (RM_SERVICE_DENIED_BEGIN+14)
+/** Attempt to add object to NameServer denied: The object name already exists in the NameServer */
+#define RM_SERVICE_DENIED_NAMESERVER_ERROR_NAME_ALREADY_EXISTS (RM_SERVICE_DENIED_BEGIN+15)
+/** No valid ranges were specified for the resource within the RM instance's node within the policy.
+ *  By default all resource requests for this resource are denied */
+#define RM_SERVICE_DENIED_POLICY_DENIAL_NO_RANGES_SPECIFIED (RM_SERVICE_DENIED_BEGIN+16)
 /** End of resource denied reasons */
-#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+13)
+#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+16)
 
 /** RM Service Request Error Code Base */
 #define RM_SERVICE_ERROR_BASE (-64)
@@ -143,6 +151,10 @@ extern "C" {
 #define RM_SERVICE_ERROR_NAMESERVER_OBJECT_MOD_ON_INVALID_INSTANCE (RM_SERVICE_ERROR_BASE-12)
 /** Request failed because both a NameServer name and a resource range were specified */
 #define RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED (RM_SERVICE_ERROR_BASE-13)
+/** Error occurred when trying to add an object to the NameServer */
+#define RM_SERVICE_ERROR_NAMESERVER_OBJECT_ADD_FAILED (RM_SERVICE_ERROR_BASE-14)
+/** Could not find the object specified in the service request in the NameServer */
+#define RM_SERVICE_ERROR_NAMESERVER_ERROR_NAME_DOES_NOT_EXIST (RM_SERVICE_ERROR_BASE-15)
 
 /**
  * @brief Maximum number of characters in the resource names
index 4b958cd8bbc87bc8095bf1c925ddf1f549a0b617..d4ed58df7951b8505dacb77ee96b3e488ad004b5 100644 (file)
@@ -48,6 +48,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdbool.h>
+#include <ctype.h>
 
 #endif /* __RMTYPES_H__ */
 
index db537518ce2d344eb0d32f5834fa493e4d124631..43a54602c6e31d7fccf0fc973348f2efc818832c 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -1043,6 +1043,7 @@ int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)
 void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
 {\r
     Rm_AllocatorOpInfo opInfo;\r
+    Rm_PolicyNodeProperties policyNodeProps;\r
     int32_t retVal = transaction->state;\r
 \r
     /* Initialize the opInfo structure */\r
@@ -1123,39 +1124,53 @@ void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
                 retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
             }\r
         }\r
-        else if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED)\r
-        {\r
-            if ((transaction->resourceInfo.alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) ||\r
-                (transaction->resourceInfo.alignment == 0))\r
-            {   \r
-                /* TEMP: Default resource alignment of 1 if the resource alignment is not\r
-                 *       specified */\r
-                opInfo.resourceInfo->alignment = 1;\r
-            }\r
-\r
-            /* TODO: set the resourceInfo->base value to be the base of the resource range\r
-             *       allowed for the RM instance */\r
-            // opInfo.resourceInfo->base = policy_get_instance_base(...);\r
-            opInfo.resourceInfo->base = 0;\r
-\r
-            /* Execute the allocator pre-allocate operation to get the next available resources.\r
-             * NORMALLY CHECKED AGAINST THE POLICY */\r
-            opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
-\r
-            /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
-             * by opInfo will contain the next available resources that satisfy the\r
-             * resource properties */\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
-        }\r
 \r
-        /* Call allocator as long as an error or denial hasn't occurred */\r
-        if ((retVal == RM_SERVICE_PROCESSING) || (retVal == RM_NS_ACTION_APPROVED))\r
+        /* Get the policy data for the specified resource and attempt to service the request */\r
+        if (retVal == RM_SERVICE_PROCESSING)\r
         {\r
-            opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
-\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+#if 0            \r
+            if((retVal = Rm_policyGetResourceData(rmInst, opInfo.serviceSrcInstName, \r
+                                                  opInfo.resourceInfo->name, &policyNodeProps)) == \r
+               RM_SERVICE_PROCESSING)\r
+            {\r
+                if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED)\r
+                {\r
+                    /* Check the alignment against the policy.  If the resource alignment is \r
+                     * unspecified the alignment will be retrieved from the policy.  If no alignment\r
+                     * is specified in the policy it will be set to the global default as specified\r
+                     * in rm_policyloc.h */\r
+                    retVal = Rm_policyValidateAlignment(rmInst, opInfo, &policyNodeProps);\r
+        \r
+                    /* TODO: set the resourceInfo->base value to be the base of the resource range\r
+                     *       allowed for the RM instance */\r
+                    // opInfo.resourceInfo->base = policy_get_instance_base(...);\r
+                    opInfo.resourceInfo->base = 0;\r
+        \r
+                    /* Execute the allocator pre-allocate operation to get the next available resources.\r
+                     * NORMALLY CHECKED AGAINST THE POLICY */\r
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
+        \r
+                    /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
+                     * by opInfo will contain the next available resources that satisfy the\r
+                     * resource properties */\r
+                    retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+                }\r
+                else\r
+                {\r
+                    /* Validate the resource against the policy if it is fully specifed in the request  */\r
+                    retVal = Rm_policyValidateResource(rmInst, opInfo, &policyNodeProps);\r
+                }\r
+        \r
+                /* Call allocator as long as an error or denial hasn't occurred */\r
+                if (retVal == RM_SERVICE_PROCESSING)\r
+                {\r
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
+                    retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+                }\r
+            }\r
+#endif            \r
         }\r
-\r
+        \r
         transaction->state = retVal;\r
 \r
         if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
@@ -1213,6 +1228,7 @@ void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
 void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
 {\r
     Rm_AllocatorOpInfo opInfo;\r
+    Rm_PolicyNodeProperties policyNodeProps;    \r
     int32_t retVal = transaction->state;\r
 \r
     /* Initialize the opInfo structure */\r
@@ -1282,14 +1298,21 @@ void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
                 retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
             }\r
         }\r
-        \r
-        /* Call allocator as long as an error or denial hasn't occurred */\r
-        if ((retVal == RM_SERVICE_PROCESSING) || (retVal == RM_NS_ACTION_APPROVED))\r
+#if 0        \r
+        if((retVal = Rm_policyGetResourceData(rmInst, opInfo.serviceSrcInstName, \r
+                                              opInfo.resourceInfo->name, &policyNodeProps)) == \r
+           RM_SERVICE_PROCESSING)\r
         {\r
-            opInfo.operation = Rm_allocatorOp_FREE;\r
-\r
-            retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+            /* Validate the resource against the policy if it is fully specifed in the request  */\r
+            if((retVal = Rm_policyValidateResource(rmInst, opInfo, &policyNodeProps) ==\r
+               RM_SERVICE_PROCESSING)\r
+            {        \r
+                /* Call allocator as long as an error or denial hasn't occurred */\r
+                opInfo.operation = Rm_allocatorOp_FREE;\r
+                retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+            }\r
         }\r
+#endif        \r
 \r
         transaction->state = retVal;\r
 \r
@@ -1558,44 +1581,23 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
                     {\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) == 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
+                        transaction->state = Rm_nsAddObject(rmInst, &transaction->resourceInfo);\r
                     }\r
                     else if (transaction->type == Rm_service_RESOURCE_GET_BY_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_nsFindObject(rmInst, &transaction->resourceInfo) == RM_NS_ACTION_APPROVED)\r
+                        /* Find the object tied to the specified name in the NameServer */\r
+                        if (Rm_nsFindObject(rmInst, &transaction->resourceInfo) == RM_SERVICE_PROCESSING)\r
                         {\r
+                            /* NameServer found the object if it returned "PROCESSING".  Map this to\r
+                             * approved and completed for the transaction state information */\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) == \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
+                        transaction->state = Rm_nsDeleteObject(rmInst, &transaction->resourceInfo);\r
                     }\r
 \r
                     /* If source instance name does not match the local instance\r
@@ -2062,16 +2064,19 @@ void Rm_printResourceStatus(Rm_Handle *rmHandle)
     Rm_nsPrintObjects(rmInst);\r
 }\r
 \r
-Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
+Rm_Handle Rm_init(Rm_InitCfg *initCfg, int32_t *result)\r
 {\r
     Rm_Inst *rmInst;\r
     void *globalResourceDtb = NULL;\r
     void *linuxResourceDtb = NULL;\r
 \r
+    *result = RM_INIT_OK;\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
+        *result = RM_INIT_ERROR_INSTANCE_NAME_TOO_BIG;\r
         return (NULL);\r
     }\r
     \r
@@ -2097,8 +2102,8 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
      * on the RM Server */\r
     rmInst->nameServer = NULL;\r
 \r
-    /* Initialize the pointer to the policy information */\r
-    rmInst->policyData = NULL;\r
+    /* Initialize the pointer to the policy */\r
+    rmInst->policy = NULL;\r
 \r
     /* Initialize the transaction queue elements. */\r
     rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
@@ -2132,7 +2137,10 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
      * Client Delegates */\r
     if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy)\r
     {\r
-        Rm_policyInit(rmInst, initCfg->policy);\r
+        if ((*result = Rm_policyInit(rmInst, initCfg->policy)) != RM_INIT_OK)\r
+        {\r
+            return(NULL);\r
+        }\r
     }\r
 \r
     /* Return the RM Handle */\r
index acb353c12d60a0853bf724115855703f48589eaf..e79c430a42f668d481c0141a4b0f031446afa414 100644 (file)
@@ -471,43 +471,117 @@ void Rm_resourceFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
 /* Policy Properties - These are the property values used
  * by an application integrator to define the properties of resources
  * listed in a Resource Manager Policy */
-char rmPolicyAssignedRanges[] = "assigned-ranges";
+char rmPolicyValidInstances[] = "valid-instances";
+char rmPolicyAssignments[] = "assignments";
 char rmPolicyAllocationSizes[] = "allocation-sizes";
-char rmPolicyAssignedNames[] = "assigned-names";
 char rmPolicyAllocationAlignments[] = "allocation-alignments";
 
 Rm_PolicyPropType Rm_policyGetPropertyType(const char * propertyName)
 {
     Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
 
-    if(strcmp(rmPolicyAssignedRanges, propertyName) == 0)
+    if(strcmp(rmPolicyAssignments, propertyName) == 0)
     {
-        propertyType = Rm_policyPropType_ASSIGNED_RANGES;
+        propertyType = Rm_policyPropType_ASSIGNMENTS;
     }
     else if(strcmp(rmPolicyAllocationSizes, propertyName) == 0)
     {
         propertyType = Rm_policyPropType_ALLOCATION_SIZES;
     }
-    else if(strcmp(rmPolicyAssignedNames, propertyName) == 0)
-    {
-        propertyType = Rm_policyPropType_ASSIGNED_NAMES;
-    }
     else if(strcmp(rmPolicyAllocationAlignments, propertyName) == 0)
     {
         propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENTS;
     }    
+    else if(strcmp(rmPolicyValidInstances, propertyName) == 0)
+    {
+        propertyType = Rm_policyPropType_VALID_INSTANCES;
+    }       
 
     return (propertyType);
 }
 
-Rm_ResourceRange *Rm_policyExtractAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen)
+Rm_PolicyAssignment *Rm_policyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen)
 {
-    return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
+    uint8_t *dtbAssignmentData = (uint8_t *)dtbDataPtr;
+    uint32_t permissionsLenBytes;
+    uint32_t extractedValue;
+    uint8_t *extractedValueBytePtr;        
+    Rm_PolicyAssignment *startAssignment = NULL;
+    Rm_PolicyAssignment *newAssignment = NULL;
+    Rm_PolicyAssignment *prevAssignment = NULL;
+    int8_t i = 0;
+    uint16_t j;
+    
+    /* Policy assignments are stored in the DTB as two 32-bit words containing a 
+     * resource base and length to be assigned the permissions in the defined in
+     * the string that follows.  There is no padding between the 32-bit words and the 
+     * string.  Therefore the 32-bit word may not be on a 4-byte boundary and must
+     * be constructed upon extraction */
+
+    /* Extract the policy assignment data from the DTB */
+    while(i < dtbDataLen)
+    {
+        /* Creat a new NameServer assignment entry */
+        newAssignment = (Rm_PolicyAssignment *) Rm_osalMalloc(sizeof(Rm_PolicyAssignment));
+
+        /* Extract the 32-bit resource base value */
+        extractedValueBytePtr = (uint8_t *)&extractedValue;
+        for (j = 0; j < sizeof(uint32_t); j++, i++)
+        {
+            extractedValueBytePtr[j] = dtbAssignmentData[i];
+        }
+        /* flip the endianness */
+        newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
+
+        /* Extract the 32-bit resource length value */
+        for (j = 0; j < sizeof(uint32_t); j++, i++)
+        {
+            extractedValueBytePtr[j] = dtbAssignmentData[i];
+        }
+        /* flip the endianness */
+        newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
+
+        /* Allocate a buffer for the assignment permissions string (adding one for 
+         * the null character). */
+        permissionsLenBytes = strlen((char *) &dtbAssignmentData[i]) + 1;
+        newAssignment->permissionsList = (char *) Rm_osalMalloc(permissionsLenBytes);
+        strcpy(newAssignment->permissionsList, ((char *) &dtbAssignmentData[i]));
+        i += permissionsLenBytes;
+
+        newAssignment->nextAssignment = NULL;
+
+        if (prevAssignment == NULL)
+        {
+            /* Save the first entry so it can be returned */
+            startAssignment = newAssignment;
+        }
+        else
+        {
+            prevAssignment->nextAssignment = newAssignment;
+        }
+        prevAssignment = newAssignment;
+    }
+
+    /* Return a pointer to the start of the policy assignment list */
+    return (startAssignment);
 }
 
-void Rm_policyFreeAssignedRanges(Rm_ResourceRange *rangeList)
+void Rm_policyFreeAssignments(Rm_PolicyAssignment *assignmentList)
 {
-    Rm_commonFreeRangeList(rangeList);
+    Rm_PolicyAssignment *nextAssignment;
+    int32_t permissionsSize;
+    
+    while (assignmentList != NULL)
+    {
+        nextAssignment = assignmentList->nextAssignment;
+        /* Free the character array memory first */
+        permissionsSize = strlen(assignmentList->permissionsList);
+        /* Add one for the NULL character */
+        Rm_osalFree((void *)assignmentList->permissionsList, permissionsSize+1);
+        /* Free the list element */
+        Rm_osalFree((void *)assignmentList, sizeof(Rm_PolicyAssignment));
+        assignmentList = nextAssignment;
+    }
 }
 
 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
@@ -522,81 +596,80 @@ void Rm_policyFreeAllocationSizes (Rm_ResourceValue *allocationSizeList)
     Rm_commonFreeValueList(allocationSizeList);
 }
 
-/* Construct and return a list of assigned NameServer names as specified in the Policy DTB */
-Rm_AssignedNsNames *Rm_policyExtractAssignedNames(const void *dtbDataPtr, int32_t dtbDataLen)
+/* Construct and return a list of allocation alignments as specified in the Policy DTB */
+Rm_ResourceValue *Rm_policyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+    return(Rm_commonExtractValueList(dtbDataPtr, dtbDataLen));
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted allocation alignments */
+void Rm_policyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
 {
-    uint8_t *dtbAssignedNsNamesData = (uint8_t *)dtbDataPtr;
-    uint32_t nameLenBytes;        
-    Rm_AssignedNsNames *startAssignedName = NULL;
-    Rm_AssignedNsNames *newAssignedName = NULL;
-    Rm_AssignedNsNames *prevAssignedName = NULL;
+    Rm_commonFreeValueList(alignmentList);
+}
+
+Rm_PolicyValidInst *Rm_policyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+    uint8_t *dtbValidInstData = (uint8_t *)dtbDataPtr;
+    uint32_t instLenBytes;       
+    Rm_PolicyValidInst *startInst = NULL;
+    Rm_PolicyValidInst *newInst = NULL;
+    Rm_PolicyValidInst *prevInst = NULL;
     int8_t i = 0;
     
-    /* Assigned NameServer names are stored in the DTB as a block of null-terminated 
-     * character strings.  There is no padding between the strings. */
+    /* Valid RM instances are stored in the DTB as a list of null-terminated character
+     * strings. */
 
-    /* Extract the assigned NameServer name data from the DTB */
+    /* Extract the valid instance data from the DTB */
     while(i < dtbDataLen)
     {
-        /* Creat a new assigned NameServer name entry */
-        newAssignedName = (Rm_AssignedNsNames *) Rm_osalMalloc(sizeof(Rm_AssignedNsNames));
+        /* Creat a new valid instance entry */
+        newInst = (Rm_PolicyValidInst *) Rm_osalMalloc(sizeof(Rm_PolicyValidInst));
         
-        /* Populate the new assigned name entry.  Allocate a buffer for the assigned
+        /* Populate the new instance entry.  Allocate a buffer for the instance
          * name string (adding one for the null character). */
-        nameLenBytes = strlen((char *) &dtbAssignedNsNamesData[i]) + 1;
-        newAssignedName->assignedName = (char *) Rm_osalMalloc(nameLenBytes);
-        strcpy(newAssignedName->assignedName, ((char *) &dtbAssignedNsNamesData[i]));
+        instLenBytes = strlen((char *) &dtbValidInstData[i]) + 1;
+        newInst->instName = (char *) Rm_osalMalloc(instLenBytes);
+        strcpy(newInst->instName, ((char *) &dtbValidInstData[i]));
+        
+        i += instLenBytes;
 
-        newAssignedName->nextAssignedName = NULL;
+        newInst->nextValidInst = NULL;
 
-        if (prevAssignedName == NULL)
+        if (prevInst == NULL)
         {
             /* Save the first entry so it can be returned */
-            startAssignedName = newAssignedName;
+            startInst = newInst;
         }
         else
         {
-            prevAssignedName->nextAssignedName = (void *) newAssignedName;
+            prevInst->nextValidInst = newInst;
         }
-        prevAssignedName = newAssignedName;
+        prevInst = newInst;
     }
 
-    /* Return a pointer to the start of the assigned NameServer names list */
-    return (startAssignedName);
+    /* Return a pointer to the start of the valid instance list */
+    return (startInst);
 }
 
-/* Function to clean up the memory allocated for a linked list of extracted 
- * assigned NameServer names. */
-void Rm_policyFreeAssignmentNames (Rm_AssignedNsNames *assignedNsNamesList)
+void Rm_policyFreeValidInstances (Rm_PolicyValidInst *validInstList)
 {
-    Rm_AssignedNsNames *nextAssignedName;
-    int32_t nameSize;
+    Rm_PolicyValidInst *nextInst;
+    int32_t instSize;
     
-    while (assignedNsNamesList != NULL)
+    while (validInstList != NULL)
     {
-        nextAssignedName = assignedNsNamesList->nextAssignedName;
+        nextInst = validInstList->nextValidInst;
         /* Free the character array memory first */
-        nameSize = strlen(assignedNsNamesList->assignedName);
+        instSize = strlen(validInstList->instName);
         /* Add one for the NULL character */
-        Rm_osalFree((void *)assignedNsNamesList->assignedName, nameSize+1);
+        Rm_osalFree((void *)validInstList->instName, instSize+1);
         /* Free the list element */
-        Rm_osalFree((void *)assignedNsNamesList, sizeof(Rm_AssignedNsNames));
-        assignedNsNamesList = nextAssignedName;
+        Rm_osalFree((void *)validInstList, sizeof(Rm_PolicyValidInst));
+        validInstList = nextInst;
     }
 }
 
-/* Construct and return a list of allocation alignments as specified in the Policy DTB */
-Rm_ResourceValue *Rm_policyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
-{
-    return(Rm_commonExtractValueList(dtbDataPtr, dtbDataLen));
-}
-
-/* Function to clean up the memory allocated for a linked list of extracted allocation alignments */
-void Rm_policyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
-{
-    Rm_commonFreeValueList(alignmentList);
-}
-
 /**********************************************************************
  ****************Linux DTB Parsing Defines and Functions***************
  **********************************************************************/
index 20740c996e5a5da2238476955cf52fe3d0f444b0..a5c47cbffd3257c08c577ac7f0fe167af6cff915 100644 (file)
@@ -97,54 +97,40 @@ RB_GENERATE(_Rm_NameServerTree, _Rm_NameServerNode, linkage, Rm_NameServerNodeCo
  ********************** Internal Functions ****************************
  **********************************************************************/
 
-int32_t Rm_nsInit(Rm_Inst *rmInst)
-{
-    Rm_NameServerTree *rootEntry = NULL;
-
-    /* Create the NameServer root entry and initialize it */
-    rootEntry = Rm_osalMalloc(sizeof(Rm_NameServerTree));
-    RB_INIT(rootEntry);
-
-    rmInst->nameServer = (void *)rootEntry;
-
-    return(RM_NS_ACTION_APPROVED);
-}
-
 int32_t Rm_nsAddObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
 {
     Rm_NameServerNode *newNode = NULL;
     Rm_NameServerNode *collidingNode = NULL;
+    int32_t retVal = RM_SERVICE_APPROVED_AND_COMPLETED;
 
     newNode = Rm_newNameServerNode(resourceInfo->nsName, resourceInfo->name,
                                    resourceInfo->base, resourceInfo->length);
 
-    /* Try to insert the new name */
-    collidingNode = RB_INSERT(_Rm_NameServerTree, rmInst->nameServer, newNode);
-
-    if (collidingNode)
+    if (newNode)
     {
-        Rm_freeNameServerNode(newNode);
-        return(RM_NS_ERROR_NAME_ALREADY_EXISTS);
+        /* Try to insert the new name */
+        collidingNode = RB_INSERT(_Rm_NameServerTree, rmInst->nameServer, newNode);
+
+        if (collidingNode)
+        {
+            Rm_freeNameServerNode(newNode);
+            retVal = RM_SERVICE_DENIED_NAMESERVER_ERROR_NAME_ALREADY_EXISTS;
+        }
     }
-    
-    return(RM_NS_ACTION_APPROVED);
-}
-
-void Rm_nsPrintObjects(Rm_Inst *rmInst)
-{
-    Rm_NameServerNode *node;
-
-    RB_FOREACH(node, _Rm_NameServerTree, rmInst->nameServer)
-    {               
-        Rm_osalLog("Name: %s resourceName: %s base: %d length: %d\n", node->name, node->resourceName,
-                                                                      node->base, node->length);
+    else
+    {
+        retVal = RM_SERVICE_ERROR_NAMESERVER_OBJECT_ADD_FAILED;
     }
+    
+    return(retVal);
 }
 
 int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
 {
     Rm_NameServerNode findNode;
     Rm_NameServerNode *matchingNode = NULL;
+    int32_t retVal = RM_SERVICE_PROCESSING;
+
 
     /* Copy the name to find into the find node structure */
     strcpy(findNode.name, resourceInfo->nsName);
@@ -160,17 +146,17 @@ int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
     }
     else
     {
-        return(RM_NS_ERROR_NAME_DOES_NOT_EXIST);
+        retVal = RM_SERVICE_ERROR_NAMESERVER_ERROR_NAME_DOES_NOT_EXIST;
     }
     
-    /* STUB APPROVED FOR NOW */
-    return(RM_NS_ACTION_APPROVED);
+    return(retVal);
 }
 
 int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
 {   
     Rm_NameServerNode findNode;
     Rm_NameServerNode *matchingNode = NULL;
+    int32_t retVal = RM_SERVICE_APPROVED_AND_COMPLETED;    
 
     /* Copy the name to find into the find node structure */
     strcpy(findNode.name, resourceInfo->nsName);
@@ -185,10 +171,31 @@ int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
     }
     else
     {
-        return(RM_NS_ERROR_NAME_DOES_NOT_EXIST);
+        retVal = RM_SERVICE_ERROR_NAMESERVER_ERROR_NAME_DOES_NOT_EXIST;
     }
     
-    /* STUB APPROVED FOR NOW */
-    return(RM_NS_ACTION_APPROVED);
+    return(retVal);
+}
+
+void Rm_nsPrintObjects(Rm_Inst *rmInst)
+{
+    Rm_NameServerNode *node;
+
+    RB_FOREACH(node, _Rm_NameServerTree, rmInst->nameServer)
+    {               
+        Rm_osalLog("Name: %s resourceName: %s base: %d length: %d\n", node->name, node->resourceName,
+                                                                      node->base, node->length);
+    }
+}
+
+void Rm_nsInit(Rm_Inst *rmInst)
+{
+    Rm_NameServerTree *rootEntry = NULL;
+
+    /* Create the NameServer root entry and initialize it */
+    rootEntry = Rm_osalMalloc(sizeof(Rm_NameServerTree));
+    RB_INIT(rootEntry);
+
+    rmInst->nameServer = (void *)rootEntry;
 }
 
index 178e3f1ec293804f336e9cdcae8a0417f54741be..2118e224669270d1482fbc5bce17cd0e4fdde0a1 100644 (file)
@@ -43,6 +43,7 @@
 #include <ti/drv/rm/rm_types.h>
 
 /* RM external API includes */
+#include <ti/drv/rm/rm.h>
 #include <ti/drv/rm/rm_policy.h>
 #include <ti/drv/rm/rm_services.h>
 
 /* RM OSAL layer */
 #include <rm_osal.h>
 
-/**********************************************************************
- ************** Red-Black BBST Tree NameServer Functions **************
- **********************************************************************/
+int32_t Rm_policyCheckInstances(Rm_PolicyValidInst *validInstList, 
+                                Rm_PolicyPermission *permissionsList)
+{
+
+    return(RM_INIT_OK);
+}
 
-Rm_PolicyInstNode *Rm_newPolicyInstNode(const char *instName, int32_t nodeOffset)
+Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permStrEnd, 
+                                                 int32_t *result)
 {
-    Rm_PolicyInstNode *newNode = NULL;
+    Rm_PolicyPermission *startPerm = NULL;
+    Rm_PolicyPermission *newPerm = NULL;
+    Rm_PolicyPermission *prevPerm = NULL;
+    Rm_PolicyPermission *nextPerm = NULL;
+    char *permStrPtr = NULL;
+    char *subgroupStart = NULL;
+    char *subgroupEnd = NULL;
+    uint32_t permStrLen = (uint32_t)(permStrEnd - permStrStart + 1);
+    char instNameTemp[RM_INSTANCE_NAME_MAX_CHARS];
+    uint32_t instNameIndex;
+    bool foundInstName;
+    bool instNameComplete;
+    bool foundAssignment;
+
+    /* Create a local copy of the sub-permission string */
+    permStrPtr = Rm_osalMalloc(permStrLen);
+    strncpy(permStrPtr, permStrStart, permStrLen);
+    /* Make sure the last character in the copied sub-permission string is null */
+    permStrPtr[permStrLen - 1] = '\0';
+
+    permStrStart = permStrPtr;
+    permStrEnd = permStrPtr + strlen(permStrPtr);
+
+    /* Find the beginning and end of the sub-permission instance group */
+    subgroupStart = strchr(permStrStart, RM_POLICY_PERM_SUBGROUP_START);
+    subgroupEnd = strchr(permStrStart, RM_POLICY_PERM_SUBGROUP_END);
+
+    if ((!subgroupStart) || (!subgroupEnd) || (subgroupStart > subgroupEnd) ||
+        ((subgroupStart != strrchr(permStrStart, RM_POLICY_PERM_SUBGROUP_START)) &&
+         (subgroupEnd != strrchr(permStrStart, RM_POLICY_PERM_SUBGROUP_END))))
+    {
+        /* Free the memory associated with the temp string and return an error if:
+         * a) Could not find the instance group start
+         * b) Could not find the instance group end
+         * c) Subgroup start and end are out of order
+         * d) There is more than one instance subgroup specified in the string.  There
+         *    should only be one subgroup per sub-permission string */
+        Rm_osalFree((void *)permStrStart, permStrLen);
+        *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+        return(NULL);
+    }
+
+    /* Create a permission entry for each instance specified in the instance group.
+     * Instances names are separated by one or more spaces. */
+    permStrPtr = subgroupStart;
+    instNameIndex = 0;
+    foundInstName = FALSE;
+    instNameComplete = FALSE;
+    while (permStrPtr < subgroupEnd)
+    {
+        if (isspace(*permStrPtr) && foundInstName)
+        {
+            /* First space encountered after copying an instance name.  This
+             * terminates the instance name.  All other space characters are
+             * ignored. */
+            instNameTemp[instNameIndex] = '\0';
+            instNameComplete = TRUE; 
+        }
+        else
+        {
+            if (!foundInstName)
+            {
+                /* First non-whitespace character encountered is the start of an
+                 * instance name */
+                foundInstName = TRUE;
+            }
 
-    newNode = Rm_osalMalloc(sizeof(Rm_PolicyInstNode));
+            /* Copy the character into the temporary instance name string */
+            instNameTemp[instNameIndex++] = *permStrPtr;
+        }
 
-    /* Populate the node */
-    strcpy(newNode->instName, instName);
-    newNode->nodeOffset = nodeOffset;
-    
-    return(newNode);
+        if (instNameComplete)
+        {
+            newPerm = (Rm_PolicyPermission *) Rm_osalMalloc(sizeof(Rm_PolicyPermission));
+            memset((void *)newPerm, 0, sizeof(Rm_PolicyPermission));
+
+            strcpy(newPerm->instName, instNameTemp);
+            newPerm->nextPermission = NULL;
+
+            if (prevPerm == NULL)
+            {
+                /* Save the first instance so it can be returned */
+                startPerm = newPerm;
+            }
+            else
+            {
+                prevPerm->nextPermission = (void *) newPerm;
+            }
+            prevPerm = newPerm;
+
+            instNameComplete = FALSE;
+            instNameIndex = 0;
+            foundInstName = FALSE;
+        }
+
+        permStrPtr++;
+    }
+
+    /* Fill in the permissions for each instance name */
+
+    /* Look on left of instance group for the permission assignments. */
+    permStrPtr = subgroupStart;
+    foundAssignment = FALSE;
+    while (permStrPtr >= permStrStart)
+    {
+        if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT)
+        {
+            if (foundAssignment)
+            {
+                /* Assignment character has been found more than once.  This is a
+                 * syntax error.  Free the permission list and the temporary string
+                 * and return. */
+                while (startPerm)
+                {
+                    nextPerm = startPerm->nextPermission;
+                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                    startPerm = nextPerm;
+                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                    return(NULL);
+                } 
+            }
+            else
+            {
+                foundAssignment = TRUE;
+            }
+        }
+        else if (!isspace(*permStrPtr))
+        {
+            if (foundAssignment)
+            {
+                if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) || 
+                    (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
+                {
+                    
+                    /* Set the init permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) || 
+                         (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
+                {
+                    /* Set the use permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) || 
+                         (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
+                {
+                    /* Set the exclusive permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else
+                {
+                    /* Invalid permission character.  This is a
+                     * syntax error.  Free the permission list and the temporary string
+                     * and return. */
+                    while (startPerm)
+                    {
+                        nextPerm = startPerm->nextPermission;
+                        Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                        startPerm = nextPerm;
+                        Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                        *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                        return(NULL);
+                    }                      
+                }
+            }
+            else
+            {
+                /* Character found without the assignment character being found.  This is a
+                 * syntax error.  Free the permission list and the temporary string
+                 * and return. */
+                while (startPerm)
+                {
+                    nextPerm = startPerm->nextPermission;
+                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                    startPerm = nextPerm;
+                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                    return(NULL);
+                }    
+            }
+        }
+        permStrPtr--;
+    }
+
+    /* Look on right of instance group for the permission assignments. */
+    permStrPtr = subgroupEnd;
+    while (permStrPtr <= permStrEnd)
+    {
+        if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT)
+        {
+            if (foundAssignment)
+            {
+                /* Assignment character has been found more than once.  This is a
+                 * syntax error.  Free the permission list and the temporary string
+                 * and return. */
+                while (startPerm)
+                {
+                    nextPerm = startPerm->nextPermission;
+                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                    startPerm = nextPerm;
+                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                    return(NULL);
+                } 
+            }
+            else
+            {
+                foundAssignment = TRUE;
+            }
+        }
+        else if (!isspace(*permStrPtr))
+        {
+            if (foundAssignment)
+            {
+                if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) || 
+                    (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
+                {
+                    
+                    /* Set the init permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) || 
+                         (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
+                {
+                    /* Set the use permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) || 
+                         (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
+                {
+                    /* Set the exclusive permissions */
+                    RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
+                    permStrPtr++;
+                }
+                else
+                {
+                    /* Invalid permission character.  This is a
+                     * syntax error.  Free the permission list and the temporary string
+                     * and return. */
+                    while (startPerm)
+                    {
+                        nextPerm = startPerm->nextPermission;
+                        Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                        startPerm = nextPerm;
+                        Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                        *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                        return(NULL);
+                    }                      
+                }
+            }
+            else
+            {
+                /* Character found without the assignment character being found.  This is a
+                 * syntax error.  Free the permission list and the temporary string
+                 * and return. */
+                while (startPerm)
+                {
+                    nextPerm = startPerm->nextPermission;
+                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+                    startPerm = nextPerm;
+                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+                    return(NULL);
+                }    
+            }
+        }
+        permStrPtr++;
+    }
+
+    *result = RM_INIT_OK;
+    return (startPerm);
 }
 
-void Rm_freePolicyInstNode(Rm_PolicyInstNode *node)
+void Rm_policyFreeAssignmentPermissions(Rm_PolicyPermission *permissionList)
 {
-    /* Free the memory associated with the tree node. */
-    Rm_osalFree((void *)node, sizeof(Rm_PolicyInstNode));
+    Rm_PolicyPermission *nextPerm;
+    
+    while (permissionList != NULL)
+    {
+        nextPerm = permissionList->nextPermission;
+        /* Free the list element */
+        Rm_osalFree((void *)permissionList, sizeof(Rm_PolicyPermission));
+        permissionList = nextPerm;
+    }
 }
 
-/* Prototype for tree node comparison function
- * element1 < element2 --> return < 0
- * element1 = element2 --> return 0
- * element1 > element2 --> return > 0 */
-int Rm_PolicyInstNodeCompare(Rm_PolicyInstNode *element1, Rm_PolicyInstNode *element2)
+Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assignment, 
+                                                       int32_t *result)
 {
-    return(strcmp(element1->instName, element2->instName));
-}
+    Rm_PolicyPermission *startPerm = NULL;
+    Rm_PolicyPermission *newPerm = NULL;
+    Rm_PolicyPermission *prevPerm = NULL;
+    char *permStrStart = assignment->permissionsList;
+    char *permStrEnd;
+    uint32_t permStrLen = strlen(assignment->permissionsList) + 1;
+    uint32_t i = 0;
+    
+    while(i < permStrLen)
+    {
+        /* Find the first sub-permission specification and parse it.  A sub-permission
+         * can be terminated by the termination character or the end of the string. */
+        if (!(permStrEnd = strchr(permStrStart, RM_POLICY_PERM_TERMINATOR)))
+        {           
+            /* Sub-permission termination character not found.  The permission string
+             * end is the end of the entire permission string */
+            permStrEnd = permStrStart + strlen(permStrStart);
+        }
 
-/* Generate the red-black tree manipulation functions */
-RB_GENERATE(_Rm_PolicyInstLookupTree, _Rm_PolicyInstNode, linkage, Rm_PolicyInstNodeCompare);
+        newPerm = Rm_policyParseSubPermission(permStrStart, permStrEnd, result);
 
-/**********************************************************************
- ********************** Internal Functions ****************************
- **********************************************************************/
+        if (*result != RM_INIT_OK)
+        {
+            /* Delete the permission list that's been created thus far, return
+             * the error and NULL for the permission list */
+            Rm_policyFreeAssignmentPermissions(startPerm);
+            return(NULL);
+        }
 
-/* Function parses the policy DTB and saves the offset into the DTB for each
- * RM instance name.  When services need to be checked against the policy the
- * RM instance offset into the policy DTB can be retrieved from the lookup
- * tree rather than reparsing the entire policy DTB */
-void Rm_policyCreateInstanceLookup(Rm_PolicyData *policyDataPtr)
-{
-    Rm_PolicyInstLookupTree *rootEntry = NULL;
-    Rm_PolicyInstNode *policyNode = NULL;  
-    Rm_PolicyInstNode *collidingNode = NULL;    
-    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
-    int32_t depth = RM_DTB_UTIL_STARTING_DEPTH;
-    const char *instName;
-
-    /* Create the policy instance lookup root entry and initialize it */
-    rootEntry = Rm_osalMalloc(sizeof(Rm_PolicyInstLookupTree));
-    RB_INIT(rootEntry);
-
-    policyDataPtr->instLookupTreeRoot = (void *)rootEntry;
-
-    /* Parse the entire policy DTB and store the node offsets that correspond to the root
-     * node for each RM instance. */
-    do
-    {
-        if (depth == RM_POLICY_DTB_INSTANCE_DEPTH)
+        if (prevPerm == NULL)
         {
-            instName = fdt_get_name(policyDataPtr->policyDtb, nodeOffset, NULL);
-            
-            /* Store the RM instance name and it's node offset into the policy DTB */
-            policyNode = Rm_newPolicyInstNode(instName, nodeOffset);
-            
-            /* Try to insert the new policy lookup node */
-            collidingNode = RB_INSERT(_Rm_PolicyInstLookupTree, 
-                                      policyDataPtr->instLookupTreeRoot, policyNode);
-            if (collidingNode)
-            {
-                Rm_freePolicyInstNode(policyNode);
-            }            
+            /* Save the first sub-permission in the list so it can be returned */
+            startPerm = newPerm;
+        }
+        else
+        {
+            prevPerm->nextPermission = newPerm;
+        }
+
+        /* Set prevPerm to the last sub-permission returned by the sub-permission parser */
+        prevPerm = newPerm;
+        while(prevPerm->nextPermission != NULL)
+        {
+            prevPerm = prevPerm->nextPermission;
         }
         
-        /* Get the next node */
-        nodeOffset = fdt_next_node(policyDataPtr->policyDtb, nodeOffset, &depth);
-    } while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH));
-   
-    /* TODO: ADD ERROR RETURN CODES */
+        /* Update the number of characters parsed from the permission list and point to 
+         * the start of the next sub-permission */
+        i += ((uint32_t)(permStrEnd - permStrStart + 1));
+        permStrStart = permStrEnd + 1;
+    }
+
+    *result = RM_INIT_OK;
+    /* Return a pointer to the start of the permissions list */
+    return(startPerm);
 }
 
-int32_t Rm_policyCheck(Rm_PolicyHandle policyDtb, Rm_PolicyCheckInfo *checkInfo,
-                       Rm_PolicyNodeProperties *nodeProperties)
+int32_t Rm_policyValidateAssignmentPermissions(Rm_PolicyValidInst *validInstList,
+                                               Rm_PolicyAssignment *assignmentList)
 {
+    Rm_PolicyAssignment *assignment = assignmentList;
+    Rm_PolicyPermission *permissionList;
+    int32_t result;
+
+    while (assignment)
+    {
+        /* Run the permissions parser to make sure the assignment's permissions
+         * parse okay */
+        permissionList = Rm_policyGetAssignmentPermissions(assignment, &result);
+        if (result != RM_INIT_OK)
+        {
+            return(result);
+        }                        
+        
+        /* Compare the instances defined in the permissions with those defined
+         * in the valid instance list.  Return an error if there are any
+         * instances defined in the permissions that are not defined in the
+         * valid instance list */
+        if (result = Rm_policyCheckInstances(validInstList, permissionList) != RM_INIT_OK)
+        {
+            Rm_policyFreeAssignmentPermissions(permissionList);
+            return(result);
+        }
 
+        Rm_policyFreeAssignmentPermissions(permissionList);
+        assignment = assignment->nextAssignment;
+    }
+
+    return (RM_INIT_OK);
 }
 
-int32_t Rm_policyCheckResource(Rm_Inst *rmInst, Rm_PolicyCheckInfo *checkInfo)
+int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb)
 {
-    Rm_PolicyData *policyDataPtr = (Rm_PolicyData *) rmInst->policyData;
-    Rm_PolicyInstNode findNode;
-    Rm_PolicyInstNode *matchingNode = NULL;
     int32_t nodeOffset;
-    int32_t depth = RM_DTB_UTIL_STARTING_DEPTH;
+    int32_t propertyOffset;
+    int32_t depth;
     const char *nodeName;
-    Rm_PolicyNodeProperties nodeProps;  
+    const char *propertyName;
        int32_t propertyLen;
        const void *propertyData;
-    Rm_PolicyPropType propertyType;    
-    int32_t retVal = RM_SERVICE_PROCESSING;
+    Rm_PolicyPropType propertyType;
+    Rm_PolicyValidInst *validInstList;
+    Rm_PolicyAssignment *assignmentList;
+    int32_t result;
 
-    /* Initialize the node properties to NULL */
-    memset((void *) &nodeProps, 0, sizeof(Rm_PolicyNodeProperties));
-    
-    /* Get the RM instance's node offset from the lookup tree */
-    strcpy(findNode.instName, checkInfo->serviceSrcInstName);
-    matchingNode = RB_FIND(_Rm_PolicyInstLookupTree, policyDataPtr->instLookupTreeRoot, &findNode);
+    depth = RM_DTB_UTIL_STARTING_DEPTH;
+    nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
 
-    if (matchingNode)
+    /* Get the root node's properties which must contain the valid-instance list */
+    nodeOffset = fdt_first_property_offset(policyDtb, nodeOffset);
+    if (nodeOffset < -FDT_ERR_NOTFOUND)
     {
-        nodeOffset = matchingNode->nodeOffset;
-        nodeName = matchingNode->instName;        
-
-        /* Search for the resource node that matches the resource in the service request.
-         * Exit the search loop if the resource node is found or if all subnodes have been parsed
-         * without finding the resource (signalled by the depth being equivalent to the starting
-         * depth. */
-        while (strcmp(nodeName, checkInfo->resourceInfo->name))
-        {
-            /* Parse the nodes for the resource node.  All nodes should be subnodes of the
-             * found RM instance node.  Therefore, the depth should be greater than the
-             * starting depth */
-            nodeOffset = fdt_next_node(policyDataPtr->policyDtb, nodeOffset, &depth);
-            
-            if ((depth <= RM_DTB_UTIL_STARTING_DEPTH) || (nodeOffset <= -FDT_ERR_NOTFOUND))
-            {
-                retVal = RM_SERVICE_DENIED_RESOURCE_NOT_DEFINED_IN_POLICY;
-                break;
-            }  
-            
-            nodeName = fdt_get_name(policyDataPtr->policyDtb, nodeOffset, NULL);         
-        }
-
-        if (retVal == RM_SERVICE_PROCESSING)
-        {
-            /* Get the resource node's properties */
+        return (nodeOffset);
+    }
+    else if (nodeOffset == -FDT_ERR_NOTFOUND)
+    {
+        return (RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED);
+    }
+    propertyData = fdt_getprop_by_offset(policyDtb, nodeOffset, &nodeName, &propertyLen);
+    propertyType = Rm_policyGetPropertyType(nodeName);
+    if (propertyType != Rm_policyPropType_VALID_INSTANCES)
+    {
+        return (RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED);
+    }
+    validInstList = Rm_policyExtractValidInstances(propertyData, propertyLen);
 
-            /* Get the properties for the resource node if any exist */
-           nodeOffset = fdt_first_property_offset(policyDataPtr->policyDtb, nodeOffset);
+    /* Parse the DTB, verifying each resource's assignment permissions.  The
+     * permissions must have the correct syntax and contain valid instance names
+     * according the validInstList */
+    while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH))
+    {
+        nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
+        nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
 
-            while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (retVal == RM_SERVICE_PROCESSING))
+        /* Parse the properties for an assignment field if the node contains any properties. */
+        propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);
+        if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET)
+        {
+            /* Make sure the resource node name matches an existing allocator */
+            if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL)
             {
-                /* Get the property data and store it in the corresponding nodeProps field */
-                   propertyData = fdt_getprop_by_offset(policyDataPtr->policyDtb, nodeOffset, 
-                                                        &nodeName, &propertyLen);
-
-                propertyType = Rm_policyGetPropertyType(nodeName);
-                if (propertyType == Rm_policyPropType_ASSIGNED_RANGES)
-                {
-                    if (nodeProps.rangeData || nodeProps.rangeLen)
-                    {
-                        /* The range fields have already been populated.  Return an error.
-                         * The policy has specified a property field more than once
-                         * for a resource node */
-                        retVal = RM_SERVICE_DENIED_ASSIGNED_RANGE_SPECIFICATION_ERROR;
-                    }
-                    else
-                    {
-                        nodeProps.rangeData = propertyData;
-                        nodeProps.rangeLen = propertyLen;
-                    }
-                }
-                else if (propertyType == Rm_policyPropType_ALLOCATION_SIZES)
-                {
-                    if (nodeProps.allocationSizeData || nodeProps.allocationSizeLen)
-                    {
-                        /* The allocationSize fields have already been populated.  Return an error.
-                         * The policy has specified a property field more than once
-                         * for a resource node */
-                        retVal = RM_SERVICE_DENIED_ALLOCATION_SIZE_SPECIFICATION_ERROR;
-                    }
-                    else
-                    {
-                        nodeProps.allocationSizeData = propertyData;
-                        nodeProps.allocationSizeLen = propertyLen;
-                    }
-                }
-                else if (propertyType == Rm_policyPropType_ASSIGNED_NAMES)
-                {
-                    if (nodeProps.assignedNamesData || nodeProps.assignedNamesLen)
-                    {
-                        /* The assignedNames fields have already been populated.  Return an error.
-                         * The policy has specified a property field more than once
-                         * for a resource node */
-                        retVal = RM_SERVICE_DENIED_ASSIGNED_NAME_SPECIFICATION_ERROR;
-                    }
-                    else
-                    {
-                        nodeProps.assignedNamesData = propertyData;
-                        nodeProps.assignedNamesLen = propertyLen;
-                    }
-                }        
-                else if (propertyType == Rm_policyPropType_ALLOCATION_ALIGNMENTS)
+                Rm_policyFreeValidInstances(validInstList);
+                return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
+            }        
+                
+            while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET)
+            {
+                /* Get the assignment data */
+                propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
+            
+                propertyType = Rm_policyGetPropertyType(propertyName);
+                if (propertyType == Rm_policyPropType_ASSIGNMENTS)
                 {
-                    if (nodeProps.alignmentData || nodeProps.alignmentLen)
+                    assignmentList = Rm_policyExtractAssignments(propertyData, propertyLen);
+                    
+                    /* Make sure the assignment's permissions parse okay and there all RM instances
+                     * defined in the permission lists match with the valid instances. */
+                    if ((result = Rm_policyValidateAssignmentPermissions(validInstList, assignmentList)) != 
+                        RM_INIT_OK)
                     {
-                        /* The alignment fields have already been populated.  Return an error.
-                         * The policy has specified a property field more than once
-                         * for a resource node */
-                        retVal = RM_SERVICE_DENIED_ALLOCATION_ALIGNMENT_SPECIFICATION_ERROR;
+                        Rm_policyFreeValidInstances(validInstList);
+                        Rm_policyFreeAssignments(assignmentList);
+                        return(result);
                     }
-                    else
-                    {
-                        nodeProps.alignmentData = propertyData;
-                        nodeProps.alignmentLen = propertyLen;
-                    }
-                }                  
-                else
-                {
-                    retVal = RM_SERVICE_DENIED_UNKNOWN_POLICY_PROPERTY;
+
+                    Rm_policyFreeAssignments(assignmentList);
                 }
 
-                nodeOffset = fdt_next_property_offset(policyDataPtr->policyDtb, nodeOffset);
+                propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
             }
         }
-
-        if (retVal == RM_SERVICE_PROCESSING)
-        {
-            /* Check the resource(s) in the service request against what is assigned to 
-             * the instance */
-            retVal = Rm_policyCheck(policyDataPtr->policyDtb, checkInfo, &nodeProps);
-        }
     }
-    else
-    {
-        /* RM instance not defined in policy.  Service denied */
-        retVal = RM_SERVICE_DENIED_RM_INST_NOT_DEFINED_IN_POLICY;
-    }    
 
-    return(retVal);
+    Rm_policyFreeValidInstances(validInstList);
+    return(RM_INIT_OK);
 }
 
-void Rm_policyInit(Rm_Inst *rmInst, void *policyDtb)
+/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
+int32_t Rm_policyInit(Rm_Inst *rmInst, void *policyDtb)
 {
-    Rm_PolicyData *policyDataPtr;
-    
-    /* Allocate memory for the policy data structure */
-    policyDataPtr = Rm_osalMalloc(sizeof(Rm_PolicyData));
+    int32_t result = RM_INIT_OK;
     
     /* Open the policy DTB and create the instance node offset lookup table */
-    fdt_open_into(policyDtb, policyDtb, fdt_totalsize(policyDtb));
-    policyDataPtr->policyDtb = policyDtb;
-    Rm_policyCreateInstanceLookup(policyDataPtr);
+    fdt_open_into(policyDtb, policyDtb, fdt_totalsize(policyDtb));    
+
+    /* Validate the RM policy and store it in the RM instance if validation succeeds
+     * a) Compare the list of valid instances with the instances specified in
+     *    the permission assignments
+     * b) Make sure there are no syntax errors in the assignment permission
+     *    strings */
+    if ((result = Rm_policyValidatePolicy(rmInst, policyDtb)) == RM_INIT_OK)
+    {
+        rmInst->policy = policyDtb;
+    }
 
-    /* Store the policy in the RM instance */
-    rmInst->policyData = (void *) policyDataPtr;
+    return(result);
 }