Adding policy checking feature on RM Server
authorJustin Sobota <jsobota@ti.com>
Mon, 7 Jan 2013 19:40:51 +0000 (14:40 -0500)
committerJustin Sobota <jsobota@ti.com>
Mon, 7 Jan 2013 19:40:51 +0000 (14:40 -0500)
12 files changed:
device/tci6614-global-policy.dts.old [deleted file]
device/tci6614-server-policy.dtb [new file with mode: 0644]
device/tci6614-server-policy.dts [new file with mode: 0644]
include/rm_dtb_utilloc.h
include/rm_loc.h
include/rm_policyloc.h [new file with mode: 0644]
rm.h
rm_services.h
src/rm.c
src/rm_dtb_util.c
src/rm_policy.c
test/rm_test.c

diff --git a/device/tci6614-global-policy.dts.old b/device/tci6614-global-policy.dts.old
deleted file mode 100644 (file)
index 7f5c9ac..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/dts-v1/;
-
-/ {
-    policy-type = "global";  /* Policy type i.e. global-policy or 
-                                   * startup-policy */
-    
-    /* Format for defining resources available to all RM instances and system 
-     * tasks */
-    unrestricted {
-        /* System resources with resource-name that matches a resource name
-         * provided in both the global device list and by components
-         * utilizing RM.  The resource node name must match a resource node name
-         * defined in a component utilizing RM and in the global resource list. */
-        timers {  
-            /* assigned range property - defines the range of this resource
-             * available to the instance node.
-             * The format is <base num> - base = the first value in the range
-             *                                   of the available resource
-             *                            num  = number of this type of 
-             *                                   resource starting at base */
-            assigned-ranges = <0 5 7 13>;  /* range specifies 6 isn't used */
-            /* Maximum allocatable resource block size.  Block allocations
-             * typically used for resources with large pools such as general
-             * purpose QM queues and memory */
-            allocation-size = <1>;
-            /* Name resources of this type registered with the NameServer that
-             * are available.  Name must match a name registered with the
-             * NameServer */
-            assigned-ns-names = "Shared_Timer","The_Other_Timer";
-        };
-           qmss {
-               qmss-gp-queues {
-                   assigned-ranges = <0 2000>;
-                   allocation-sizes = <32>;
-               };
-               qmss-accum-queues {
-                   assigned-ranges = <4000 32>;
-                   allocation-sizes = <1>;
-               };
-           };
-    };
-
-    /* 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 {  
-        timers {  
-            assigned-ranges = <14 15>;
-            allocation-sizes = <1>;
-        };
-           qmss {
-               qmss-gp-queues {
-                   assigned-range = <2000 1000>;
-                   allocation-sizes = <32>;
-               };
-           };
-    };
-
-    /* Format for assigning resources to specific RM instances */
-    RM_Client {  
-           qmss {
-               qmss-gp-queues {
-                   assigned-ranges = <3000 1000>;
-                   allocation-sizes = <32>;
-               };
-           };
-    };    
-
-    test-task {  
-        timers {  
-            assigned-ranges = <16>;
-            allocation-sizes = <1>;
-        };
-    };
-};
-
-
diff --git a/device/tci6614-server-policy.dtb b/device/tci6614-server-policy.dtb
new file mode 100644 (file)
index 0000000..ab0c887
Binary files /dev/null and b/device/tci6614-server-policy.dtb differ
diff --git a/device/tci6614-server-policy.dts b/device/tci6614-server-policy.dts
new file mode 100644 (file)
index 0000000..d078f4b
--- /dev/null
@@ -0,0 +1,81 @@
+/dts-v1/;
+
+/* 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";
+               }; 
+           };
+    };
+
+    /* 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";
+               }; 
+           };      
+    };  
+
+    /* 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>;
+               };                      
+           };
+
+           cppi {
+               pass-rx-flow-id {
+                       assigned-names = "NETFP_Fail_Route_Flow_ID";
+               }; 
+           };      
+    };    
+};
+
+
index 103df61656820e64c6035b3e419dd7b3c5931e0f..5770a64f9d86e0bdd8e4a33409656833e8c68f1b 100644 (file)
@@ -68,6 +68,11 @@ typedef struct {
     void *nextRange;
 } Rm_ResourceRange;
 
+typedef struct {
+    uint32_t value;
+    void *nextValue;
+} Rm_ResourceValue;
+
 /**********************************************************************
  ***********Resource List DTB Parsing Defines and Functions************
  **********************************************************************/
@@ -118,38 +123,38 @@ void Rm_resourceFreeNsAssignmentList(Rm_NsAssignment *nsAssignmentList);
  ***************Policy DTB Parsing Defines and Functions***************
  **********************************************************************/
 
+/** 
+* @brief Depth of the RM instance nodes in the policy DTB
+*/
+#define RM_POLICY_DTB_INSTANCE_DEPTH 1
+
 typedef enum {
     /** Policy DTB unknown property type */
-    Rm_policyPropType_UNKNOWN = 0,
-    /** Policy DTB policy type property type */
-    Rm_policyPropType_POLICY_TYPE = 1,      
+    Rm_policyPropType_UNKNOWN = 0,     
     /** Policy DTB resource assigned ranges property type */
-    Rm_policyPropType_RESOURCE_ASSIGNED_RANGES = 2,
+    Rm_policyPropType_ASSIGNED_RANGES = 1,
     /** Policy DTB resource allocation sizes property type */
-    Rm_policyPropType_RESOURCE_ALLOCATION_SIZES = 3,
+    Rm_policyPropType_ALLOCATION_SIZES = 2,
     /** Policy DTB assigned NameServer names property type */
-    Rm_policyPropType_ASSIGNED_NS_NAMES = 4,    
+    Rm_policyPropType_ASSIGNED_NAMES = 3,
+    /** Policy DTB allocation alignments property type */
+    Rm_policyPropType_ALLOCATION_ALIGNMENTS = 4,
 } Rm_PolicyPropType;
 
-typedef struct {
-    uint32_t allocationSize;
-    void *nextAllocationSize;
-} Rm_AllocationSize;
-
 typedef struct {
     char *assignedName;
     void *nextAssignedName;
 } Rm_AssignedNsNames;
 
 Rm_PolicyPropType Rm_policyGetPropertyType(const char *propertyName);
-char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreePolicyType(char *policyType);
 Rm_ResourceRange *Rm_policyExtractAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen);
 void Rm_policyFreeAssignedRanges(Rm_ResourceRange *rangeList);
-Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreeAllocationSizesPropList(Rm_AllocationSize *allocationSizeList);
-Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreeAssignmentNsNamesList(Rm_AssignedNsNames *assignedNsNamesList);
+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);
 
 /**********************************************************************
  ****************Linux DTB Parsing Defines and Functions***************
index 057942e8ac0b45e6e5482b66b01260b4f73a61f5..366a1788cc1821023fca60863a07e75020c938d3 100644 (file)
@@ -46,7 +46,6 @@ extern "C" {
 
 /* RM external includes */
 #include <ti/drv/rm/rm_services.h>
-#include <ti/drv/rm/rm_policy.h>
 #include <ti/drv/rm/rm_transport.h>
 
 /* AVL BBST includes */
@@ -76,6 +75,9 @@ typedef void *Rm_Allocators;
 /** Pointer to the RM instance's NameServer (Valid only on Server) */
 typedef void *Rm_NameServer;
 
+/** Pointer to the RM instance's policy information */
+typedef void *Rm_Policy;
+
 /**
  * @brief RM protocol packet resource information
  */
@@ -106,7 +108,7 @@ typedef struct {
     Rm_ServiceType type;
     /** Local ID of the transaction. */
     uint32_t localId;
-    /** ID of transaction on lower level RM instance that generated the
+    /** ID of transaction in RM instance that generated the
      *  packet that resulted in the creation of the transaction.  The
      *  originating ID will be placed in the transaction's response packet
      *  to the lower level RM instance.  The lower level RM instance will 
@@ -162,7 +164,7 @@ typedef struct {
     char name[RM_INSTANCE_NAME_MAX_CHARS];
     Rm_InstType instType;
     bool registeredWithDelegateOrServer;
-    Rm_PolicyHandle policyDtb;
+    Rm_Policy policyData;
     Rm_Allocators allocators;
     Rm_NameServer nameServer;
     /* RM instance transport parameters */
diff --git a/include/rm_policyloc.h b/include/rm_policyloc.h
new file mode 100644 (file)
index 0000000..a1471b8
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  file  rm_policyloc.h
+ *
+ *  Prototypes and data structures for the Resource Manager Policies.
+ *
+ *  ============================================================================
+ *      (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
+*/
+
+#ifndef RM_POLICYLOC_H_
+#define RM_POLICYLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* RM external API includes */
+#include <ti/drv/rm/rm_policy.h>
+
+/* 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;
+
+typedef struct {
+    const void *rangeData;
+    int32_t rangeLen;
+    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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RM_POLICYLOC_H_ */
+
diff --git a/rm.h b/rm.h
index 04f4b05b397a82481775711f7c51a9930ed1e588..832395d99a74dee5e3e22cb7ae14ac47ef176667 100644 (file)
--- a/rm.h
+++ b/rm.h
@@ -191,7 +191,7 @@ typedef struct {
      *  Note: This parameter will be ignored when the instance type is either 
      *  Client Delegate or Client */
     void *linuxDtb;    
-    /** [Server/Client Delegate Paramter] Pointer to the startup allocation
+    /** [Server/Client Delegate Paramter] Pointer to the allocation
      *  policy.  RM Servers should be initialized with the global policy 
      *  listing for all RM instances within the system.  RM Client Delegates 
      *  can be initialized with their local policy, must be a subset of the 
@@ -204,7 +204,7 @@ typedef struct {
      *  Note: This parameter will be ignored when the instance type is a 
      *        Client 
      */
-    void *startupPolicy;
+    void *policy;
 } Rm_InitCfg;
 
 /* TESTING PURPOSES: SERVER ONLY */
index 224bd33bb74a180e1c33b819fb082111152b8382..88eabc9923f40cfb18f8765a714fcc574c525939 100644 (file)
@@ -87,8 +87,22 @@ extern "C" {
 /** No free resource ranges could be found that satisfy the resource base, length, and
  *  alignment requirements */
 #define RM_SERVICE_DENIED_RESOURCE_ALLOCATION_REQUIREMENTS_COULD_NOT_BE_SATISFIED (RM_SERVICE_DENIED_BEGIN+6)
+/** The RM instance requesting the service is not defined in the policy */
+#define RM_SERVICE_DENIED_RM_INST_NOT_DEFINED_IN_POLICY (RM_SERVICE_DENIED_BEGIN+7)
+/** The resource in the service request is not defined in the policy */
+#define RM_SERVICE_DENIED_RESOURCE_NOT_DEFINED_IN_POLICY (RM_SERVICE_DENIED_BEGIN+8)
+/** The resource has multiple assigned range definitions */
+#define RM_SERVICE_DENIED_ASSIGNED_RANGE_SPECIFICATION_ERROR (RM_SERVICE_DENIED_BEGIN+9)
+/** The resource has multiple allocation size definitions */
+#define RM_SERVICE_DENIED_ALLOCATION_SIZE_SPECIFICATION_ERROR (RM_SERVICE_DENIED_BEGIN+10)
+/** The resource has multiple assigned name definitions */
+#define RM_SERVICE_DENIED_ASSIGNED_NAME_SPECIFICATION_ERROR (RM_SERVICE_DENIED_BEGIN+11)
+/** The resource has multiple allocation alignment definitions */
+#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)
 /** End of resource denied reasons */
-#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+5)
+#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+13)
 
 /** RM Service Request Error Code Base */
 #define RM_SERVICE_ERROR_BASE (-64)
index 2f99160d23698914c46af4a60bbb1dec93d4cea9..db537518ce2d344eb0d32f5834fa493e4d124631 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -54,6 +54,7 @@
 #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
+#include <ti/drv/rm/include/rm_policyloc.h>\r
 \r
 /* RM LIBFDT includes */\r
 #include <ti/drv/rm/src/libfdt/libfdt.h>\r
@@ -2076,11 +2077,11 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
     \r
     /* Get memory for RM instance from local memory */\r
     rmInst = Rm_osalMalloc (sizeof(Rm_Inst));\r
+    memset ((void *) rmInst, 0, 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
@@ -2096,6 +2097,9 @@ 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
+\r
     /* Initialize the transaction queue elements. */\r
     rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
     rmInst->transactionQueue= NULL;\r
@@ -2124,17 +2128,11 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
         }\r
     }\r
 \r
-    /* Instance startup policies are only used for Servers and Client Delegates */\r
-    if (rmInst->instType != Rm_instType_CLIENT)\r
+    /* Open the instance's policy and store it.  Instance policies are only used for Servers and \r
+     * Client Delegates */\r
+    if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy)\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
+        Rm_policyInit(rmInst, initCfg->policy);\r
     }\r
 \r
     /* Return the RM Handle */\r
index 2275dd0ebd359629dbe49913394341969028b876..acb353c12d60a0853bf724115855703f48589eaf 100644 (file)
@@ -147,6 +147,65 @@ void Rm_commonFreeRangeList(Rm_ResourceRange *rangeList)
     }
 }
 
+/* Construct and return a list of values as specified in the Policy DTB */
+Rm_ResourceValue *Rm_commonExtractValueList(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+    uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
+    Rm_ResourceValue *startValue = NULL;
+    Rm_ResourceValue *newValue = NULL;
+    Rm_ResourceValue *prevValue = NULL;
+    uint32_t i;
+    
+    /* Values are stored in the DTB as a list of 32-bit words. The DTB 
+     * gives properties lengths in bytes so the length returned from the DTB 
+     * should be a multiple of the number of bytes a uint32_t. */
+    if (dtbDataLen % sizeof(uint32_t))
+    {
+        return (NULL);
+    }
+
+    /* Extract the value data from the DTB */
+    for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
+    {
+        /* Creat a new allocation size entry */
+        newValue = (Rm_ResourceValue *) Rm_osalMalloc(sizeof(Rm_ResourceValue));
+        /* Populate the new allocation size entry.  The endianness of the value extracted must
+         * be flipped */
+        newValue->value = fdt32_to_cpu(dtbRangeData[i]);
+        newValue->nextValue = NULL;
+        
+        /* Resource value linked list pointer accounting */
+        if (prevValue == NULL)
+        {
+            /* Save the first entry so it can be returned */
+            startValue = newValue;
+        }
+        else
+        {
+            prevValue->nextValue = (void *) newValue;
+        }
+
+        prevValue = newValue;
+    }
+
+    /* Return a pointer to the start of the resource value list */
+    return (startValue);
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted values */
+void Rm_commonFreeValueList (Rm_ResourceValue *valueList)
+{
+    Rm_ResourceValue *nextValue;
+    
+    while (valueList != NULL)
+    {
+        nextValue = valueList->nextValue;
+        Rm_osalFree((void *)valueList, sizeof(Rm_ResourceValue));
+        valueList = nextValue;
+    }
+}
+
+
 /**********************************************************************
  ***********Resource List DTB Parsing Defines and Functions************
  **********************************************************************/
@@ -412,46 +471,35 @@ 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 rmPolicyPolicyTypeProp[] = "policy-type";
-char rmPolicyAssignedRangesProp[] = "assigned-ranges";
-char rmPolicyAllocationSizesProp[] = "allocation-sizes";
-char rmPolicyAssignedNsNamesProp[] = "assigned-ns-names";
+char rmPolicyAssignedRanges[] = "assigned-ranges";
+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(rmPolicyPolicyTypeProp, propertyName) == 0)
+    if(strcmp(rmPolicyAssignedRanges, propertyName) == 0)
     {
-        propertyType = Rm_policyPropType_POLICY_TYPE;
-    } 
-    else if(strcmp(rmPolicyAssignedRangesProp, propertyName) == 0)
-    {
-        propertyType = Rm_policyPropType_RESOURCE_ASSIGNED_RANGES;
+        propertyType = Rm_policyPropType_ASSIGNED_RANGES;
     }
-    else if(strcmp(rmPolicyAllocationSizesProp, propertyName) == 0)
+    else if(strcmp(rmPolicyAllocationSizes, propertyName) == 0)
     {
-        propertyType = Rm_policyPropType_RESOURCE_ALLOCATION_SIZES;
+        propertyType = Rm_policyPropType_ALLOCATION_SIZES;
     }
-    else if(strcmp(rmPolicyAssignedNsNamesProp, propertyName) == 0)
+    else if(strcmp(rmPolicyAssignedNames, propertyName) == 0)
     {
-        propertyType = Rm_policyPropType_ASSIGNED_NS_NAMES;
+        propertyType = Rm_policyPropType_ASSIGNED_NAMES;
     }
+    else if(strcmp(rmPolicyAllocationAlignments, propertyName) == 0)
+    {
+        propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENTS;
+    }    
 
     return (propertyType);
 }
 
-/* MODIFY TO RETURN A POLICY TYPE INSTEAD OF A STRING??? */
-char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen)
-{
-    return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
-}
-
-void Rm_policyFreePolicyType(char *policyType)
-{
-    Rm_commonFreeName(policyType);
-}
-
 Rm_ResourceRange *Rm_policyExtractAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen)
 {
     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
@@ -463,65 +511,19 @@ void Rm_policyFreeAssignedRanges(Rm_ResourceRange *rangeList)
 }
 
 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
-Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
+Rm_ResourceValue *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
 {
-    uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
-    Rm_AllocationSize *startAllocationSize = NULL;
-    Rm_AllocationSize *newAllocationSize = NULL;
-    Rm_AllocationSize *prevAllocationSize = NULL;
-    uint32_t i;
-    
-    /* Allocation sizes are stored in the DTB as a list of 32-bit words. The DTB 
-     * gives properties lengths in bytes so the length returned from the DTB 
-     * should be a multiple of the number of bytes a uint32_t. */
-    if (dtbDataLen % sizeof(uint32_t))
-    {
-        return (NULL);
-    }
-
-    /* Extract the allocation size data from the DTB */
-    for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
-    {
-        /* Creat a new allocation size entry */
-        newAllocationSize = (Rm_AllocationSize *) Rm_osalMalloc(sizeof(Rm_AllocationSize));
-        /* Populate the new allocation size entry.  The endianness of the value extracted must
-         * be flipped */
-        newAllocationSize->allocationSize = fdt32_to_cpu(dtbRangeData[i]);
-        newAllocationSize->nextAllocationSize = NULL;
-        
-        /* Allocation size linked list pointer accounting */
-        if (prevAllocationSize == NULL)
-        {
-            /* Save the first entry so it can be returned */
-            startAllocationSize = newAllocationSize;
-        }
-        else
-        {
-            prevAllocationSize->nextAllocationSize = (void *) newAllocationSize;
-        }
-
-        prevAllocationSize = newAllocationSize;
-    }
-
-    /* Return a pointer to the start of the allocation size list */
-    return (startAllocationSize);
+    return(Rm_commonExtractValueList(dtbDataPtr, dtbDataLen));
 }
 
 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
-void Rm_policyFreeAllocationSizesList (Rm_AllocationSize *allocationSizeList)
+void Rm_policyFreeAllocationSizes (Rm_ResourceValue *allocationSizeList)
 {
-    Rm_AllocationSize *nextAllocationSize;
-    
-    while (allocationSizeList != NULL)
-    {
-        nextAllocationSize = allocationSizeList->nextAllocationSize;
-        Rm_osalFree((void *)allocationSizeList, sizeof(Rm_AllocationSize));
-        allocationSizeList = nextAllocationSize;
-    }
+    Rm_commonFreeValueList(allocationSizeList);
 }
 
 /* Construct and return a list of assigned NameServer names as specified in the Policy DTB */
-Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int32_t dtbDataLen)
+Rm_AssignedNsNames *Rm_policyExtractAssignedNames(const void *dtbDataPtr, int32_t dtbDataLen)
 {
     uint8_t *dtbAssignedNsNamesData = (uint8_t *)dtbDataPtr;
     uint32_t nameLenBytes;        
@@ -565,7 +567,7 @@ Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int3
 
 /* Function to clean up the memory allocated for a linked list of extracted 
  * assigned NameServer names. */
-void Rm_policyFreeAssignmentNsNamesList (Rm_AssignedNsNames *assignedNsNamesList)
+void Rm_policyFreeAssignmentNames (Rm_AssignedNsNames *assignedNsNamesList)
 {
     Rm_AssignedNsNames *nextAssignedName;
     int32_t nameSize;
@@ -583,6 +585,18 @@ void Rm_policyFreeAssignmentNsNamesList (Rm_AssignedNsNames *assignedNsNamesList
     }
 }
 
+/* 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 07525a7a148e2baaa38005b7d071e88400f533e6..178e3f1ec293804f336e9cdcae8a0417f54741be 100644 (file)
 
 /* RM external API includes */
 #include <ti/drv/rm/rm_policy.h>
+#include <ti/drv/rm/rm_services.h>
 
 /* RM internal API includes */
-//#include <ti/drv/rm/include/rm_policyloc.h>
+#include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_policyloc.h>
 #include <ti/drv/rm/include/rm_dtb_utilloc.h>
 
 /* RM LIBFDT includes */
 /* RM OSAL layer */
 #include <rm_osal.h>
 
+/**********************************************************************
+ ************** Red-Black BBST Tree NameServer Functions **************
+ **********************************************************************/
+
+Rm_PolicyInstNode *Rm_newPolicyInstNode(const char *instName, int32_t nodeOffset)
+{
+    Rm_PolicyInstNode *newNode = NULL;
+
+    newNode = Rm_osalMalloc(sizeof(Rm_PolicyInstNode));
+
+    /* Populate the node */
+    strcpy(newNode->instName, instName);
+    newNode->nodeOffset = nodeOffset;
+    
+    return(newNode);
+}
+
+void Rm_freePolicyInstNode(Rm_PolicyInstNode *node)
+{
+    /* Free the memory associated with the tree node. */
+    Rm_osalFree((void *)node, sizeof(Rm_PolicyInstNode));
+}
+
+/* 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)
+{
+    return(strcmp(element1->instName, element2->instName));
+}
+
+/* Generate the red-black tree manipulation functions */
+RB_GENERATE(_Rm_PolicyInstLookupTree, _Rm_PolicyInstNode, linkage, Rm_PolicyInstNodeCompare);
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+/* 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)
+        {
+            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);
+            }            
+        }
+        
+        /* 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 */
+}
+
+int32_t Rm_policyCheck(Rm_PolicyHandle policyDtb, Rm_PolicyCheckInfo *checkInfo,
+                       Rm_PolicyNodeProperties *nodeProperties)
+{
+
+}
+
+int32_t Rm_policyCheckResource(Rm_Inst *rmInst, Rm_PolicyCheckInfo *checkInfo)
+{
+    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;
+    const char *nodeName;
+    Rm_PolicyNodeProperties nodeProps;  
+       int32_t propertyLen;
+       const void *propertyData;
+    Rm_PolicyPropType propertyType;    
+    int32_t retVal = RM_SERVICE_PROCESSING;
+
+    /* 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);
+
+    if (matchingNode)
+    {
+        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 */
+
+            /* Get the properties for the resource node if any exist */
+           nodeOffset = fdt_first_property_offset(policyDataPtr->policyDtb, nodeOffset);
+
+            while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (retVal == RM_SERVICE_PROCESSING))
+            {
+                /* 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)
+                {
+                    if (nodeProps.alignmentData || nodeProps.alignmentLen)
+                    {
+                        /* 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;
+                    }
+                    else
+                    {
+                        nodeProps.alignmentData = propertyData;
+                        nodeProps.alignmentLen = propertyLen;
+                    }
+                }                  
+                else
+                {
+                    retVal = RM_SERVICE_DENIED_UNKNOWN_POLICY_PROPERTY;
+                }
+
+                nodeOffset = fdt_next_property_offset(policyDataPtr->policyDtb, nodeOffset);
+            }
+        }
+
+        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);
+}
+
+void Rm_policyInit(Rm_Inst *rmInst, void *policyDtb)
+{
+    Rm_PolicyData *policyDataPtr;
+    
+    /* Allocate memory for the policy data structure */
+    policyDataPtr = Rm_osalMalloc(sizeof(Rm_PolicyData));
+    
+    /* 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);
+
+    /* Store the policy in the RM instance */
+    rmInst->policyData = (void *) policyDataPtr;
+}
+
+
index 60420ae5674defc72a7d329ec7c5b9fa03604416..92cecedd9dc44dd2865188a1e9d1c3e602f31fe9 100644 (file)
@@ -1232,7 +1232,7 @@ Int main(Int argc, Char* argv[])
         /* Open the Global Resource and Policy DTB files */
         globalResourceFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-global-resources.dtb", "rb");
         linuxDtbFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-linux-evm.dtb", "rb");
-        globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\global-policy.dtb", "rb");
+        globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-server-policy.dtb", "rb");
 
         /* Get the size of the Global Resource List, Linux DTB, and Global Policy */
         fseek(globalResourceFp, 0, SEEK_END);
@@ -1266,7 +1266,7 @@ Int main(Int argc, Char* argv[])
         /* Provide the DTBs to the RM Server */
         rmInitCfg.globalResourceList = globalResourceList;
         rmInitCfg.linuxDtb = linuxDtb;
-        rmInitCfg.startupPolicy = globalPolicy;
+        rmInitCfg.policy = globalPolicy;
 
         /* Get the RM Server handle */
         rmServerHandle = Rm_init(&rmInitCfg);
@@ -1281,7 +1281,7 @@ Int main(Int argc, Char* argv[])
         rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
         /* SET TO NULL - FEATURES NOT ADDED YET */
         rmInitCfg.globalResourceList = NULL;
-        rmInitCfg.startupPolicy = NULL;
+        rmInitCfg.policy = NULL;
 
         /* Get the RM Client Delegate handle */
         rmClientDelegateHandle = Rm_init(&rmInitCfg);
@@ -1292,7 +1292,7 @@ Int main(Int argc, Char* argv[])
         rmInitCfg.instType = Rm_instType_CLIENT;
         /* SET TO NULL - FEATURES NOT ADDED YET */
         rmInitCfg.globalResourceList = NULL;
-        rmInitCfg.startupPolicy = NULL;
+        rmInitCfg.policy = NULL;
 
         /* Get the RM Client handle */
         rmClientHandle = Rm_init(&rmInitCfg);