diff --git a/src/rm_policy.c b/src/rm_policy.c
index f741468a790a287ea4a515abbc289e2ba196fd14..e870a5fab9eb9f57e52f5b61d81b582162b737e6 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
/* RM LIBFDT includes */
#include <ti/drv/rm/src/libfdt/libfdt.h>
+/* AVL BBST includes */
+#include <ti/drv/rm/include/tree.h>
+
/* RM OSAL layer */
#include <rm_osal.h>
+/**********************************************************************
+ ************************** Globals ***********************************
+ **********************************************************************/
+
char Rm_policyAllInstances[] = "*";
-int32_t Rm_policyCheckInstances(Rm_PolicyValidInst *validInstList,
+/**********************************************************************
+ ************ Red-Black BBST Tree Valid Instance Functions ************
+ **********************************************************************/
+Rm_ValidInstNode *Rm_newValidInstNode(char *instName)
+{
+ Rm_ValidInstNode *newNode = NULL;
+
+ newNode = Rm_osalMalloc(sizeof(Rm_ValidInstNode));
+
+ strcpy(newNode->name, instName);
+ newNode->allocRefCount = 0;
+ newNode->deletePending = FALSE;
+
+ return(newNode);
+}
+
+void Rm_freeValidInstNode(Rm_ValidInstNode *node)
+{
+ if (node->allocRefCount == 0) {
+ Rm_osalFree((void *)node, sizeof(Rm_ValidInstNode));
+ }
+}
+
+/* Prototype for tree node comparison function
+ * element1 < element2 --> return < 0
+ * element1 = element2 --> return 0
+ * element1 > element2 --> return > 0 */
+int Rm_ValidInstNodeCompare(Rm_ValidInstNode *element1, Rm_ValidInstNode *element2)
+{
+ return(strcmp(element1->name, element2->name));
+}
+
+/* Generate the red-black tree manipulation functions */
+RB_GENERATE(_Rm_ValidInstTree, _Rm_ValidInstNode, linkage, Rm_ValidInstNodeCompare);
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+int32_t Rm_policyCheckInstances(Rm_ValidInstTree *root,
Rm_PolicyPermission *permissionsList)
{
- Rm_PolicyValidInst *validInst = validInstList;
Rm_PolicyPermission *permission = permissionsList;
- bool instNameMatch = FALSE;
+ bool instNameMatch = FALSE;
- /* Check each instance name in the permission list against the list of valid instance
- * names. Return an error if any permission instance name is not in the valid instance
- * name list */
- while (permission)
- {
- /* Instantly declare a name match if the permission's instance name is the "all"
- * wildcard */
- if (strcmp(permission->instName, Rm_policyAllInstances) == 0)
- {
+ while (permission) {
+ if (strcmp(permission->instName, Rm_policyAllInstances) == 0) {
instNameMatch = TRUE;
}
- else
- {
- while (validInst)
- {
- if (strcmp(permission->instName, validInst->instName) == 0)
- {
+ else if (Rm_policyGetValidInstNode(root, permission->instName)) {
instNameMatch = TRUE;
- }
- validInst = validInst->nextValidInst;
- }
}
- if (!instNameMatch)
- {
+ if (!instNameMatch) {
return(RM_INIT_ERROR_POLICY_UNKNOWN_INSTANCE);
}
- /* Get the next permission and reset to the beginning of the valid instance list */
permission = permission->nextPermission;
- validInst = validInstList;
instNameMatch = FALSE;
}
@@ -119,7 +146,8 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
uint32_t instNameIndex;
bool foundInstName;
bool instNameComplete;
- bool foundAssignment;
+ bool assignmentLeft;
+ bool assignmentRight;
/* Create a local copy of the sub-permission string */
permStrPtr = Rm_osalMalloc(permStrLen);
@@ -145,31 +173,27 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
* 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;
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_INSTANCE_GROUP;
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;
+ permStrPtr = subgroupStart + 1;
instNameIndex = 0;
foundInstName = FALSE;
instNameComplete = FALSE;
- while (permStrPtr <= subgroupEnd)
- {
+ while (permStrPtr <= subgroupEnd) {
if ((isspace(*permStrPtr) || (*permStrPtr == RM_POLICY_PERM_SUBGROUP_END))
- && foundInstName)
- {
+ && 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)
- {
+ else {
+ if (!foundInstName) {
/* First non-whitespace character encountered is the start of an
* instance name */
foundInstName = TRUE;
@@ -179,21 +203,18 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
instNameTemp[instNameIndex++] = *permStrPtr;
}
- if (instNameComplete)
- {
+ 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)
- {
+ if (prevPerm == NULL) {
/* Save the first instance so it can be returned */
startPerm = newPerm;
}
- else
- {
+ else {
prevPerm->nextPermission = (void *) newPerm;
}
prevPerm = newPerm;
@@ -208,220 +229,187 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
/* Fill in the permissions for each instance name */
- /* Look on left of instance group for the permission assignments. */
- permStrPtr = subgroupStart;
- foundAssignment = FALSE;
+ /* Look on left of instance group for permission assignments. */
+ permStrPtr = subgroupStart - 1;
+ assignmentLeft = FALSE;
while (permStrPtr >= permStrStart)
{
- if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT)
- {
- if (foundAssignment)
- {
+ if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
+ if (assignmentLeft) {
/* 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)
- {
+ 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);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
- else
- {
- foundAssignment = TRUE;
+ else {
+ assignmentLeft = TRUE;
}
}
- else if (!isspace(*permStrPtr))
- {
- if (foundAssignment)
- {
+ else if (!isspace(*permStrPtr)) {
+ if (assignmentLeft) {
if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
- {
- /* Set the init permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
- {
- /* Set the use permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
- {
- /* Set the exclusive permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER))
- {
- /* Set the shared Linux permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
- else
- {
+ else {
/* Invalid permission character. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ 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);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
+ return(NULL);
}
}
- else
- {
+ 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)
- {
+ 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);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_PERM_CHAR_WITHOUT_ASSIGN_CHAR;
+ 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)
- {
+ /* Look on right of instance group for permission assignments. */
+ permStrPtr = subgroupEnd + 1;
+ while (permStrPtr < permStrEnd) {
+ if (assignmentLeft && (!isspace(*permStrPtr))) {
+ /* There should be nothing but spaces on right if assignment was already found on left */
+ 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_INVALID_CHAR_ON_RIGHT_WITH_ASSINMENT_ON_LEFT;
+ return(NULL);
+ }
+
+ if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
+ if (assignmentRight) {
/* 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)
- {
+ 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);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
- else
- {
- foundAssignment = TRUE;
+ else {
+ assignmentRight = TRUE;
}
}
- else if (!isspace(*permStrPtr))
- {
- if (foundAssignment)
- {
+ else if (!isspace(*permStrPtr)) {
+ if (assignmentRight) {
if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
- {
- /* Set the init permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
- {
- /* Set the use permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
- {
- /* Set the exclusive permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER))
- {
- /* Set the shared Linux permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
- else
- {
+ else {
/* Invalid permission character. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ 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);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
+ return(NULL);
}
}
- else
- {
+ 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)
- {
+ 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);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
}
permStrPtr++;
{
Rm_PolicyPermission *nextPerm;
- while (permissionList != NULL)
- {
+ while (permissionList != NULL) {
nextPerm = permissionList->nextPermission;
- /* Free the list element */
Rm_osalFree((void *)permissionList, sizeof(Rm_PolicyPermission));
permissionList = nextPerm;
}
@@ -455,12 +441,10 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
uint32_t permStrLen = strlen(assignment->permissionsList) + 1;
uint32_t i = 0;
- while(i < permStrLen)
- {
+ 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)))
- {
+ 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);
@@ -468,28 +452,24 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
newPerm = Rm_policyParseSubPermission(permStrStart, permStrEnd, result);
- if (*result != RM_INIT_OK)
- {
+ 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);
}
- if (prevPerm == NULL)
- {
+ if (prevPerm == NULL) {
/* Save the first sub-permission in the list so it can be returned */
startPerm = newPerm;
}
- else
- {
+ else {
prevPerm->nextPermission = newPerm;
}
/* Set prevPerm to the last sub-permission returned by the sub-permission parser */
prevPerm = newPerm;
- while(prevPerm->nextPermission != NULL)
- {
+ while(prevPerm->nextPermission != NULL) {
prevPerm = prevPerm->nextPermission;
}
@@ -500,33 +480,24 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
}
*result = RM_INIT_OK;
- /* Return a pointer to the start of the permissions list */
return(startPerm);
}
-int32_t Rm_policyValidateAssignmentPermissions(Rm_PolicyValidInst *validInstList,
+int32_t Rm_policyValidateAssignmentPermissions(Rm_ValidInstTree *root,
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 */
+ while (assignment) {
+ /* Make sure assignment's permissions parse okay */
permissionList = Rm_policyGetAssignmentPermissions(assignment, &result);
- if (result != RM_INIT_OK)
- {
+ 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)
- {
+ if (result = Rm_policyCheckInstances(root, permissionList) != RM_INIT_OK) {
Rm_policyFreeAssignmentPermissions(permissionList);
return(result);
}
@@ -538,111 +509,143 @@ int32_t Rm_policyValidateAssignmentPermissions(Rm_PolicyValidInst *validInstList
return (RM_INIT_OK);
}
+void Rm_policyIncrementValidInstAllocationCount(void *validInstNameNode)
+{
+ Rm_ValidInstNode *node = (Rm_ValidInstNode *)validInstNameNode;
+
+ node->allocRefCount++;
+}
+
+void Rm_policyDecrementValidInstAllocationCount(void *validInstNameNode)
+{
+ Rm_ValidInstNode *node = (Rm_ValidInstNode *)validInstNameNode;
+
+ node->allocRefCount--;
+}
+
+void *Rm_policyGetValidInstNode(void *validInstTree, char *instName)
+{
+ Rm_ValidInstTree *root = (Rm_ValidInstTree *)validInstTree;
+ Rm_ValidInstNode findNode;
+
+ memset((void *)&findNode, 0, sizeof(Rm_ValidInstNode));
+ strcpy(findNode.name, instName);
+
+ return (RB_FIND(_Rm_ValidInstTree, root, &findNode));
+}
+
+char *Rm_policyGetValidInstNodeName(void *validInstNode)
+{
+ Rm_ValidInstNode *node = validInstNode;
+
+ return (node->name);
+}
+
+void *Rm_policyGetLinuxInstNode(void * validInstTree)
+{
+ char linuxName[] = RM_ALLOCATED_TO_LINUX;
+
+ return (Rm_policyGetValidInstNode(validInstTree, linuxName));
+}
+
+/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb)
{
- int32_t nodeOffset;
- int32_t propertyOffset;
- int32_t depth;
- const char *nodeName;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_PolicyPropType propertyType;
- Rm_PolicyValidInst *validInstList;
+ int32_t nodeOffset;
+ int32_t propertyOffset;
+ int32_t depth;
+ const char *nodeName;
+ const char *propertyName;
+ int32_t propertyLen;
+ const void *propertyData;
+ Rm_PolicyPropType propertyType;
Rm_PolicyAssignment *assignmentList;
- int32_t result;
+ int32_t result;
depth = RM_DTB_UTIL_STARTING_DEPTH;
nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
- /* 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)
- {
- 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);
-
- /* 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))
- {
+ /* Parse DTB, verifying each resource's assignment permissions.
+ * Permissions must have correct syntax and contain valid instance names
+ * according 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);
-
- /* 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)
- {
- Rm_policyFreeValidInstances(validInstList);
+ if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL) {
+ /* No allocator tied to resource name */
return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
}
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET)
- {
- /* Get the assignment data */
+ while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
-
propertyType = Rm_policyGetPropertyType(propertyName);
- if (propertyType == Rm_policyPropType_ASSIGNMENTS)
- {
+ if (propertyType == Rm_policyPropType_ASSIGNMENTS) {
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)
- {
- Rm_policyFreeValidInstances(validInstList);
+ if ((result = Rm_policyValidateAssignmentPermissions((Rm_ValidInstTree *) rmInst->validInstances,
+ assignmentList)) != RM_INIT_OK) {
Rm_policyFreeAssignments(assignmentList);
return(result);
}
-
Rm_policyFreeAssignments(assignmentList);
}
-
propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
}
}
}
-
- Rm_policyFreeValidInstances(validInstList);
return(RM_INIT_OK);
}
-/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
-int32_t Rm_policyInit(Rm_Inst *rmInst, void *policyDtb)
+void *Rm_policyCreateValidInstTree(void *policyDtb, int32_t *result)
{
- 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));
-
- /* 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;
+ int32_t validInstOffset;
+ const char *validInstName;
+ int32_t validInstLen;
+ const void *validInstData;
+ Rm_PolicyPropType propertyType;
+ Rm_PolicyValidInst *validInstList;
+ Rm_ValidInstTree *rootEntry = NULL;
+ Rm_ValidInstNode *newNode;
+ char linuxName[] = RM_ALLOCATED_TO_LINUX;
+
+ /* Valid instance list must be first and only property in the root node of
+ * the policyDtb */
+ validInstOffset = fdt_first_property_offset(policyDtb, RM_DTB_UTIL_STARTING_NODE_OFFSET);
+ if (validInstOffset < -FDT_ERR_NOTFOUND) {
+ *result = validInstOffset;
+ return (NULL);
+ }
+ else if (validInstOffset == -FDT_ERR_NOTFOUND) {
+ *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+ return (NULL);
+ }
+ validInstData = fdt_getprop_by_offset(policyDtb, validInstOffset, &validInstName, &validInstLen);
+ propertyType = Rm_policyGetPropertyType(validInstName);
+ if (propertyType != Rm_policyPropType_VALID_INSTANCES) {
+ *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+ return (NULL);
}
+ validInstList = Rm_policyExtractValidInstances(validInstData, validInstLen);
- return(result);
-}
+ /* Create the tree */
+ rootEntry = Rm_osalMalloc(sizeof(Rm_ValidInstTree));
+ RB_INIT(rootEntry);
+
+ while (validInstList) {
+ newNode = Rm_newValidInstNode(validInstList->instName);
+ RB_INSERT(_Rm_ValidInstTree, rootEntry, newNode);
+
+ validInstList = validInstList->nextValidInst;
+ }
+
+ /* Add the Linux kernel node */
+ newNode = Rm_newValidInstNode(linuxName);
+ RB_INSERT(_Rm_ValidInstTree, rootEntry, newNode);
+ *result = RM_INIT_OK;
+ return ((void *)rootEntry);
+}