summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 020af6d)
raw | patch | inline | side by side (parent: 020af6d)
author | Justin Sobota <jsobota@ti.com> | |
Mon, 7 Jan 2013 19:40:51 +0000 (14:40 -0500) | ||
committer | Justin 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] | patch | blob | history |
device/tci6614-server-policy.dtb | [new file with mode: 0644] | patch | blob |
device/tci6614-server-policy.dts | [new file with mode: 0644] | patch | blob |
include/rm_dtb_utilloc.h | patch | blob | history | |
include/rm_loc.h | patch | blob | history | |
include/rm_policyloc.h | [new file with mode: 0644] | patch | blob |
rm.h | patch | blob | history | |
rm_services.h | patch | blob | history | |
src/rm.c | patch | blob | history | |
src/rm_dtb_util.c | patch | blob | history | |
src/rm_policy.c | patch | blob | history | |
test/rm_test.c | patch | blob | history |
diff --git a/device/tci6614-global-policy.dts.old b/device/tci6614-global-policy.dts.old
+++ /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
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
--- /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)
--- a/include/rm_dtb_utilloc.h
+++ b/include/rm_dtb_utilloc.h
void *nextRange;
} Rm_ResourceRange;
+typedef struct {
+ uint32_t value;
+ void *nextValue;
+} Rm_ResourceValue;
+
/**********************************************************************
***********Resource List DTB Parsing Defines and Functions************
**********************************************************************/
***************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***************
diff --git a/include/rm_loc.h b/include/rm_loc.h
index 057942e8ac0b45e6e5482b66b01260b4f73a61f5..366a1788cc1821023fca60863a07e75020c938d3 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
/* 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 */
/** 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
*/
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
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
--- /dev/null
+++ b/include/rm_policyloc.h
@@ -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_ */
+
index 04f4b05b397a82481775711f7c51a9930ed1e588..832395d99a74dee5e3e22cb7ae14ac47ef176667 100644 (file)
--- a/rm.h
+++ b/rm.h
* 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
* Note: This parameter will be ignored when the instance type is a
* Client
*/
- void *startupPolicy;
+ void *policy;
} Rm_InitCfg;
/* TESTING PURPOSES: SERVER ONLY */
diff --git a/rm_services.h b/rm_services.h
index 224bd33bb74a180e1c33b819fb082111152b8382..88eabc9923f40cfb18f8765a714fcc574c525939 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
/** 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)
diff --git a/src/rm.c b/src/rm.c
index 2f99160d23698914c46af4a60bbb1dec93d4cea9..db537518ce2d344eb0d32f5834fa493e4d124631 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
#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
\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
* 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
}\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
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index 2275dd0ebd359629dbe49913394341969028b876..acb353c12d60a0853bf724115855703f48589eaf 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
}
}
+/* 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************
**********************************************************************/
/* 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));
}
/* 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***************
**********************************************************************/
diff --git a/src/rm_policy.c b/src/rm_policy.c
index 07525a7a148e2baaa38005b7d071e88400f533e6..178e3f1ec293804f336e9cdcae8a0417f54741be 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
/* 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;
+}
+
+
diff --git a/test/rm_test.c b/test/rm_test.c
index 60420ae5674defc72a7d329ec7c5b9fa03604416..92cecedd9dc44dd2865188a1e9d1c3e602f31fe9 100644 (file)
--- a/test/rm_test.c
+++ b/test/rm_test.c
/* 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);
/* 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);
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);
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);