summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d63d9c7)
raw | patch | inline | side by side (parent: d63d9c7)
author | Justin Sobota <jsobota@ti.com> | |
Sat, 12 Jan 2013 00:23:48 +0000 (19:23 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Sat, 12 Jan 2013 00:23:48 +0000 (19:23 -0500) |
15 files changed:
device/global-policy.dtb | [deleted file] | patch | blob | history |
device/tci6614-global-resources-mixed.dts | [deleted file] | patch | blob | history |
device/tci6614-server-policy.dtb | patch | blob | history | |
device/tci6614-server-policy.dts | patch | blob | history | |
include/rm_dtb_utilloc.h | patch | blob | history | |
include/rm_loc.h | patch | blob | history | |
include/rm_nameserverloc.h | patch | blob | history | |
include/rm_policyloc.h | patch | blob | history | |
rm.h | patch | blob | history | |
rm_services.h | patch | blob | history | |
rm_types.h | patch | blob | history | |
src/rm.c | patch | blob | history | |
src/rm_dtb_util.c | patch | blob | history | |
src/rm_nameserver.c | patch | blob | history | |
src/rm_policy.c | patch | blob | history |
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
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
+++ /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
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
index d078f4b7a18412072dae9cfa7b8551a4dedd1f7a..773af792b40422b5c2b1ec3f1ecbf9b053b74f00 100644 (file)
/* 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)
--- a/include/rm_dtb_utilloc.h
+++ b/include/rm_dtb_utilloc.h
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***************
diff --git a/include/rm_loc.h b/include/rm_loc.h
index 366a1788cc1821023fca60863a07e75020c938d3..f1d651341040cc1982dcad7c9b2fc468da4d5f89 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
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)
/* 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);
diff --git a/include/rm_policyloc.h b/include/rm_policyloc.h
index a1471b81a6983302935a84171bed58277d627d9c..a7592c252dc91448d5121642f7aae90dea07bb3f 100644 (file)
--- a/include/rm_policyloc.h
+++ b/include/rm_policyloc.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;
+/* 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
}
index 832395d99a74dee5e3e22cb7ae14ac47ef176667..c9d08257e370a67a01379bd3c50ed932e09eb5ce 100644 (file)
--- a/rm.h
+++ b/rm.h
@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
*/
* 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
diff --git a/rm_services.h b/rm_services.h
index 88eabc9923f40cfb18f8765a714fcc574c525939..ce45ff1528fe359db733a50879ba6251178f63a2 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
#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)
#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
diff --git a/rm_types.h b/rm_types.h
index 4b958cd8bbc87bc8095bf1c925ddf1f549a0b617..d4ed58df7951b8505dacb77ee96b3e488ad004b5 100644 (file)
--- a/rm_types.h
+++ b/rm_types.h
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
+#include <ctype.h>
#endif /* __RMTYPES_H__ */
diff --git a/src/rm.c b/src/rm.c
index db537518ce2d344eb0d32f5834fa493e4d124631..43a54602c6e31d7fccf0fc973348f2efc818832c 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
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
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
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
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
{\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
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
* 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
* 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
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index acb353c12d60a0853bf724115855703f48589eaf..e79c430a42f668d481c0141a4b0f031446afa414 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
/* 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 */
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***************
**********************************************************************/
diff --git a/src/rm_nameserver.c b/src/rm_nameserver.c
index 20740c996e5a5da2238476955cf52fe3d0f444b0..a5c47cbffd3257c08c577ac7f0fe167af6cff915 100644 (file)
--- a/src/rm_nameserver.c
+++ b/src/rm_nameserver.c
@@ -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);
}
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);
}
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;
}
diff --git a/src/rm_policy.c b/src/rm_policy.c
index 178e3f1ec293804f336e9cdcae8a0417f54741be..2118e224669270d1482fbc5bce17cd0e4fdde0a1 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
#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);
}