summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 05383cb)
raw | patch | inline | side by side (parent: 05383cb)
author | Justin Sobota <jsobota@ti.com> | |
Mon, 1 Jun 2015 21:54:00 +0000 (17:54 -0400) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Mon, 1 Jun 2015 21:54:00 +0000 (17:54 -0400) |
index e4735b9aa186eb5a40f1755bbc2dc07ede3866f8..842d2c0e3a7f2d63fd73b9e0b821498f1e5b1360 100644 (file)
/* Allocator operation configuration structure */
typedef struct {
- /* Pointer to policy used for validation of allocator operation */
- void *policy;
/* RM instance for which the allocator operation is taking place */
- Rm_PolicyValidInstNode *serviceSrcInstNode;
+ Rm_PolicyValidInstNode *serviceInstNode;
/* Allocator operation type */
Rm_AllocatorOp operation;
/* Resources for which the allocator operation will affect */
Rm_ResourceInfo *resourceInfo;
} Rm_AllocatorOpInfo;
-int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName,
- Rm_ResourceRange *range);
-Rm_AllocatorTree *rmAllocatorGetTree(Rm_Handle rmHandle);
Rm_AllocatorNode *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName);
int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName,
int32_t *resBase, uint32_t *resLen);
int32_t rmAllocatorOperation(Rm_Handle rmHandle, Rm_AllocatorOpInfo *opInfo);
-int32_t rmAllocatorInitTree(Rm_Handle rmHandle);
-int32_t rmAllocatorPopulateTree(Rm_Handle rmHandle, void *globalResourceDtb,
- void *linuxDtb);
+int32_t rmAllocatorTreeInit(Rm_Handle rmHandle, void *grlDtb,
+ void *policyDtb, void *linuxDtb);
+int32_t rmAllocatorAddResNode(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
+ int32_t resBase, uint32_t resLen);
void rmAllocatorDeleteResNode(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
int32_t resBase, uint32_t resLen);
-int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName);
-void rmAllocatorDeleteTree(Rm_Handle rmHandle);
+void rmAllocatorTreeDelete(Rm_Handle rmHandle);
#ifdef __cplusplus
}
diff --git a/include/rm_loc.h b/include/rm_loc.h
index 9a8bc07566705dea8099a40c3e8cdb96487d38f3..d3ec4d659f9a2af1c3d867d456a891e575977b5f 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
/* Server-specific instance data */
typedef struct {
- /* Pointer to the global policy */
- void *globalPolicy;
- /* Policy size in bytes */
- uint32_t policySize;
- /* Pointer to root entry of valid instance tree */
- Rm_PolicyValidInstTree *validInstTree;
- /* Pointer to allocator tree */
- Rm_AllocatorTree *allocatorTree;
/* Pointer to the root entry of the NameServer */
- Rm_NameServerTree *nameServer;
+ Rm_NameServerTree *nameServer;
} Rm_ServerInstData;
-/* Client Delegate-specific instance data */
-typedef struct {
- /* Pointer to the cd policy if provided */
- void *cdPolicy;
- /* Pointer to root entry of valid instance tree
- * extracted from cd policy */
- Rm_PolicyValidInstTree *validInstTree;
- /* Pointer to allocator tree */
- Rm_AllocatorTree *allocatorTree;
-} Rm_ClientDelegateInstData;
-
-/* Client-specific instance data */
-typedef struct {
- /* Pointer to the static policy if provided */
- void *staticPolicy;
- /* Pointer to the root entry of the valid instance tree
- * extracted from the static policy */
- Rm_PolicyValidInstTree *staticValidInstTree;
-} Rm_ClientInstData;
-
/* Shared Client-specific instance data */
typedef struct {
/* Shared Server instance handle */
typedef struct {
/* Name given to the RM instance. Policy will assign resources based
* on the names assigned to instances at instance init */
- char instName[RM_NAME_MAX_CHARS];
+ char instName[RM_NAME_MAX_CHARS];
/* Instance type */
- Rm_InstType instType;
+ Rm_InstType instType;
/* Instance lock status. Instance locks if static request fails when
* checked against global policy */
- int8_t isLocked;
+ int8_t isLocked;
/* Tracks whether the instance has registered with a CD or Server.
* Applicable to CD and Client instances */
- int8_t registeredWithDelegateOrServer;
+ int8_t registeredWithDelegateOrServer;
/* Pointer to the serviceHandle opened from the instance */
- Rm_ServiceHandle *serviceHandle;
+ Rm_ServiceHandle *serviceHandle;
/* Linked list of transports registered by the application */
- Rm_Transport *transports;
+ Rm_Transport *transports;
/* Service transaction sequence number tracker */
- uint32_t transactionSeqNum;
+ uint32_t transactionSeqNum;
/* Service transaction linked list queue */
- Rm_Transaction *transactionQueue;
+ Rm_Transaction *transactionQueue;
/* Block handle provided through OSAL for when RM needs to block due to
* a service request that requires a blocking operation to complete and
* a service callback function has not been provided */
- void *blockHandle;
+ void *blockHandle;
/* Multi-threaded semaphore object */
- uint32_t *mtSemObj;
+ uint32_t *mtSemObj;
+ /* Pointer to root entry of valid instance tree */
+ Rm_PolicyValidInstTree *validInstTree;
+ /* Max valid instance index */
+ int32_t maxInstIdx;
+ /* Pointer to allocator tree */
+ Rm_AllocatorTree *allocatorTree;
/* Instance-type specific constructs */
union {
/* Server-specific instance data */
Rm_ServerInstData server;
- /* Client Delegate-specific instance data */
- Rm_ClientDelegateInstData cd;
- /* Client-specific instance data */
- Rm_ClientInstData client;
/* Shared Client-specific instance data */
Rm_SharedClientInstData sharedClient;
} u;
diff --git a/include/rm_policyloc.h b/include/rm_policyloc.h
index ca03eae4114533a71ce3c11b91ccb9c459b3bfd3..94893782ed8c25130ed7f4af8276abf94cf22175 100644 (file)
--- a/include/rm_policyloc.h
+++ b/include/rm_policyloc.h
/* RM internal includes */
#include <ti/drv/rm/include/rm_treeloc.h>
+/* Index of global permission bits in policy tree node permission array */
+#define RM_POLICY_GLOBAL_PERM_INDEX 0
+
/* String stored for resource elements that are reserved by the Linux kernel. These
* resources will be in use for the lifetime of the system
*
* instance with exclusive privilege reserves the resource
* 3 : Shared Linux (s) - Resource has been reserved by the Linux kernel but can be
* allocated by the specified RM instances
- * 4 - 15 : UNUSED
+ * 4 - 31 : UNUSED
*/
-typedef uint16_t Rm_PolicyPermBits;
+
+/* Maximum number of bits used to represent all permissions. Must be
+ * changed as new permissions are added */
+#define RM_POLICY_PERM_MAX_BITS 4
/* Initialization permission characters */
#define RM_POLICY_PERM_INIT_LOWER 'i'
/* Permissions assignment character */
#define RM_POLICY_PERM_ASSIGNMENT '='
-/* Macro to set permissions in a Rm_PolicyPermBits type */
-#define RM_policy_SET_PERM(permBits, permTypeShift, val) \
- permBits = ((permBits & (~(((Rm_PolicyPermBits) 0x1) << permTypeShift))) | \
- ((((Rm_PolicyPermBits) val) & 0x1) << permTypeShift))
-/* Macro to get permissions from Rm_PolicyPermBits type */
-#define RM_policy_GET_PERM(permBits, permTypeShift) \
- ((permBits >> permTypeShift) & 0x1)
+/* Policy bit mask */
+#define RM_policy_PERM_FULL_MASK ((1 << RM_POLICY_PERM_MAX_BITS) - 1)
+
+#define RM_policy_PERM_INST_PER_WORD \
+ ((sizeof(Rm_PolicyPermBits) * 8) / RM_POLICY_PERM_MAX_BITS)
+#define RM_policy_PERM_INDEX(instIdx) \
+ (instIdx / RM_policy_PERM_INST_PER_WORD)
+#define RM_policy_PERM_OFFSET(instIdx) \
+ ((instIdx % RM_policy_PERM_INST_PER_WORD) * \
+ RM_POLICY_PERM_MAX_BITS)
+
+#define RM_policy_PERM_SET(permArray, wordIdx, wordOffset, permOffset, val) \
+ permArray[wordIdx] &= ~(0x1 << (wordOffset + permOffset)); \
+ permArray[wordIdx] |= (val & 0x1) << (wordOffset + permOffset);
+#define RM_policy_PERM_GET(permArray, wordIdx, wordOffset, permOffset) \
+ ((permArray[wordIdx] >> (wordOffset + permOffset)) & 0x1)
/* Assigned instance permissions linked list node */
typedef struct Rm_Permission_s {
typedef struct {
/* The type of validation to perform */
Rm_PolicyCheckType type;
- /* Policy to validate the permission check against */
- void *policyDtb;
- /* Valid instance node that will have its permissions checked for
- * the defined resource */
+ /* Resource's policy tree used to validate permissions */
+ Rm_PolicyTree *polTree;
+ /* Valid instance node having its permissions checked for the resource */
Rm_PolicyValidInstNode *validInstNode;
- /* Resource node offset in the policy DTB */
- int32_t resourceOffset;
/* Resource base to validate permissions for the valid instance node */
uint32_t resourceBase;
/* Resource length to validate permissions for the valid instance node */
uint32_t resourceLength;
} Rm_PolicyCheckCfg;
-void *rmPolicyGetPolicy(Rm_Handle rmHandle);
-Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle, char *instName);
+Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle,
+ const char *instName);
Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle);
-int rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result);
-uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validInstNode,
- int32_t resourceOffset, Rm_PolicyCheckType policyCheckType,
- int32_t *result);
-uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset);
-uint32_t rmPolicyGetResourceCdAllocSize(void *policyDtb, int32_t resourceOffset);
-int32_t rmPolicyGetResourceOffset(void *policyDtb, char *resourceName);
-int32_t rmPolicyValidateResNames(Rm_Handle rmHandle);
-int32_t rmPolicyValidatePolicy(Rm_Handle rmHandle);
-Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(Rm_Handle rmHandle,
- int addLinux,
- int32_t *result);
-void rmPolicyFreeValidInstTree(Rm_Handle rmHandle);
+int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg);
+uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
+ Rm_PolicyValidInstNode *validInstNode,
+ Rm_PolicyCheckType policyCheckType);
+uint32_t rmPolicyGetAllocAlign(Rm_PolicyTree *policyTree);
+uint32_t rmPolicyGetCdAllocSize(Rm_PolicyTree *policyTree);
+Rm_PolicyValidInstTree *rmPolicyVInstTreeInit(Rm_Handle rmHandle,
+ void *policyDtb,
+ int addLinux,
+ int32_t *result);
+void rmPolicyVInstTreeDelete(Rm_Handle rmHandle);
+int32_t rmPolicyPopulateTree(Rm_Handle rmHandle, Rm_PolicyTree *policyTree,
+ void *policyDtb, const char *resName);
#ifdef __cplusplus
}
diff --git a/include/rm_treeloc.h b/include/rm_treeloc.h
index 94d63fa703a26843331574383613576e2fc8bf27..dc2f8c8930319ec31e87b3e2d9569dd9fdfccb46 100644 (file)
--- a/include/rm_treeloc.h
+++ b/include/rm_treeloc.h
/* Resource tree root entry type definition */
typedef RB_HEAD(_Rm_AllocatorResourceTree, _Rm_ResourceNode) Rm_ResourceTree;
+/* Policy permission bit storage type
+ * Bit : Description
+ *-----------------------------
+ * 0 : Init (i) - RM instance has initialization permission for resource
+ * 1 : Use (u) - RM instance has usage permission for resource
+ * 2 : Exclusive (x) - 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 : Shared Linux (s) - Resource has been reserved by the Linux kernel but can be
+ * allocated by the specified RM instances
+ * 4 - 31 : UNUSED
+ */
+typedef uint32_t Rm_PolicyPermBits;
+
/* Policy node */
typedef struct _Rm_PolicyNode {
/* Tree algorithm data structure */
uint32_t len;
/* Pointer to array containing permission bitfields for the node's
* resource range */
- uint32_t *perms;
+ Rm_PolicyPermBits *perms;
/* Size of permissions array in bytes pointed to by the perms pointer */
uint32_t permsLen;
+ /* Allocation alignment. Allocations must be aligned to a base that is a
+ * multiple of the allocation alignment */
+ uint32_t allocAlign;
+ /* Client Delegate allocation block size */
+ uint32_t cdAllocSize;
} Rm_PolicyNode;
/* Policy tree root entry type definition */
index 0083a984f4d31735b365d6b4227db53ef55dff27..8282e18690ddc8610e791d134c088b38c6fc99ba 100644 (file)
--- a/rm.h
+++ b/rm.h
/** End of libfdt.h error codes */
#define RM_ERROR_LIBFDT_END (-13)
-/** RM error base */
+/** RM error base */
#define RM_ERROR_BASE (-64)
/** Instance name provided is NULL or greater than RM_NAME_MAX_CHARS */
#define RM_ERROR_INVALID_INST_NAME RM_ERROR_BASE-1
#define RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY RM_ERROR_BASE-17
/** Could not find an allocator for the specified resource */
#define RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST RM_ERROR_BASE-18
-/** A resource node is specified more than once in the Global Resource List (GRL) */
-#define RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE RM_ERROR_BASE-19
+/** A resource node is specified more than once in either the
+ * Global Resource List (GRL) or policy. GRL for RM Server. Policy for
+ * CD or Client */
+#define RM_ERROR_RES_SPECIFIED_MORE_THAN_ONCE RM_ERROR_BASE-19
/** No data was found at the GRL resource node's specified Linux alias path */
#define RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS RM_ERROR_BASE-20
/** RM server was not provided a Global Resource List (GRL) and global policy at initialization */
/** Could not allocate the memory needed to store the root entry of the
* allocator tree */
#define RM_ERROR_COULD_NOT_INIT_ALLOC_TREE RM_ERROR_BASE-54
+/** The instance's allocator tree could not be populated because of an invalid
+ * combination of instance type, GRL, and policy. The valid combinations are:
+ * Server OR Shared Server --> Requires GRL and Policy. Optional Linux DTB
+ * Client Delegate --> Requires Policy.
+ * Client --> Optional Static Policy. */
+#define RM_ERROR_INVALID_ALLOCATOR_INIT RM_ERROR_BASE-55
+/** A resource node in the GRL does not have at least a resource range or a
+ * NameServer assignment defined. At a minimum, each node in the GRL must
+ * have a resource range or NameServer assignment */
+#define RM_ERROR_GRL_INVALID_NODE_DEF RM_ERROR_BASE-56
+/** OSAL malloc failed when allocating an allocator node's resource tree */
+#define RM_ERROR_MALLOC_FAILED_RES_TREE RM_ERROR_BASE-57
+/** OSAL malloc failed when allocating an allocator node's policy tree */
+#define RM_ERROR_MALLOC_FAILED_POL_TREE RM_ERROR_BASE-58
+/** OSAL malloc failed when allocating a resource tree node */
+#define RM_ERROR_MALLOC_FAILED_RES_NODE RM_ERROR_BASE-59
+/** A resource specified in the GRL could not be found in the policy */
+#define RM_ERROR_RES_DOES_NOT_EXIST_IN_POLICY RM_ERROR_BASE-60
-/**
+/**
* @brief Maximum number of characters allowed for RM instance, resource, and
* NameServer names.
*/
* The Linux DTB will be parsed for all managed resources reserved for use
* by Linux. Parsing will be based on "linux-dtb-alias" resource
* properties found in the GRL. The Linux DTB must be in DTB format. */
- void *linuxDtb;
+ void *linuxDtb;
/** Pointer to the global policy defining the allocation policies for
* RM instances within the system. The global policy must be in DTB
* format. */
- void *globalPolicy;
+ void *globalPolicy;
} Rm_ServerCfg;
/**
diff --git a/src/rm.c b/src/rm.c
index b96e4dd0abbe2be3658ef808d6dcfdafaeb93f60..81d3d27327cc395d740557db4a31fd7430b519a6 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
* with a Server. The allocation request is validated
* against a static policy.
*/
-static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transaction)
+static void staticAllocationHandler(Rm_Handle rmHandle,
+ Rm_Transaction *transaction)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- void *staticPolicy = rmPolicyGetPolicy(rmHandle);
+ Rm_AllocatorNode *allocNode = NULL;
Rm_PolicyCheckCfg privCheckCfg;
- int32_t result;
-
- if (staticPolicy) {
- if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+
+ if (rmInst->allocatorTree) {
+ allocNode = rmAllocatorFind(rmHandle, transaction->resourceInfo.name);
+
+ if (allocNode &&
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
(transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
/* Check request against static policy */
memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-
+
if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
privCheckCfg.type = Rm_policyCheck_INIT;
- }
- else {
+ } else {
privCheckCfg.type = Rm_policyCheck_USE;
}
- privCheckCfg.policyDtb = staticPolicy;
- privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmHandle, rmInst->instName);
- privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(staticPolicy,
- transaction->resourceInfo.name);
- privCheckCfg.resourceBase = transaction->resourceInfo.base;
+ privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmHandle,
+ rmInst->instName);
+ privCheckCfg.polTree = allocNode->policyRoot;
+ privCheckCfg.resourceBase = transaction->resourceInfo.base;
privCheckCfg.resourceLength = transaction->resourceInfo.length;
-
- if (rmPolicyCheckPrivilege(&privCheckCfg, &result)) {
+
+ if (rmPolicyCheckPrivilege(&privCheckCfg)) {
transaction->state = RM_SERVICE_APPROVED_STATIC;
- }
- else if (result == RM_OK) {
- /* Privilege check returned false without error */
+ } else {
transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
}
- else {
- /* Privilege check returned false with error */
- transaction->state = result;
- }
- }
- else {
+ } else {
transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
}
- }
- else {
+ } else {
transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
- }
+ }
}
/* FUNCTION PURPOSE: Requests resources from Server for CD
@@ -425,26 +418,32 @@ static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transac
* pending state in order to wait for the response from the
* Server
*/
-static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transaction)
+static int32_t cdRequestServerResources(Rm_Inst *rmInst,
+ Rm_Transaction *transaction)
{
- Rm_Transaction *newTrans = NULL;
- void * policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
- int32_t resourceOffsetInPolicy;
- uint32_t allocSize = 0;
- int32_t retVal;
-
- resourceOffsetInPolicy = rmPolicyGetResourceOffset(policy, transaction->resourceInfo.name);
- if (resourceOffsetInPolicy > 0) {
- if ((allocSize = rmPolicyGetResourceCdAllocSize(policy, resourceOffsetInPolicy))) {
- if ((newTrans = rmTransactionQueueAdd(rmInst))) {
+ Rm_AllocatorNode *allocNode = NULL;
+ Rm_Transaction *newTrans = NULL;
+ uint32_t allocSize = 0;
+ int32_t retVal;
+
+ allocNode = rmAllocatorFind((Rm_Handle)rmInst,
+ transaction->resourceInfo.name);
+
+ if (allocNode) {
+ if (allocSize = rmPolicyGetCdAllocSize(allocNode->policyRoot)) {
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
newTrans->type = transaction->type;
- rm_strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
- newTrans->state = RM_SERVICE_PROCESSING;
- rm_strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ rm_strncpy(newTrans->serviceSrcInstName, rmInst->instName,
+ RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ rm_strncpy(newTrans->resourceInfo.name,
+ transaction->resourceInfo.name,
+ RM_NAME_MAX_CHARS);
newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
/* Make sure request length will satisfy transaction length */
newTrans->resourceInfo.length = allocSize;
- while (newTrans->resourceInfo.length < transaction->resourceInfo.length) {
+ while (newTrans->resourceInfo.length <
+ transaction->resourceInfo.length) {
newTrans->resourceInfo.length += allocSize;
}
newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
@@ -452,18 +451,15 @@ static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transac
transactionForwarder(rmInst, newTrans);
retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
- }
- else {
+ } else {
retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
}
- }
- else {
+ } else {
/* Forward request to Server for completion if policy has
* no allocation size for resource */
retVal = RM_SERVICE_PROCESSING;
}
- }
- else {
+ } else {
/* Resource could not be found in policy */
retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
}
int32_t retVal = transaction->state;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
- opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
opInfo.resourceInfo = &transaction->resourceInfo;
- opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
- if (opInfo.serviceSrcInstNode == NULL) {
+ opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+ transaction->serviceSrcInstName);
+ if (opInfo.serviceInstNode == NULL) {
retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
goto errorExit;
- }
-
+ }
+
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
* current status (currently just owner reference count)
* for the resource specified in the transaction
*/
-static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+static void statusHandler(Rm_Inst *rmInst, Rm_Transaction *transaction)
{
Rm_AllocatorOpInfo opInfo;
Rm_NameServerObjCfg nameServerObjCfg;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
opInfo.operation = Rm_allocatorOp_GET_STATUS;
- opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
opInfo.resourceInfo = &transaction->resourceInfo;
- opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
- if (opInfo.serviceSrcInstNode == NULL) {
+ opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+ transaction->serviceSrcInstName);
+ if (opInfo.serviceInstNode == NULL) {
retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
goto errorExit;
}
goto errorExit;
}
}
- retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
}
-errorExit:
- transaction->state = retVal;
+errorExit:
+ transaction->state = retVal;
}
/* FUNCTION PURPOSE: Arbitrates free service requests
* retrieved from the NameServer prior to the free
* attempt.
*/
-static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+static void freeHandler(Rm_Inst *rmInst, Rm_Transaction *transaction)
{
Rm_AllocatorOpInfo opInfo;
- Rm_NameServerObjCfg nameServerObjCfg;
+ Rm_NameServerObjCfg nameServerObjCfg;
int32_t retVal = transaction->state;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
opInfo.operation = Rm_allocatorOp_FREE;
- opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
opInfo.resourceInfo = &transaction->resourceInfo;
- opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
- if (opInfo.serviceSrcInstNode == NULL) {
+ opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+ transaction->serviceSrcInstName);
+ if (opInfo.serviceInstNode == NULL) {
retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
goto errorExit;
}
}
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
- /* Attempt to free from local resources that were provided by Server */
- retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ /* Attempt to free from local resources that were provided by Server */
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
- if (retVal == RM_SERVICE_APPROVED) {
- /* Check if free allows local resources to be freed back to Server */
- retVal = cdFreeResourcesToServer(rmInst, transaction);
- }
- else if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
- /* Request resource range was not found within local allocator resources
- * provided by Server. Set back to PROCESSING so request is forwarded to
- * Server */
- retVal = RM_SERVICE_PROCESSING;
- }
- }
+ if (retVal == RM_SERVICE_APPROVED) {
+ /* Check if free allows local resources to be freed back to
+ * Server */
+ retVal = cdFreeResourcesToServer(rmInst, transaction);
+ }
+ else if ((retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) ||
+ (retVal == RM_SERVICE_DENIED_RES_DOES_NOT_EXIST)) {
+ /* Requested resource or its range were not found within local
+ * allocator resources provided by Server. Set back to PROCESSING
+ * so request is forwarded to Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
}
else if ((rmInst->instType == Rm_instType_SERVER) ||
(rmInst->instType == Rm_instType_SHARED_SERVER)) {
/* Return original transaction to processing state to attempt completion. */
pendingTrans->state = RM_SERVICE_PROCESSING;
}
- else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ else if ((transaction->type ==
+ Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type ==
+ Rm_service_RESOURCE_ALLOCATE_USE)) {
/* Add resources provided by Server to those managed by CD */
- if ((allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name))) {
- Rm_ResourceNode *treeNode = NULL;
-
- treeNode = rmResourceNodeNew(transaction->resourceInfo.base, transaction->resourceInfo.length);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, treeNode);
- }
- else {
- Rm_ResourceRange resRange;
-
- memset((void *)&resRange, 0, sizeof(resRange));
- resRange.base = transaction->resourceInfo.base;
- resRange.length = transaction->resourceInfo.length;
-
- rmAllocatorCreate((Rm_Handle)rmInst, transaction->resourceInfo.name, &resRange);
+ if ((allocator = rmAllocatorFind((Rm_Handle)rmInst,
+ transaction->resourceInfo.name))) {
+ rmAllocatorAddResNode((Rm_Handle)rmInst,
+ allocator,
+ transaction->resourceInfo.base,
+ transaction->resourceInfo.length);
}
/* Return original transaction to processing state to attempt completion */
allocator = rmAllocatorFind((Rm_Handle)rmInst,
transaction->resourceInfo.name);
- /* Local resource freed on Server. Need to remove from
+ /* Local resource freed on Server. Remove node in
* local allocator's resource tree as well */
rmAllocatorDeleteResNode((Rm_Handle)rmInst,
allocator,
transaction->resourceInfo.base,
transaction->resourceInfo.length);
- /* Delete the allocator's resource tree if there are no
- * nodes left in the resource tree */
- if (RB_MIN(_Rm_AllocatorResourceTree,
- allocator->resourceRoot) == NULL) {
- rmAllocatorDelete((Rm_Handle)rmInst,
- transaction->resourceInfo.name);
- }
-
/* Allow original free to complete */
pendingTrans->state = RM_SERVICE_APPROVED;
}
Rm_AllocatorOpInfo opInfo;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
- opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
opInfo.resourceInfo = &pendingTrans->resourceInfo;
- opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, pendingTrans->serviceSrcInstName);
+ opInfo.serviceInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+ pendingTrans->serviceSrcInstName);
/* Can't regain the original type of allocate. Default to init */
opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) != RM_SERVICE_APPROVED) {
transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
- }
+ }
}
/* Transfer error or denial to pending transaction */
pendingTrans->state = transaction->state;
if ((rmInst->instType == Rm_instType_SERVER) ||
(rmInst->instType == Rm_instType_SHARED_SERVER) ||
(rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
-
- allocTree = rmAllocatorGetTree((Rm_Handle)rmInst);
+
+ allocTree = rmInst->allocatorTree;
if (rmInst->instType == Rm_instType_SHARED_SERVER) {
rmAllocatorTreeInv(allocTree);
}
Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
{
Rm_Inst *rmInst = NULL;
- Rm_Inst *sharedServerInst = NULL;
- uint32_t policySize;
- void *globalResourceDtb = NULL;
- void *linuxResourceDtb = NULL;
+ void *grlDtb = NULL;
+ void *policyDtb = NULL;
+ void *linuxDtb = NULL;
int addLinux = RM_FALSE;
void *key;
goto errorExit;
}
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- /* Shared Server makes copy of policy in shared memory for Shared
- * Clients on other cores */
- policySize = fdt_totalsize(initCfg->instCfg.serverCfg.globalPolicy);
- /* Align policy size to cache boundary */
- if (policySize % RM_MAX_CACHE_ALIGN) {
- policySize += (RM_MAX_CACHE_ALIGN - (policySize % RM_MAX_CACHE_ALIGN));
- }
- rmInst->u.server.policySize = policySize;
- rmInst->u.server.globalPolicy = Rm_osalMalloc(rmInst->u.server.policySize);
- memcpy(rmInst->u.server.globalPolicy, initCfg->instCfg.serverCfg.globalPolicy, rmInst->u.server.policySize);
- } else {
- rmInst->u.server.globalPolicy = initCfg->instCfg.serverCfg.globalPolicy;
- }
-
if (initCfg->instCfg.serverCfg.linuxDtb) {
- linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;
+ linuxDtb = initCfg->instCfg.serverCfg.linuxDtb;
addLinux = RM_TRUE;
}
- /* Create valid instance list from policy. Must be done prior to parsing
- * GRL so that Linux resources can be reserved correctly */
- rmInst->u.server.validInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
- if (*result == RM_OK) {
- *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
- }
-
+ /* Create valid instance list from policy. Must be done prior to
+ * parsing GRL so that Linux resources can be reserved correctly */
+ policyDtb = initCfg->instCfg.serverCfg.globalPolicy;
+ rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+ addLinux, result);
if (*result != RM_OK) {
- if (rmInst->u.server.validInstTree) {
- rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
- }
goto errorExit;
- } else {
- rmNameServerInit((Rm_Handle)rmInst);
-
- globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
-
- if ((*result = rmAllocatorInitTree((Rm_Handle) rmInst)) == RM_OK) {
- if ((*result = rmAllocatorPopulateTree((Rm_Handle)rmInst,
- globalResourceDtb,
- linuxResourceDtb)) ==
- RM_OK) {
- *result = rmPolicyValidateResNames((Rm_Handle)rmInst);
- }
- }
+ }
- if (*result != RM_OK) {
- rmAllocatorDeleteTree((Rm_Handle)rmInst);
- rmNameServerDelete((Rm_Handle)rmInst);
- if (rmInst->u.server.validInstTree) {
- rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
- }
- goto errorExit;
- }
+ rmNameServerInit((Rm_Handle)rmInst);
+ grlDtb = initCfg->instCfg.serverCfg.globalResourceList;
+ if ((*result = rmAllocatorTreeInit(rmInst, grlDtb,
+ policyDtb, linuxDtb)) != RM_OK) {
+ goto errorExit;
}
} else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
if (!initCfg->instCfg.cdCfg.cdPolicy) {
goto errorExit;
}
- rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
- rmInst->u.cd.validInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
- if (*result == RM_OK) {
- *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
- }
-
+ policyDtb = initCfg->instCfg.cdCfg.cdPolicy;
+ rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+ addLinux, result);
if (*result != RM_OK) {
- if (rmInst->u.cd.validInstTree) {
- rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
- }
goto errorExit;
}
- if ((*result = rmAllocatorInitTree((Rm_Handle) rmInst)) != RM_OK) {
- if (rmInst->u.cd.validInstTree) {
- rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
- }
+ if ((*result = rmAllocatorTreeInit(rmInst, NULL,
+ policyDtb, NULL)) != RM_OK) {
goto errorExit;
}
/* Remove once CD instance is stable - tracked by SDOCM00100797 */
*result = RM_WARNING_CD_INSTANCE_NOT_STABLE;
+
} else if (rmInst->instType == Rm_instType_CLIENT) {
if (initCfg->instCfg.clientCfg.staticPolicy) {
- rmInst->u.client.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy;
- rmInst->u.client.staticValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
- if (*result == RM_OK) {
- *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
- }
-
+ policyDtb = initCfg->instCfg.clientCfg.staticPolicy;
+ rmInst->validInstTree = rmPolicyVInstTreeInit(rmInst, policyDtb,
+ addLinux, result);
if (*result != RM_OK) {
- if (rmInst->u.client.staticValidInstTree) {
- rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
- }
+ goto errorExit;
+ }
+
+ if ((*result = rmAllocatorTreeInit(rmInst, NULL,
+ policyDtb, NULL)) != RM_OK) {
goto errorExit;
}
}
+
} else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
- if (initCfg->instCfg.sharedClientCfg.sharedServerHandle) {
- rmInst->u.sharedClient.sharedServerHandle = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
- /* Invalidate the Shared server instance structure on this core to get the latest
- * instance data. */
+ Rm_Handle sHdl = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
+ Rm_Inst *ssInst = NULL;
+
+ if (sHdl) {
+ rmInst->u.sharedClient.sharedServerHandle = sHdl;
+ /* Invalidate the Shared server instance structure on this core to
+ * get the latest instance data. */
key = Rm_osalCsEnter();
- Rm_osalBeginMemAccess((void *)rmInst->u.sharedClient.sharedServerHandle, sizeof(Rm_Inst));
- sharedServerInst = rmInst->u.sharedClient.sharedServerHandle;
- if (sharedServerInst->instType != Rm_instType_SHARED_SERVER) {
+ Rm_osalBeginMemAccess((void *)sHdl, sizeof(Rm_Inst));
+ ssInst = rmInst->u.sharedClient.sharedServerHandle;
+ if (ssInst->instType != Rm_instType_SHARED_SERVER) {
*result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
Rm_osalCsExit(key);
goto errorExit;
} else {
- /* Invalidate the policy */
- Rm_osalBeginMemAccess((void *)sharedServerInst->u.server.globalPolicy,
- sharedServerInst->u.server.policySize);
+ /* Invalidate all the trees */
+ rmPolicyValidInstTreeInv(ssInst->validInstTree);
+ rmAllocatorTreeInv(ssInst->allocatorTree);
+ rmNameServerTreeInv(ssInst->u.server.nameServer);
}
Rm_osalCsExit(key);
} else {
}
if (initCfg->instType == Rm_instType_SHARED_SERVER) {
- /* Writeback the instance and policy for other cores */
- Rm_osalEndMemAccess ((void *)rmInst, sizeof(Rm_Inst));
- Rm_osalEndMemAccess ((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+ /* Writeback instance and trees for other cores */
+ rmPolicyValidInstTreeWb(rmInst->validInstTree);
+ rmAllocatorTreeWb(rmInst->allocatorTree);
+ rmNameServerTreeWb(rmInst->u.server.nameServer);
+ Rm_osalEndMemAccess((void *)rmInst, sizeof(*rmInst));
} else if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
/* Create the instance's task blocking mechanism */
rmInst->blockHandle = Rm_osalTaskBlockCreate();
}
- return ((Rm_Handle) rmInst);
+ return((Rm_Handle)rmInst);
+
errorExit:
if (rmInst) {
- Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+ rmAllocatorTreeDelete((Rm_Handle)rmInst);
+ rmNameServerDelete((Rm_Handle)rmInst);
+ rmPolicyVInstTreeDelete((Rm_Handle)rmInst);
+ Rm_osalFree((void *)rmInst, sizeof(*rmInst));
}
- return (NULL);
+ return(NULL);
}
/* FUNCTION PURPOSE: Deletes an RM instance
key = Rm_osalCsEnter();
if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- Rm_osalBeginMemAccess((void *)rmInst, sizeof(Rm_Inst));
+ Rm_osalBeginMemAccess((void *)rmInst, sizeof(*rmInst));
}
if (rmInst->serviceHandle) {
- return (RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
- }
- else if (rmInst->transports) {
- return (RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
- }
- else if (rmInst->transactionQueue && !ignorePendingServices) {
- return (RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
- }
-
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- rmAllocatorDeleteTree(rmHandle);
- rmNameServerDelete(rmHandle);
- rmInst->u.server.allocatorTree = NULL;
-
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- Rm_osalFree((void *)rmInst->u.server.globalPolicy,
- rmInst->u.server.policySize);
- }
- }
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- rmAllocatorDeleteTree(rmHandle);
- rmInst->u.cd.allocatorTree = NULL;
+ return(RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
+ } else if (rmInst->transports) {
+ return(RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
+ } else if (rmInst->transactionQueue && !ignorePendingServices) {
+ return(RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
}
if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
- /* Delete valid instance tree */
- rmPolicyFreeValidInstTree(rmHandle);
+ rmNameServerDelete(rmHandle);
+ rmAllocatorTreeDelete(rmHandle);
+ rmPolicyVInstTreeDelete(rmHandle);
/* Delete any transactions */
while(rmInst->transactionQueue) {
if (rmInst->instType != Rm_instType_SHARED_SERVER) {
/* Delete the instance's task blocking mechanism */
Rm_osalTaskBlockDelete(rmInst->blockHandle);
- }
- else {
- Rm_osalEndMemAccess((void *)rmInst, sizeof(Rm_Inst));
+ } else {
+ rmInst->allocatorTree = NULL;
+ rmInst->validInstTree = NULL;
+ rmInst->u.server.nameServer = NULL;
+ Rm_osalEndMemAccess((void *)rmInst, sizeof(*rmInst));
}
}
- Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
-
+ Rm_osalFree((void *)rmInst, sizeof(*rmInst));
Rm_osalCsExit(key);
- return (RM_OK);
+ return(RM_OK);
}
/* FUNCTION PURPOSE: Returns RM version information
*/
uint32_t Rm_getVersion(void)
{
- return RM_VERSION_ID;
+ return(RM_VERSION_ID);
}
/* FUNCTION PURPOSE: Returns RM version string
*/
const char* Rm_getVersionStr(void)
{
- return rmVersionStr;
+ return(rmVersionStr);
}
diff --git a/src/rm_allocator.c b/src/rm_allocator.c
index f69e0ac32962bd0a99843da19466814dac739472..420fffd5330a10e3df23f79d4b4cbf3841c0540a 100644 (file)
--- a/src/rm_allocator.c
+++ b/src/rm_allocator.c
/* FUNCTION PURPOSE: Checks a resource node's ownership
***********************************************************************
* DESCRIPTION: Returns the owner reference count if the provided
- * instance node is in the list of resource node owners. Otherwise,
- * returns 0.
+ * instance node is in the list of resource node owners.
+ * Otherwise, returns 0.
*/
-static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node,
+ Rm_PolicyValidInstNode *serviceInstNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
while (owner) {
RM_SS_OBJ_INV(rmInst, owner, Rm_Owner);
if (owner->instNameNode == serviceInstNode) {
- return(owner->refCnt);
+ return(owner->refCnt);
}
owner = owner->nextOwner;
}
***********************************************************************
* DESCRIPTION: Increments a resource owner's reference count
*/
-static void allocatorResNodeOwnerRefCntInc(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+static void allocatorResNodeOwnerRefCntInc(Rm_Handle rmHandle,
+ Rm_ResourceNode *node,
+ Rm_PolicyValidInstNode *serviceInstNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
@@ -108,7 +111,9 @@ static void allocatorResNodeOwnerRefCntInc(Rm_Handle rmHandle, Rm_ResourceNode *
***********************************************************************
* DESCRIPTION: Decrements a resource owner's reference count
*/
-static void allocatorResNodeOwnerRefCntDec(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+static void allocatorResNodeOwnerRefCntDec(Rm_Handle rmHandle,
+ Rm_ResourceNode *node,
+ Rm_PolicyValidInstNode *serviceInstNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
@@ -128,7 +133,9 @@ static void allocatorResNodeOwnerRefCntDec(Rm_Handle rmHandle, Rm_ResourceNode *
***********************************************************************
* DESCRIPTION: Returns a resource owner's reference count
*/
-static uint16_t allocatorResNodeOwnerGetRefCnt(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+static uint16_t allocatorResNodeOwnerGetRefCnt(Rm_Handle rmHandle,
+ Rm_ResourceNode *node,
+ Rm_PolicyValidInstNode *serviceInstNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
@@ -150,9 +157,10 @@ static uint16_t allocatorResNodeOwnerGetRefCnt(Rm_Handle rmHandle, Rm_ResourceNo
* list of owners. If the owner is already present that
* owner's reference count is incremented
*/
-static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node,
+ Rm_PolicyValidInstNode *serviceInstNode)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *ownerList = node->ownerList;
Rm_Owner *newOwner = NULL;
* DESCRIPTION: Returns TRUE if the resource nodes are neighbors from
* a base+length perspective. Otherwise, returns FALSE.
*/
-static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1,
+ Rm_ResourceNode *node2)
{
uint32_t node1End;
uint32_t node2End;
@@ -223,7 +232,9 @@ static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1, Rm_ResourceNo
* DESCRIPTION: Returns TRUE if the owners of two resource nodes
* are equivalent. Otherwise, returns FALSE.
*/
-static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle,
+ Rm_ResourceNode *node1,
+ Rm_ResourceNode *node2)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *node1Owners = node1->ownerList;
@@ -274,7 +285,9 @@ static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *nod
* owner is greater than 1 only the refCnt is
* decremented
*/
-static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
+static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle,
+ Rm_ResourceNode *node,
+ void *serviceInstNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
@@ -318,7 +331,9 @@ static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle, Rm_ResourceNode *nod
*
* dstNode must be a newly created node without any owners.
*/
-static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle, Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
+static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle,
+ Rm_ResourceNode *dstNode,
+ Rm_ResourceNode *srcNode)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *srcOwnerList = srcNode->ownerList;
@@ -355,9 +370,10 @@ static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle, Rm_ResourceNode *dstNo
* DESCRIPTION: Deletes all owners from the owners list of a
* resource node.
*/
-static void allocatorResNodeOwnerClear(Rm_Handle rmHandle, Rm_ResourceNode *node)
+static void allocatorResNodeOwnerClear(Rm_Handle rmHandle,
+ Rm_ResourceNode *node)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
Rm_Owner *nextOwner;
Rm_AllocatorOpInfo *opInfo)
{
Rm_ResourceNode findNode;
- Rm_ResourceNode *matchingNode = NULL;
+ Rm_ResourceNode *matchingNode = NULL;
uint32_t matchingEnd;
- uint32_t findEnd;
+ uint32_t findEnd;
int32_t retVal;
memset((void *)&findNode, 0, sizeof(findNode));
findEnd = findNode.base + findNode.length - 1;
if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
- opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle,
+ matchingNode,
+ opInfo->serviceInstNode);
retVal = RM_SERVICE_APPROVED;
}
else {
retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
}
- return(retVal);
+ return(retVal);
}
/* FUNCTION PURPOSE: Preallocates an allocator resource
*/
static int32_t allocatorPreAllocate(Rm_Handle rmHandle,
Rm_AllocatorNode *allocator,
- int32_t resourcePolicy,
Rm_AllocatorOpInfo *opInfo)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) {
policyCheckType = Rm_policyCheck_INIT;
- }
- else if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE) {
+ } else if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE) {
policyCheckType = Rm_policyCheck_USE;
- }
- else {
+ } else {
retVal = RM_ERROR_INVALID_SERVICE_TYPE;
- return (retVal);
+ return(retVal);
}
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- /* Set base to first node's base since CD will not have all resources like Server */
+ /* Set base to first node's base since CD will not have all resources
+ * like Server */
matchingNode = RB_MIN(_Rm_AllocatorResourceTree, allocator->resourceRoot);
opInfo->resourceInfo->base = matchingNode->base;
- }
- else {
- opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode,
- resourcePolicy, policyCheckType,
- &retVal);
+ } else {
+ opInfo->resourceInfo->base = rmPolicyGetResourceBase(allocator->policyRoot,
+ opInfo->serviceInstNode,
+ policyCheckType);
}
if (retVal != RM_OK) {
return (retVal);
}
- if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {
+ if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {
/* Get alignment from policy */
- opInfo->resourceInfo->alignment = rmPolicyGetResourceAlignment(opInfo->policy, resourcePolicy);
+ opInfo->resourceInfo->alignment = rmPolicyGetAllocAlign(allocator->policyRoot);
}
if (opInfo->resourceInfo->alignment == 0) {
/* Configure policy checking structure */
memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg));
- policyCheckCfg.policyDtb = opInfo->policy;
- policyCheckCfg.resourceOffset = resourcePolicy;
-
+ policyCheckCfg.polTree = allocator->policyRoot;
+
do {
matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->resourceRoot, &findNode);
/* Attempt to preallocate from node only if not owned by anyone and sits
* within a matching node. */
policyCheckCfg.type = policyCheckType;
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
+ policyCheckCfg.validInstNode = opInfo->serviceInstNode;
policyCheckCfg.resourceBase = findNode.base;
policyCheckCfg.resourceLength = findNode.length;
- nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
-
+ nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg);
+
if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
-
if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
/* Check if instance requesting resource has privileges to share
* a resource already reserved by Linux */
policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
- nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg);
}
if (nodePassesPolicy) {
/* Check exclusive privileges of instance requesting resource. Requesting
* instance with exclusive privileges can't reserve resource if already owned*/
policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
- nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg);
}
}
/* Check exclusive privileges of instance that currently owns resource */
policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
- nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg);
}
if (retVal != RM_OK) {
*/
static int32_t allocatorAllocate(Rm_Handle rmHandle,
Rm_AllocatorNode *allocator,
- int32_t resourcePolicy,
Rm_AllocatorOpInfo *opInfo)
{
Rm_ResourceNode findNode;
Rm_ResourceNode *leftNode = NULL;
Rm_ResourceNode *rightNode = NULL;
Rm_PolicyCheckType policyCheckType;
- Rm_PolicyCheckCfg policyCheckCfg;
- int allocPassesPolicy;
+ Rm_PolicyCheckCfg checkCfg;
+ int32_t allocPassesPolicy;
int combineLeft = RM_FALSE;
int combineRight = RM_FALSE;
uint32_t findEnd;
if (opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) {
policyCheckType = Rm_policyCheck_INIT;
- }
- else if (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE) {
+ } else if (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE) {
policyCheckType = Rm_policyCheck_USE;
- }
- else {
+ } else {
retVal = RM_ERROR_INVALID_SERVICE_TYPE;
return (retVal);
- }
+ }
memset((void *)&findNode, 0, sizeof(findNode));
findNode.base = opInfo->resourceInfo->base;
findNode.length = opInfo->resourceInfo->length;
- matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->resourceRoot, &findNode);
+ matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->resourceRoot,
+ &findNode);
/* Prepare privilege checks */
- memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg));
+ memset((void *)&checkCfg, 0, sizeof(checkCfg));
if (matchingNode) {
findEnd = findNode.base + findNode.length - 1;
matchingEnd = matchingNode->base + matchingNode->length - 1;
if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
- if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmHandle)) {
- /* Bypass policy checks since Linux Kernel has full privileges */
+ if (opInfo->serviceInstNode == rmPolicyGetLinuxInstNode(rmHandle)) {
+ /* Bypass policy checks since Linux Kernel has full
+ * privileges */
allocPassesPolicy = RM_TRUE;
- }
- else {
- policyCheckCfg.policyDtb = opInfo->policy;
- policyCheckCfg.resourceOffset = resourcePolicy;
- policyCheckCfg.type = policyCheckType;
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
- policyCheckCfg.resourceBase = findNode.base;
- policyCheckCfg.resourceLength = findNode.length;
- allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ } else {
+ checkCfg.type = policyCheckType;
+ checkCfg.polTree = allocator->policyRoot;
+ checkCfg.validInstNode = opInfo->serviceInstNode;
+ checkCfg.resourceBase = findNode.base;
+ checkCfg.resourceLength = findNode.length;
+ allocPassesPolicy = rmPolicyCheckPrivilege(&checkCfg);
if (!allocPassesPolicy) {
if (policyCheckType == Rm_policyCheck_INIT) {
retVal = RM_SERVICE_DENIED_INIT_PERM_NOT_GIVEN;
- }
- else {
+ } else {
retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;
}
}
- if (!allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
+ if (!allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceInstNode)) {
if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
/* Check if instance requesting resource has privileges to share
* a resource already reserved by Linux */
- policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
- allocPassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ checkCfg.type = Rm_policyCheck_SHARED_LINUX;
+ checkCfg.validInstNode = opInfo->serviceInstNode;
+ allocPassesPolicy = rmPolicyCheckPrivilege(&checkCfg);
if (!allocPassesPolicy) {
retVal = RM_SERVICE_DENIED_RES_NOT_SHARED_LINUX;
}
if (allocPassesPolicy) {
/* Check exclusive privileges of instance requesting resource. Requesting
* instance with exclusive privileges can't reserve resource if already owned*/
- policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
- allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ checkCfg.type = Rm_policyCheck_EXCLUSIVE;
+ checkCfg.validInstNode = opInfo->serviceInstNode;
+ allocPassesPolicy = !rmPolicyCheckPrivilege(&checkCfg);
if (!allocPassesPolicy) {
retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;
}
}
if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {
/* Check exclusive privileges of instance that currently owns resource */
- policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
- policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
- allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
+ checkCfg.type = Rm_policyCheck_EXCLUSIVE;
+ checkCfg.validInstNode = matchingNode->ownerList->instNameNode;
+ allocPassesPolicy = !rmPolicyCheckPrivilege(&checkCfg);
if (!allocPassesPolicy) {
retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;
}
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
- allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceInstNode);
if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
/* findNode range is subset of matchingNode range and neither boundary is
matchingNode->base = findNode.base;
matchingNode->length = findNode.length;
- allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceInstNode);
/* Insert all the nodes */
RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else {
if (findNode.base == matchingNode->base) {
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
/* Add allocating instance to owner list for compare with leftNode */
- allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceInstNode);
if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, leftNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else if (findEnd == matchingEnd) {
/* findNode end and matchingNode end are equivalent. May be combine
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
/* Add allocating instance to owner list for compare with rightNode */
- allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceInstNode);
if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, rightNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
/* Remove allocating instance from leftover matchingNode */
- allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
}
retVal = RM_SERVICE_APPROVED;
retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
}
- return(retVal);
+ return(retVal);
}
/* FUNCTION PURPOSE: Frees an allocator resource
findEnd = findNode.base + findNode.length - 1;
matchingEnd = matchingNode->base + matchingNode->length - 1;
- if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+ if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
if (matchingNode->allocationCount) {
- if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
- if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
- {
+ if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceInstNode)) {
+ if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
/* Case 1: Free range equals allocated matched node exactly. Attempt to combine
* freed node with nodes to left and right.
*
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
- allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceInstNode);
if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
/* Case 2: Free range is less than range in matched node. Split
@@ -1007,16 +1013,16 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
* proper accounting of allocations in validInstance list
*/
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
- allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceInstNode);
leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
- allocatorResNodeOwnerAdd(rmHandle, leftNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, leftNode, opInfo->serviceInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, leftNode);
rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
- allocatorResNodeOwnerAdd(rmHandle, rightNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, rightNode, opInfo->serviceInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, rightNode);
matchingNode->base = findNode.base;
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else {
if (findNode.base == matchingNode->base) {
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
/* Remove freeing instance from owner list for compare with leftNode */
- allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceInstNode);
if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, leftNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
else if (findEnd == matchingEnd) {
/* Case 4: Free range is on right boundary of matched node. Try to
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
/* Remove freeing instance from owner list for compare with rightNode */
- allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceInstNode);
if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
@@ -1098,11 +1104,11 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
* and originating instance allocation reference count. */
opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, rightNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
}
/* Add freeing instance back into matchingNode allocations */
- allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot, matchingNode);
}
retVal = RM_SERVICE_APPROVED;
* check in application */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
}
}
* check in application */
opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
- opInfo->serviceSrcInstNode);
+ opInfo->serviceInstNode);
retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
}
}
@@ -1141,25 +1147,27 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
* values retrieved from the Linux DTB via the
* "linux-dtb-alias" properties within the GRL.
*/
-static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle, Rm_LinuxAlias *linuxAlias,
- Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)
+static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle,
+ Rm_LinuxAlias *linuxAlias,
+ Rm_LinuxValueRange *linuxValues,
+ Rm_AllocatorOpInfo *opInfo)
{
- int32_t retVal = RM_OK;
- int baseFound = RM_FALSE;
- int lengthFound = RM_FALSE;
- uint32_t valueIndex = 0;
+ int32_t retVal = RM_OK;
+ int baseFound = RM_FALSE;
+ int lengthFound = RM_FALSE;
+ uint32_t valueIndex = 0;
while ((linuxValues) && (!baseFound || !lengthFound)) {
if (linuxAlias->baseOffset == valueIndex) {
opInfo->resourceInfo->base = linuxValues->value;
baseFound = RM_TRUE;
- if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
+ if (linuxAlias->lengthOffset ==
+ RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
opInfo->resourceInfo->length = 1;
lengthFound = RM_TRUE;
}
- }
- else if (linuxAlias->lengthOffset == valueIndex) {
+ } else if (linuxAlias->lengthOffset == valueIndex) {
opInfo->resourceInfo->length = linuxValues->value;
lengthFound = RM_TRUE;
}
@@ -1170,15 +1178,14 @@ static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle, Rm_LinuxAlias *
if (!baseFound || !lengthFound) {
retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
- }
- else {
+ } else {
/* Allocate resource to Linux */
retVal = rmAllocatorOperation(rmHandle, opInfo);
if (retVal == RM_SERVICE_APPROVED) {
retVal = RM_OK;
}
}
- return (retVal);
+ return(retVal);
}
/* FUNCTION PURPOSE: Finds and reserves Linux resources
@@ -1188,10 +1195,11 @@ static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle, Rm_LinuxAlias *
* "linux-dtb-alias" property defined in the GRL it is
* reserved.
*/
-static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resourceName, void *linuxDtb,
+static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle,
+ const char *resourceName,
+ void *linuxDtb,
Rm_LinuxAlias *linuxAlias)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_AllocatorOpInfo opInfo;
Rm_ResourceInfo resourceInfo;
uint32_t pathOffset;
@@ -1204,18 +1212,22 @@ static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resour
int32_t depth = RM_DTB_UTIL_STARTING_DEPTH;
int32_t propertyLen;
const char *propertyName;
- const void *propertyData;
- Rm_LinuxValueRange *linuxValueRange;
- int32_t retVal = RM_OK;
+ const void *propertyData;
+ Rm_LinuxValueRange *linValRange;
+ int32_t retVal = RM_OK;
memset((void *)&opInfo, 0, sizeof(opInfo));
memset((void *)&resourceInfo, 0, sizeof(resourceInfo));
rm_strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
- opInfo.policy = rmInst->u.server.globalPolicy;
- opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmHandle);
- opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
- opInfo.resourceInfo = &resourceInfo;
+ opInfo.serviceInstNode = rmPolicyGetLinuxInstNode(rmHandle);
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ opInfo.resourceInfo = &resourceInfo;
+
+ if (!opInfo.serviceInstNode) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
while(linuxAlias) {
/* Reset parsing variables */
@@ -1224,52 +1236,57 @@ static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resour
tempAliasPath = Rm_osalMalloc(pathSize);
rm_strncpy(tempAliasPath, linuxAlias->path, pathSize);
nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
- prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
+ prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
resourceInfo.base = 0;
resourceInfo.length = 0;
spacePtr = strpbrk(tempAliasPath, " ");
if (spacePtr) {
*spacePtr = '\0';
- }
-
+ }
+
while(pathOffset < pathSize) {
/* Move through DTB nodes until next alias path node found */
- if (strcmp(tempAliasPath + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {
+ if (strcmp(tempAliasPath + pathOffset,
+ fdt_get_name(linuxDtb, nodeOffset, NULL))) {
nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);
if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {
- /* Returning from subnode that matched part of alias path without finding
- * resource values */
+ /* Returning from subnode that matched part of alias path
+ * without finding resource values */
retVal = RM_ERROR_DATA_NOT_FOUND_AT_LINUX_ALIAS;
break;
}
- }
- else {
- /* Found next alias path node. Move to next node name in path string. */
+ } else {
+ /* Found next alias path node. Move to next node name in path
+ * string. */
pathOffset += (strlen(tempAliasPath + pathOffset) + 1);
spacePtr = strpbrk(tempAliasPath + pathOffset, " ");
if (spacePtr) {
*spacePtr = '\0';
- }
-
+ }
+
prevDepth = fdt_node_depth(linuxDtb, nodeOffset);
propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);
while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
(pathOffset < pathSize)) {
- propertyData = fdt_getprop_by_offset(linuxDtb, propOffset,
- &propertyName, &propertyLen);
+ propertyData = fdt_getprop_by_offset(linuxDtb, propOffset,
+ &propertyName,
+ &propertyLen);
if (strcmp(tempAliasPath + pathOffset, propertyName) == 0) {
/* Found resource at end of alias path */
pathOffset += (strlen(tempAliasPath + pathOffset) + 1);
- linuxValueRange = rmDtbUtilLinuxExtractValues(propertyData, propertyLen);
- retVal = allocatorReserveLinuxResource(rmHandle, linuxAlias,
- linuxValueRange, &opInfo);
- rmDtbUtilLinuxFreeValues(linuxValueRange);
+ linValRange = rmDtbUtilLinuxExtractValues(propertyData,
+ propertyLen);
+ retVal = allocatorReserveLinuxResource(rmHandle,
+ linuxAlias,
+ linValRange,
+ &opInfo);
+ rmDtbUtilLinuxFreeValues(linValRange);
}
propOffset = fdt_next_property_offset(linuxDtb, propOffset);
- }
+ }
if (propOffset < -FDT_ERR_NOTFOUND) {
retVal = propOffset;
@@ -1277,166 +1294,401 @@ static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resour
}
}
}
-
+
Rm_osalFree(tempAliasPath, pathSize);
if (retVal < RM_OK) {
break;
}
linuxAlias = linuxAlias->nextLinuxAlias;
}
- return (retVal);
+errorExit:
+ return(retVal);
}
-/* FUNCTION PURPOSE: Creates and initializes a resource allocator
+/* FUNCTION PURPOSE: Populates an allocator's resource tree
***********************************************************************
- * DESCRIPTION: Creates a resource allocator for the provided
- * resource name and resource properties retrieved
- * from the GRL. Resources will be reserved for
- * the Linux kernel if the Linux DTB is provided
- * and there are "linux-dtb-alias" properties
- * specified in the GRL.
+ * DESCRIPTION: Uses resource range information pulled from GRL to
+ * populate an allocator's resource tree
*/
-static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle,
+static int32_t allocatorPopulateResTree(Rm_ResourceTree *resTree,
+ Rm_ResourceRange *range)
+{
+ Rm_ResourceNode *resNode = NULL;
+ int32_t retVal = RM_OK;
+
+ while (range != NULL) {
+ if (resNode = rmResourceNodeNew(range->base, range->length)) {
+ RB_INSERT(_Rm_AllocatorResourceTree, resTree,
+ resNode);
+ } else {
+ retVal = RM_ERROR_MALLOC_FAILED_RES_NODE;
+ break;
+ }
+ range = range->nextRange;
+ }
+
+ return(retVal);
+}
+
+/* FUNCTION PURPOSE: Initializes a new allocator
+ ***********************************************************************
+ * DESCRIPTION: allocates and initializes a new allocator for the
+ * provided resource name. The resource and policy tree
+ * root nodes are allocated and initialized as part of
+ * the allocator node initialization.
+ */
+static Rm_AllocatorNode *allocatorInitNode(Rm_Inst *rmInst,
const char *resourceName,
- Rm_ResourceProperties *resProps,
- void *linuxDtb)
+ int32_t *retVal)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_ResourceRange *range = NULL;
- Rm_ResourceRange *rangeBasePtr = NULL;
- Rm_NsAssignment *nsAssignments = NULL;
- Rm_NsAssignment *nsAssignmentBasePtr = NULL;
- Rm_LinuxAlias *linuxAlias = NULL;
- Rm_NameServerObjCfg nameServerObjCfg;
- int32_t retVal = RM_OK;
-
+ Rm_AllocatorTree *allocTree = rmInst->allocatorTree;
+ Rm_AllocatorNode *newAllocNode = NULL;
+ Rm_ResourceTree *resTree = NULL;
+ Rm_PolicyTree *polTree = NULL;
+
+ *retVal = RM_OK;
+
if ((strlen(resourceName) + 1) > RM_NAME_MAX_CHARS) {
- retVal = RM_ERROR_RESOURCE_NAME_TOO_LONG;
- return(retVal);
+ *retVal = RM_ERROR_RESOURCE_NAME_TOO_LONG;
+ goto errorExit;
}
- if (resProps->rangeData && (resProps->rangeLen > 0)) {
- range = rangeBasePtr = rmDtbUtilResExtractRange(resProps->rangeData,
- resProps->rangeLen);
-
- if ((retVal = rmAllocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
- if (resProps->linuxAliasData && resProps->linuxAliasLen) {
- if (linuxDtb) {
- linuxAlias = rmDtbUtilResExtractLinuxAlias(resProps->linuxAliasData,
- resProps->linuxAliasLen, &retVal);
- if (linuxAlias) {
- retVal = allocatorFindLinuxResource(rmHandle, resourceName, linuxDtb, linuxAlias);
- }
- }
- }
+ newAllocNode = rmAllocatorNodeNew(resourceName);
+ if (newAllocNode) {
+ if (RB_INSERT(_Rm_AllocatorTree, allocTree, newAllocNode)) {
+ /* Collision */
+ *retVal = RM_ERROR_RES_SPECIFIED_MORE_THAN_ONCE;
+ goto errorExit;
+ }
+
+ if (resTree = Rm_osalMalloc(sizeof(*resTree))) {
+ RB_INIT(resTree);
+ newAllocNode->resourceRoot = resTree;
+ } else {
+ *retVal = RM_ERROR_MALLOC_FAILED_RES_TREE;
+ goto errorExit;
+ }
+
+ if (polTree = Rm_osalMalloc(sizeof(*polTree))) {
+ RB_INIT(polTree);
+ newAllocNode->policyRoot = polTree;
+ } else {
+ *retVal = RM_ERROR_MALLOC_FAILED_POL_TREE;
+ goto errorExit;
}
+ } else {
+ *retVal = RM_ERROR_COULD_NOT_CREATE_NEW_ALLOCATOR;
+ goto errorExit;
}
-
- if (retVal >= RM_OK) {
- if (resProps->nsAssignData && resProps->nsAssignLen) {
- nsAssignments = rmDtbUtilResExtractNsAssignment(resProps->nsAssignData,
- resProps->nsAssignLen, &retVal);
- if (nsAssignments) {
- nsAssignmentBasePtr = nsAssignments;
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmNameServerTreeInv(rmInst->u.server.nameServer);
- }
- while (nsAssignments) {
- memset((void *)&nameServerObjCfg, 0, sizeof(nameServerObjCfg));
- nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
- nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
- nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
- nameServerObjCfg.nodeCfg.resourceBase= nsAssignments->resourceBase;
- nameServerObjCfg.nodeCfg.resourceLength = nsAssignments->resourceLength;
- rmNameServerAddObject(&nameServerObjCfg);
- nsAssignments = nsAssignments->nextNsAssignment;
- }
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmNameServerTreeWb(rmInst->u.server.nameServer);
- }
- rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
+
+errorExit:
+ if ((*retVal != RM_OK) && newAllocNode) {
+ rmAllocatorNodeFree(newAllocNode);
+ }
+ return(newAllocNode);
+}
+
+/* FUNCTION PURPOSE: Creates and initializes an allocator node
+ ***********************************************************************
+ * DESCRIPTION: Creates an allocator for the provided resource name.
+ * The resource properties retrieved from the GRL are used
+ * to create a resource tree. Resources will be reserved
+ * for the Linux kernel if the Linux DTB is provided and
+ * there are "linux-dtb-alias" properties specified in
+ * the GRL. A policy tree will be created using the
+ * resource's entry in the policy.
+ */
+static int32_t allocatorCreateNode(Rm_Inst *rmInst, void *policyDtb,
+ void *linuxDtb, const char *resourceName,
+ Rm_ResourceProperties *resProps)
+{
+ Rm_AllocatorNode *allocNode = NULL;
+ Rm_ResourceRange *range = NULL;
+ Rm_LinuxAlias *linuxAlias = NULL;
+ int32_t retVal = RM_OK;
+
+ allocNode = allocatorInitNode(rmInst, resourceName, &retVal);
+ if (allocNode) {
+ range = rmDtbUtilResExtractRange(resProps->rangeData,
+ resProps->rangeLen);
+ retVal = allocatorPopulateResTree(allocNode->resourceRoot, range);
+ if (retVal != RM_OK) {
+ goto errorExit;
+ }
+ /* Create the companion policy tree for the resource */
+ retVal = rmPolicyPopulateTree((Rm_Handle)rmInst, allocNode->policyRoot,
+ policyDtb, resourceName);
+ if (retVal != RM_OK) {
+ goto errorExit;
+ }
+
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ /* Writeback resource tree for Linux resource reservation which
+ * uses path through rmAllocatorOperation function. This function
+ * performs an invalidate of resource tree */
+ rmResourceTreeWb(allocNode->resourceRoot);
+ }
+
+ if (resProps->linuxAliasData && linuxDtb) {
+ linuxAlias = rmDtbUtilResExtractLinuxAlias(resProps->linuxAliasData,
+ resProps->linuxAliasLen,
+ &retVal);
+ /* linuxAlias will be NULL if retVal contains error code */
+ if (linuxAlias) {
+ retVal = allocatorFindLinuxResource(rmInst, resourceName,
+ linuxDtb, linuxAlias);
+ }
+
+ if (retVal != RM_OK) {
+ goto errorExit;
}
}
+
+errorExit:
+ if (range) {
+ rmDtbUtilResFreeRange(range);
+ }
+ if (linuxAlias) {
+ rmDtbUtilResFreeLinuxAlias(linuxAlias);
+ }
}
- else if (retVal != RM_ERROR_COULD_NOT_CREATE_NEW_ALLOCATOR) {
- rmAllocatorDelete(rmHandle, resourceName);
- }
+ return(retVal);
+}
+
+/* FUNCTION PURPOSE: Creates NameServer assignment entries
+ ***********************************************************************
+ * DESCRIPTION: Creates a NameServer entry for each NameServer assignment
+ * found in a GRL's resource node
+ */
+static int32_t allocatorNsAdd(Rm_Inst *rmInst, const char *resourceName,
+ Rm_ResourceProperties *resProps)
+{
+ Rm_NsAssignment *nsAssigns = NULL;
+ Rm_NsAssignment *nsAssignsBase = NULL;
+ Rm_NameServerObjCfg nsCfg;
+ int32_t retVal = RM_OK;
- rmDtbUtilResFreeRange(rangeBasePtr);
- if (linuxAlias) {
- rmDtbUtilResFreeLinuxAlias(linuxAlias);
+ if (resProps->nsAssignData) {
+ nsAssigns = rmDtbUtilResExtractNsAssignment(resProps->nsAssignData,
+ resProps->nsAssignLen,
+ &retVal);
+ /* nsAssignments will be NULL if retVal contains error code */
+ if (nsAssigns) {
+ nsAssignsBase = nsAssigns;
+ while (nsAssigns) {
+ memset((void *)&nsCfg, 0, sizeof(nsCfg));
+ nsCfg.nameServerTree = rmInst->u.server.nameServer;
+ nsCfg.nodeCfg.objName = nsAssigns->nsName;
+ nsCfg.nodeCfg.resourceName = (char *)resourceName;
+ nsCfg.nodeCfg.resourceBase= nsAssigns->resourceBase;
+ nsCfg.nodeCfg.resourceLength = nsAssigns->resourceLength;
+ rmNameServerAddObject(&nsCfg);
+ nsAssigns = nsAssigns->nextNsAssignment;
+ }
+ rmDtbUtilResFreeNsAssignmentList(nsAssignsBase);
+ }
}
+
return(retVal);
}
-/**********************************************************************
- ********************** Internal Functions ****************************
- **********************************************************************/
-/* FUNCTION PURPOSE: Creates a new allocator
+/* FUNCTION PURPOSE: Populate the allocator tree based on the GRL
***********************************************************************
- * DESCRIPTION: Creates a new allocator and its resource tree
- * using the provided resource name and value range. The
- * name and value originate from the GRL.
+ * DESCRIPTION: Populates the allocator tree using the GRL and policy DTBs.
+ * Optionally, the Linux DTB will be scanned for resources used
+ * by the Kernel if the Linux DTB is non-NULL.
*/
-int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName,
- Rm_ResourceRange *range)
+static int32_t allocatorPopulateGrlBased(Rm_Inst *rmInst, void *grlDtb,
+ void *policyDtb, void *linuxDtb)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *allocTree = rmAllocatorGetTree(rmHandle);
- Rm_AllocatorNode *newAllocNode = NULL;
- Rm_ResourceTree *resTree = NULL;
- Rm_ResourceNode *resNode = NULL;
+ int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+ int32_t nodeDepth = RM_DTB_UTIL_STARTING_DEPTH;
+ Rm_ResourceProperties resProps;
+ int32_t propOffset;
+ int32_t propertyLen;
+ const char *propertyName;
+ const void *propertyData;
+ Rm_ResourcePropType propertyType;
+ int32_t retVal = RM_OK;
- newAllocNode = rmAllocatorNodeNew(resourceName);
- if (newAllocNode) {
- resTree = Rm_osalMalloc(sizeof(*resTree));
- RB_INIT(resTree);
+ /* Create allocator tree node with resource and policy trees for
+ * each resource found in the GRL. */
+ while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
+ (nodeDepth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+
+ memset((void *)&resProps, 0, sizeof(resProps));
+ /* Get properties of resource node */
+ propOffset = fdt_first_property_offset(grlDtb, nodeOffset);
- while (range != NULL) {
- resNode = rmResourceNodeNew(range->base, range->length);
- RB_INSERT(_Rm_AllocatorResourceTree, resTree, resNode);
- range = range->nextRange;
+ while (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ propertyData = fdt_getprop_by_offset(grlDtb, propOffset,
+ &propertyName, &propertyLen);
+ propertyType = rmDtbUtilResGetPropertyType(propertyName);
+ switch(propertyType) {
+ case Rm_resourcePropType_RESOURCE_RANGE:
+ resProps.rangeData = propertyData;
+ resProps.rangeLen = propertyLen;
+ break;
+ case Rm_resourcePropType_NSASSIGNMENT:
+ resProps.nsAssignData = propertyData;
+ resProps.nsAssignLen = propertyLen;
+ break;
+ case Rm_resourcePropType_RESOURCE_LINUX_ALIAS:
+ resProps.linuxAliasData = propertyData;
+ resProps.linuxAliasLen = propertyLen;
+ break;
+ default:
+ retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;
+ goto errorExit;
+ }
+
+ propOffset = fdt_next_property_offset(grlDtb, propOffset);
+ if (propOffset == -FDT_ERR_NOTFOUND) {
+ const char *resName = fdt_get_name(grlDtb, nodeOffset,
+ NULL);
+
+ if ((!resProps.rangeData) && (!resProps.nsAssignData)) {
+ retVal = RM_ERROR_GRL_INVALID_NODE_DEF;
+ goto errorExit;
+ }
+
+ if (resProps.rangeData) {
+ /* At least range property found. Create allocator node
+ * using extracted values for resource tree and
+ * resource's policy entry for policy tree */
+ retVal = allocatorCreateNode(rmInst, policyDtb, linuxDtb,
+ resName, &resProps);
+ if (retVal != RM_OK) {
+ goto errorExit;
+ }
+ }
+
+ if (resProps.nsAssignData) {
+ retVal = allocatorNsAdd(rmInst, resName, &resProps);
+ if (retVal != RM_OK) {
+ goto errorExit;
+ }
+ }
+ } else if (propOffset < -FDT_ERR_NOTFOUND) {
+ /* Error returned by LIBFDT */
+ retVal = propOffset;
+ goto errorExit;
+ }
}
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmResourceTreeWb(resTree);
+ if (propOffset < -FDT_ERR_NOTFOUND) {
+ /* Error returned by LIBFDT */
+ retVal = propOffset;
+ goto errorExit;
}
- newAllocNode->resourceRoot = resTree;
- RM_SS_OBJ_WB(rmInst, newAllocNode, Rm_AllocatorNode);
-
- RB_INSERT(_Rm_AllocatorTree, allocTree, newAllocNode);
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmAllocatorTreeWb(allocTree);
+ nodeOffset = fdt_next_node(grlDtb, nodeOffset, &nodeDepth);
+ if (nodeOffset < -FDT_ERR_NOTFOUND) {
+ /* Error returned by LIBFDT */
+ retVal = nodeOffset;
+ goto errorExit;
}
}
- else {
- return(RM_ERROR_COULD_NOT_CREATE_NEW_ALLOCATOR);
- }
- return(RM_OK);
+errorExit:
+ return(retVal);
}
-/* FUNCTION PURPOSE: Returns a pointer to the allocator tree
+/* FUNCTION PURPOSE: Populate the allocator tree based on the GRL
***********************************************************************
- * DESCRIPTION: Returns a pointer to the instance's allocator tree
- * based on the instance type
+ * DESCRIPTION: Populates the allocator tree using the policy DTB. The
+ * resource trees in each allocator will be created on the fly
+ * as a CD requests resources from the server. Client instances
+ * will never create resource trees since they'll only use the
+ * allocator's policy trees for the static initialization phase.
*/
-Rm_AllocatorTree *rmAllocatorGetTree(Rm_Handle rmHandle)
+static int32_t allocatorPopulatePolicyBased(Rm_Inst *rmInst, void *policyDtb)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *tree = NULL;
+ int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+ int32_t nodeDepth = RM_DTB_UTIL_STARTING_DEPTH;
+ int32_t propOffset;
+ const char *resName;
+ const char *propName;
+ Rm_PolicyPropType propType;
+ Rm_AllocatorNode *newAllocNode = NULL;
+ int32_t retVal = RM_OK;
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- tree = rmInst->u.server.allocatorTree;
+ /* Search for resource node definitions in the policy */
+ while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
+ (nodeDepth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+
+ propOffset = fdt_first_property_offset(policyDtb, nodeOffset);
+ while (propOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ fdt_getprop_by_offset(policyDtb, propOffset, &propName, NULL);
+ propType = rmDtbUtilPolicyGetPropertyType(propName);
+ if (propType == Rm_policyPropType_ASSIGNMENTS) {
+ /* Found a resource node's assignment property. Create an
+ * allocator node for the resource and populate it with a
+ * policy tree */
+ resName = fdt_get_name(policyDtb, nodeOffset, NULL);
+
+ newAllocNode = allocatorInitNode(rmInst, resName, &retVal);
+ if (newAllocNode) {
+ retVal = rmPolicyPopulateTree((Rm_Handle)rmInst,
+ newAllocNode->policyRoot,
+ policyDtb, resName);
+ if (retVal != RM_OK) {
+ goto errorExit;
+ }
+ } else {
+ goto errorExit;
+ }
+
+ /* Move on to next resource node */
+ break;
+ } else if (propType == Rm_policyPropType_UNKNOWN) {
+ retVal = RM_ERROR_UNKNOWN_POLICY_RESOURCE_PROPERTY;
+ goto errorExit;
+ }
+
+ propOffset = fdt_next_property_offset(policyDtb, propOffset);
+ }
+ if (propOffset < -FDT_ERR_NOTFOUND) {
+ /* Error returned by LIBFDT */
+ retVal = propOffset;
+ goto errorExit;
+ }
+
+ nodeOffset = fdt_next_node(policyDtb, nodeOffset, &nodeDepth);
+ if (nodeOffset < -FDT_ERR_NOTFOUND) {
+ /* Error returned by LIBFDT */
+ retVal = nodeOffset;
+ goto errorExit;
+ }
}
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- tree = rmInst->u.cd.allocatorTree;
+
+errorExit:
+ return(retVal);
+}
+
+/* FUNCTION PURPOSE: Initializes the allocator tree root
+ ***********************************************************************
+ * DESCRIPTION: Initializes the allocator tree root structure
+ */
+static int32_t allocatorTreeRootInit(Rm_Inst *rmInst)
+{
+ Rm_AllocatorTree *root = NULL;
+ int32_t retVal = RM_OK;
+
+ root = Rm_osalMalloc(sizeof(*root));
+ if (root) {
+ RB_INIT(root);
+ rmInst->allocatorTree = root;
+ } else {
+ retVal = RM_ERROR_COULD_NOT_INIT_ALLOC_TREE;
}
- return(tree);
+ return(retVal);
}
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
/* FUNCTION PURPOSE: Finds an allocator
***********************************************************************
* DESCRIPTION: Returns a pointer to an allocator that matches the
Rm_AllocatorNode *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *tree = rmAllocatorGetTree(rmHandle);
+ Rm_AllocatorTree *tree = rmInst->allocatorTree;
Rm_AllocatorNode findNode;
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmAllocatorTreeInv(tree);
- }
-
- memset((void *)&findNode, 0, sizeof(Rm_AllocatorNode));
+ memset((void *)&findNode, 0, sizeof(findNode));
rm_strncpy(findNode.resourceName, resourceName, RM_NAME_MAX_CHARS);
return(RB_FIND(_Rm_AllocatorTree, tree, &findNode));
@@ -1470,9 +1718,6 @@ Rm_AllocatorNode *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName,
int32_t *resBase, uint32_t *resLen)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- void *policy = NULL;
- int32_t resOffsetInPolicy;
uint32_t allocSize;
Rm_AllocatorNode *allocator = NULL;
Rm_ResourceNode findNode;
Rm_ResourceNode *neighborNode = NULL;
int nodeIsLocalized = RM_FALSE;
- policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
- resOffsetInPolicy = rmPolicyGetResourceOffset(policy,resourceName);
- allocSize = rmPolicyGetResourceCdAllocSize(policy, resOffsetInPolicy);
allocator = rmAllocatorFind(rmHandle, resourceName);
+ allocSize = rmPolicyGetCdAllocSize(allocator->policyRoot);
- /* Nothing to free back to server if policy never specified blocks could be allocated
- * to CD */
+ /* Nothing to free back to server if policy never specified blocks could
+ * be allocated to CD */
if (allocSize) {
memset((void *)&findNode, 0, sizeof(findNode));
findNode.base = *resBase;
if (matchingNode->allocationCount) {
goto exitLocalization;
}
-
+
if (matchingNode->length % allocSize) {
- goto exitLocalization;
+ goto exitLocalization;
}
/* Check left neighbor */
@@ -1541,153 +1784,101 @@ int32_t rmAllocatorOperation(Rm_Handle rmHandle, Rm_AllocatorOpInfo *opInfo)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_AllocatorNode *allocator = NULL;
- int32_t resourceOffsetInPolicy;
int32_t retVal;
-
- resourceOffsetInPolicy = rmPolicyGetResourceOffset(opInfo->policy, opInfo->resourceInfo->name);
- allocator = rmAllocatorFind(rmHandle, opInfo->resourceInfo->name);
-
- if ((resourceOffsetInPolicy > 0) && allocator) {
+
+ if (allocator = rmAllocatorFind(rmHandle, opInfo->resourceInfo->name)) {
if (rmInst->instType == Rm_instType_SHARED_SERVER) {
rmResourceTreeInv(allocator->resourceRoot);
}
if (opInfo->operation == Rm_allocatorOp_GET_STATUS) {
retVal = allocatorStatus(rmHandle, allocator, opInfo);
- }
- else if ((opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) ||
- (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE)) {
- retVal = allocatorPreAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
- }
- else if ((opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) ||
- (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE)) {
- retVal = allocatorAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
- }
- else if (opInfo->operation == Rm_allocatorOp_FREE) {
+ } else if ((opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) ||
+ (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE)) {
+ retVal = allocatorPreAllocate(rmHandle, allocator, opInfo);
+ } else if ((opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) ||
+ (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE)) {
+ retVal = allocatorAllocate(rmHandle, allocator, opInfo);
+ } else if (opInfo->operation == Rm_allocatorOp_FREE) {
retVal = allocatorFree(rmHandle, allocator, opInfo);
- }
+ }
if ((rmInst->instType == Rm_instType_SHARED_SERVER) &&
(opInfo->operation != Rm_allocatorOp_GET_STATUS) &&
(retVal == RM_SERVICE_APPROVED)) {
rmResourceTreeWb(allocator->resourceRoot);
- }
- }
- else {
+ }
+ } else {
/* Resource could not be found in policy and/or allocator */
retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
}
return(retVal);
}
-/* FUNCTION PURPOSE: Creates the allocator tree root
+/* FUNCTION PURPOSE: Initializes the allocator tree
***********************************************************************
- * DESCRIPTION: Initializes a RM instance's allocator tree root entry
+ * DESCRIPTION: Initializes a RM instance's allocator tree using the
+ * supplied GRL and policy
*/
-int32_t rmAllocatorInitTree(Rm_Handle rmHandle)
+int32_t rmAllocatorTreeInit(Rm_Handle rmHandle, void *grlDtb,
+ void *policyDtb, void *linuxDtb)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *root = NULL;
- int32_t retVal = RM_OK;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ int32_t retVal = RM_OK;
- root = Rm_osalMalloc(sizeof(Rm_AllocatorTree));
- if (root) {
- RB_INIT(root);
- RM_SS_OBJ_WB(rmInst, root, Rm_AllocatorTree);
+ if ((retVal = allocatorTreeRootInit(rmInst)) != RM_OK) {
+ goto errorExit;
+ }
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- rmInst->u.server.allocatorTree = root;
- }
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- rmInst->u.cd.allocatorTree = root;
- }
- } else {
- retVal = RM_ERROR_COULD_NOT_INIT_ALLOC_TREE;
+ if (grlDtb && policyDtb &&
+ (rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ /* Create an allocator for each resource node in GRL. Companion
+ * policy info will be pulled and placed into policy tree */
+ retVal = allocatorPopulateGrlBased(rmInst, grlDtb, policyDtb, linuxDtb);
+ } else if (policyDtb &&
+ (rmInst->instType == Rm_instType_CLIENT_DELEGATE) ||
+ (rmInst->instType == Rm_instType_CLIENT)) {
+ /* Create an allocator for each resource node in the policy.
+ * Resource tree portion of the allocator will be NULL. Resource
+ * trees will be added at run time for Client Delegate instances.
+ * Client instances with static policy just need allocators with
+ * policy information for each resource. */
+ retVal = allocatorPopulatePolicyBased(rmInst, policyDtb);
+ } else if ((rmInst->instType != Rm_instType_CLIENT) &&
+ (rmInst->instType != Rm_instType_SHARED_CLIENT)) {
+ retVal = RM_ERROR_INVALID_ALLOCATOR_INIT;
}
+
+errorExit:
return(retVal);
}
-/* FUNCTION PURPOSE: Populates server allocator tree
+/* FUNCTION PURPOSE: Adds a node to a resource tree
***********************************************************************
- * DESCRIPTION: Creates and initializes a server instance's
- * resource allocator tree using the GRL and, if
- * provided, Linux DTB.
+ * DESCRIPTION: Adds a node to an allocator's resource tree based on the
+ * given base and length.
*/
-int32_t rmAllocatorPopulateTree(Rm_Handle rmHandle, void *globalResourceDtb,
- void *linuxDtb)
+int32_t rmAllocatorAddResNode(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
+ int32_t resBase, uint32_t resLen)
{
- int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
- int32_t nodeDepth = RM_DTB_UTIL_STARTING_DEPTH;
- Rm_ResourceProperties resProperties;
- int32_t propOffset;
- int32_t propertyLen;
- const char *propertyName;
- const void *propertyData;
- Rm_ResourcePropType propertyType;
- int32_t retVal = RM_OK;
-
- /* Parse the Global Resource List, creating an allocator for each
- * specified resource node */
- while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
- (nodeDepth >= RM_DTB_UTIL_STARTING_DEPTH)) {
- memset((void *)&resProperties, 0, sizeof(resProperties));
- /* Get properties of resource node */
- propOffset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
- while (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(globalResourceDtb, propOffset,
- &propertyName, &propertyLen);
- propertyType = rmDtbUtilResGetPropertyType(propertyName);
- if (propertyType == Rm_resourcePropType_RESOURCE_RANGE) {
- resProperties.rangeData = propertyData;
- resProperties.rangeLen = propertyLen;
- }
- else if (propertyType == Rm_resourcePropType_NSASSIGNMENT) {
- resProperties.nsAssignData = propertyData;
- resProperties.nsAssignLen = propertyLen;
- }
- else if (propertyType == Rm_resourcePropType_RESOURCE_LINUX_ALIAS) {
- resProperties.linuxAliasData = propertyData;
- resProperties.linuxAliasLen = propertyLen;
- }
- else {
- retVal = RM_ERROR_GRL_UNKNOWN_RESOURCE_PROPERTY;
- goto exitAllocInit;
- }
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_ResourceNode *resNode = NULL;
+ int32_t retVal = RM_OK;
- propOffset = fdt_next_property_offset(globalResourceDtb,
- propOffset);
- if (propOffset == -FDT_ERR_NOTFOUND) {
- /* No more resource properties but at least one found. Extract
- * the property values */
- retVal = allocatorExtractGrlResProps(rmHandle,
- fdt_get_name(globalResourceDtb, nodeOffset, NULL),
- &resProperties, linuxDtb);
- if (retVal < RM_OK) {
- goto exitAllocInit;
- }
- }
- else if (propOffset < -FDT_ERR_NOTFOUND) {
- /* Error returned by LIBFDT */
- retVal = propOffset;
- goto exitAllocInit;
- }
- }
- if (propOffset < -FDT_ERR_NOTFOUND) {
- /* Error returned by LIBFDT */
- retVal = propOffset;
- goto exitAllocInit;
- }
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeInv(allocator->resourceRoot);
+ }
- nodeOffset = fdt_next_node(globalResourceDtb, nodeOffset, &nodeDepth);
- if (nodeOffset < -FDT_ERR_NOTFOUND) {
- /* Error returned by LIBFDT */
- retVal = nodeOffset;
- goto exitAllocInit;
+ if (resNode = rmResourceNodeNew(resBase, resLen)) {
+ if (RB_INSERT(_Rm_AllocatorResourceTree, allocator->resourceRoot,
+ resNode)) {
+ retVal = RM_ERROR_RES_SPECIFIED_MORE_THAN_ONCE;
}
+ } else {
+ retVal = RM_ERROR_MALLOC_FAILED_RES_NODE;
}
-exitAllocInit:
return(retVal);
}
@@ -1719,74 +1910,23 @@ void rmAllocatorDeleteResNode(Rm_Handle rmHandle, Rm_AllocatorNode *allocator,
}
}
-/* FUNCTION PURPOSE: Deletes an allocator's resource tree
- ***********************************************************************
- * DESCRIPTION: Deletes an allocator's resource tree based on the given
- * resource name.
- */
-int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *allocTree = rmAllocatorGetTree(rmHandle);
- Rm_AllocatorNode find;
- Rm_AllocatorNode *match;
- Rm_ResourceTree *resTree;
- Rm_ResourceNode *resNode = NULL;
- Rm_ResourceNode *nextResNode = NULL;
- int32_t retVal = RM_OK;
-
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmAllocatorTreeInv(allocTree);
- }
-
- memset((void *)&find, 0, sizeof(find));
- rm_strncpy(find.resourceName, resourceName, RM_NAME_MAX_CHARS);
- match = RB_FIND(_Rm_AllocatorTree, allocTree, &find);
-
- if (match) {
- resTree = match->resourceRoot;
-
- /* Destroy resource tree */
- if (resTree) {
- for (resNode = RB_MIN(_Rm_AllocatorResourceTree, resTree);
- resNode != NULL;
- resNode = nextResNode) {
- nextResNode = RB_NEXT(_Rm_AllocatorResourceTree, resTree,
- resNode);
- RB_REMOVE(_Rm_AllocatorResourceTree, resTree, nextResNode);
- rmResourceNodeFree(resNode);
- }
- Rm_osalFree((void *)resTree, sizeof(*resTree));
- match->resourceRoot = NULL;
- RM_SS_OBJ_WB(rmInst, match, Rm_AllocatorNode);
- }
-
- RB_REMOVE(_Rm_AllocatorTree, allocTree, match);
- rmAllocatorNodeFree(match);
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmAllocatorTreeWb(allocTree);
- }
- }
- else {
- retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
- }
- return (retVal);
-}
-
/* FUNCTION PURPOSE: Deletes allocator tree
***********************************************************************
* DESCRIPTION: Removes all resource nodes for each allocator node and then
* deletes the allocator tree root.
*/
-void rmAllocatorDeleteTree(Rm_Handle rmHandle)
+void rmAllocatorTreeDelete(Rm_Handle rmHandle)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_AllocatorTree *allocTree = rmAllocatorGetTree(rmHandle);
+ Rm_AllocatorTree *allocTree = rmInst->allocatorTree;
Rm_AllocatorNode *allocNode;
Rm_AllocatorNode *nextAllocNode;
Rm_ResourceTree *resTree;
Rm_ResourceNode *resNode;
Rm_ResourceNode *nextResNode;
+ Rm_PolicyTree *polTree;
+ Rm_PolicyNode *polNode;
+ Rm_PolicyNode *nextPolNode;
if (allocTree) {
if (rmInst->instType == Rm_instType_SHARED_SERVER) {
nextAllocNode = RB_NEXT(_Rm_AllocatorTree, allocTree, allocNode);
resTree = allocNode->resourceRoot;
+ polTree = allocNode->policyRoot;
if (rmInst->instType == Rm_instType_SHARED_SERVER) {
rmResourceTreeInv(resTree);
+ rmPolicyTreeInv(polTree);
}
+
/* Delete each node in the resource tree */
for (resNode = RB_MIN(_Rm_AllocatorResourceTree, resTree);
resNode != NULL;
}
Rm_osalFree((void *)resTree, sizeof(*resTree));
+ /* Delete each node in the policy tree */
+ for (polNode = RB_MIN(_Rm_AllocatorPolicyTree, polTree);
+ polNode != NULL;
+ polNode = nextPolNode) {
+ nextPolNode = RB_NEXT(_Rm_AllocatorPolicyTree, polTree,
+ polNode);
+ RB_REMOVE(_Rm_AllocatorPolicyTree, polTree, polNode);
+ rmPolicyNodeFree(polNode);
+ }
+ Rm_osalFree((void *)polTree, sizeof(*polTree));
+
RB_REMOVE(_Rm_AllocatorTree, allocTree, allocNode);
rmAllocatorNodeFree(allocNode);
}
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index 72e0bab5323d48647278d2c46d4d8e64161bc046..8af1160573d5067089a8d658ba471c0750c0c497 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
void rmDtbUtilLinuxFreeValues(Rm_LinuxValueRange *valueList)
{
Rm_LinuxValueRange *nextValue;
-
+
while (valueList) {
nextValue = valueList->nextValue;
Rm_osalFree((void *)valueList, sizeof(Rm_LinuxValueRange));
diff --git a/src/rm_nameserver.c b/src/rm_nameserver.c
index d51cc2999ad211674a7077a9275972eed952a168..ee920403359ef857f438e8a94cee71db3e3e7c23 100644 (file)
--- a/src/rm_nameserver.c
+++ b/src/rm_nameserver.c
/* RM OSAL layer */
#include <rm_osal.h>
+/**********************************************************************
+ ************************ Local Functions *****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Returns a pointer to the NameServer tree
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's NameServer tree
+ * based on the instance type
+ */
+static Rm_NameServerTree *nameServerGetTree(Rm_Handle rmHandle)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_NameServerTree *tree = NULL;
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ tree = rmInst->u.server.nameServer;
+ }
+ return(tree);
+}
+
/**********************************************************************
******************* Internal NameServer APIs *************************
**********************************************************************/
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_NameServerTree *rootEntry = NULL;
- rootEntry = Rm_osalMalloc(sizeof(Rm_NameServerTree));
- RB_INIT(rootEntry);
- RM_SS_OBJ_WB(rmInst, rootEntry, Rm_NameServerTree);
- rmInst->u.server.nameServer = rootEntry;
+ /* NameServer only exists in Server instances for now */
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ rootEntry = Rm_osalMalloc(sizeof(Rm_NameServerTree));
+ RB_INIT(rootEntry);
+ RM_SS_OBJ_WB(rmInst, rootEntry, Rm_NameServerTree);
+ rmInst->u.server.nameServer = rootEntry;
+ }
}
/* FUNCTION PURPOSE: Deletes the NameServer tree
void rmNameServerDelete(Rm_Handle rmHandle)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_NameServerTree *treeRoot = rmInst->u.server.nameServer;
+ Rm_NameServerTree *treeRoot = nameServerGetTree(rmHandle);
Rm_NameServerNode *node;
Rm_NameServerNode *nextNode;
Rm_NameServerObjCfg objCfg;
diff --git a/src/rm_policy.c b/src/rm_policy.c
index 7f11de95020ba5933a879e422ade0f199c3f927e..82753da8f9a25c091ff0903957baf3da16000549 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
*********************** Policy Globals *******************************
**********************************************************************/
-/* Character used in Policies to specify all RM instances receive
+/* Character used in policies to specify all RM instances receive
* the defined permissions for a resource node */
-const char Rm_policyAllInstances[] = "*";
+const char Rm_policyGlobalInst[] = "*";
/**********************************************************************
******************** Local Policy Functions **************************
**********************************************************************/
-/* FUNCTION PURPOSE: Returns a pointer to the valid instance tree
- ***********************************************************************
- * DESCRIPTION: Returns a pointer to the instance's valid instance
- * tree based on the instance type
- */
-static Rm_PolicyValidInstTree *policyGetValidInstTree(Rm_Handle rmHandle)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_PolicyValidInstTree *tree = NULL;
-
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- tree = rmInst->u.server.validInstTree;
- }
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- tree = rmInst->u.cd.validInstTree;
- }
- else if (rmInst->instType == Rm_instType_CLIENT) {
- tree = rmInst->u.client.staticValidInstTree;
- }
- return(tree);
-}
-
-/* FUNCTION PURPOSE: Validates the instance names in a permissions string
- ***********************************************************************
- * DESCRIPTION: Returns RM_OK if all the instance names in a permissions
- * string match instance names defined in the valid instance
- * list. RM_ERROR_PERM_STR_INST_NOT_VALID is returned if
- * there are any mismatches
- */
-static int32_t policyCheckInstances(Rm_Handle rmHandle, Rm_PolicyPermission *permissionsList)
-{
- while (permissionsList) {
- if (strncmp(permissionsList->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) &&
- (!rmPolicyGetValidInstNode(rmHandle, permissionsList->instName))) {
- return(RM_ERROR_PERM_STR_INST_NOT_VALID);
- }
- permissionsList = permissionsList->nextPermission;
- }
- return(RM_OK);
-}
-
/* FUNCTION PURPOSE: Parses a permissions subgroup
***********************************************************************
* DESCRIPTION: Returns a linked list of policy permissions defining
@@ -245,31 +203,40 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
(*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
(*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
(*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ 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)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_SHARED_LINUX_SHIFT,
+ 1);
newPerm = newPerm->nextPermission;
}
}
@@ -320,31 +287,40 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
(*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
(*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
(*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ 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)) {
newPerm = startPerm;
- while (newPerm) {
- RM_policy_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
+ while (newPerm) {
+ Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+ RM_policy_PERM_SET(pBits, 0, 0,
+ RM_POLICY_PERM_SHARED_LINUX_SHIFT,
+ 1);
newPerm = newPerm->nextPermission;
}
}
@@ -458,347 +434,146 @@ static Rm_PolicyPermission *policyGetAssignmentPermissions(Rm_PolicyAssignment *
return(startPerm);
}
-/* FUNCTION PURPOSE: Validates a policy "assignment" string list
+/* FUNCTION PURPOSE: Returns number of bytes needed to store permissions
***********************************************************************
- * DESCRIPTION: Returns RM_OK if the specified Policy DTB "assignment"
- * property specification parses okay and all the RM
- * instances in the assignment match RM instances in the
- * valid instances list
+ * DESCRIPTION: Calculates and returns the number of bytes needed to store
+ * permissions for all valid instances. Words are packed
+ * with permissions for as many instances as can fit
*/
-static int32_t policyValidateAssignmentPermissions(Rm_Handle rmHandle,
- Rm_PolicyAssignment *assignmentList)
+static uint32_t policyGetPermBufSize(Rm_PolicyPermBits *permsPtr,
+ uint32_t maxValidInst)
{
- Rm_PolicyAssignment *assignment = assignmentList;
- Rm_PolicyPermission *permissionList;
- int32_t result;
-
- while (assignment) {
- /* Make sure assignment's permissions parse okay */
- permissionList = policyGetAssignmentPermissions(assignment, &result);
- if (result != RM_OK) {
- return(result);
- }
-
- if ((result = policyCheckInstances(rmHandle, permissionList)) !=
- RM_OK) {
- policyFreeAssignmentPermissions(permissionList);
- return(result);
- }
+ uint32_t instPerWord;
+ uint32_t numWords;
+ uint32_t totalBytes = 0;
- policyFreeAssignmentPermissions(permissionList);
- assignment = assignment->nextAssignment;
- }
+ instPerWord = RM_policy_PERM_INST_PER_WORD;
+ /* Round up */
+ numWords = (maxValidInst + instPerWord - 1) / instPerWord;
- return (RM_OK);
-}
-
-/**********************************************************************
- ************************ Internal Policy APIs ************************
- **********************************************************************/
-
-/* FUNCTION PURPOSE: Returns a pointer to the instance policy
- ***********************************************************************
- * DESCRIPTION: Returns a pointer to the instance's policy based on
- * the instance type
- */
-void *rmPolicyGetPolicy(Rm_Handle rmHandle)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- void *policy = NULL;
-
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- policy = rmInst->u.server.globalPolicy;
- }
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- policy = rmInst->u.cd.cdPolicy;
- }
- else if (rmInst->instType == Rm_instType_CLIENT) {
- policy = rmInst->u.client.staticPolicy;
- }
- return(policy);
-}
-
-/* FUNCTION PURPOSE: Get a valid instace node from the valid inst tree
- ***********************************************************************
- * DESCRIPTION: Returns a valid instance node from the valid instance
- * tree that matches the specified instName
- */
-Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle, char *instName)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_PolicyValidInstTree *treeRoot = policyGetValidInstTree(rmHandle);
- Rm_PolicyValidInstNode findNode;
-
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- rmPolicyValidInstTreeInv(treeRoot);
- }
-
- memset((void *)&findNode, 0, sizeof(Rm_PolicyValidInstNode));
- rm_strncpy(findNode.name, instName, RM_NAME_MAX_CHARS);
-
- return (RB_FIND(_Rm_PolicyValidInstTree, treeRoot, &findNode));
+ totalBytes = sizeof(*permsPtr) * numWords;
+ return(totalBytes);
}
-/* FUNCTION PURPOSE: Gets the Linux Valid instance node
+/* FUNCTION PURPOSE: Stores policy permissions in a policy tree node
***********************************************************************
- * DESCRIPTION: Returns a pointer to the valid instance node in the
- * valid instance tree that matches the instance name
- * reserved for resource assigned to the Linux kernel.
+ * DESCRIPTION: Parses permissions and stores them in a word array in a
+ * compacted format. The array is attached to the resource's
+ * policy tree node.
*/
-Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle)
+static int32_t policyStorePermissions(Rm_Inst *rmInst, Rm_PolicyNode *polNode,
+ Rm_PolicyPermission *extractedPerms)
{
- char linuxName[] = RM_ALLOCATED_TO_LINUX;
+ Rm_PolicyValidInstNode *vInst = NULL;
+ uint32_t instIdx;
+ uint32_t wordIndex;
+ uint32_t wordOffset;
+ int32_t retVal = RM_OK;
- return (rmPolicyGetValidInstNode(rmHandle, linuxName));
-}
+ while (extractedPerms) {
+ if (!strncmp(extractedPerms->instName, Rm_policyGlobalInst,
+ RM_NAME_MAX_CHARS)) {
+ instIdx = RM_POLICY_GLOBAL_PERM_INDEX;
+ } else if (vInst = rmPolicyGetValidInstNode((Rm_Handle)rmInst,
+ extractedPerms->instName)) {
+ instIdx = vInst->instIdx;
+ } else {
+ retVal = RM_ERROR_PERM_STR_INST_NOT_VALID;
+ goto errorExit;
+ }
-/* FUNCTION PURPOSE: Validates resource permissions against a Policy DTB
- ***********************************************************************
- * DESCRIPTION: Returns TRUE if the instance name has the specified
- * permissions for the specified resource in the Policy
- * DTB. Otherwise, returns FALSE.
- */
-int rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
-{
- int32_t propertyOffset;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_PolicyAssignment *assignment = NULL;
- Rm_PolicyAssignment *assignmentStart = NULL;
- Rm_PolicyPermission *permission = NULL;
- Rm_PolicyPermission *permissionStart = NULL;
- uint32_t assignmentEnd;
- uint32_t resourceEnd = privilegeCfg->resourceBase + privilegeCfg->resourceLength - 1;
- int foundInstance;
+ /* Calculate word index into policy node's permission array
+ * for the instance index */
+ wordIndex = RM_policy_PERM_INDEX(instIdx);
+ wordOffset = RM_policy_PERM_OFFSET(instIdx);
- *result = RM_OK;
+ polNode->perms[wordIndex] |= ((extractedPerms->permissionBits &
+ RM_policy_PERM_FULL_MASK) << wordOffset);
- /* Get the resource's assignments */
- propertyOffset = fdt_first_property_offset(privilegeCfg->policyDtb, privilegeCfg->resourceOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(privilegeCfg->policyDtb, propertyOffset, &propertyName, &propertyLen);
- if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_ASSIGNMENTS) {
- assignment = assignmentStart = rmDtbUtilPolicyExtractAssignments(propertyData, propertyLen);
- break;
- }
- propertyOffset = fdt_next_property_offset(privilegeCfg->policyDtb, propertyOffset);
- }
+ extractedPerms = extractedPerms->nextPermission;
}
- if (assignment) {
- while (assignment) {
- assignmentEnd = assignment->resourceBase + assignment->resourceLength - 1;
- foundInstance = RM_FALSE;
- if (((privilegeCfg->resourceBase >= assignment->resourceBase) &&
- (privilegeCfg->resourceBase <= assignmentEnd)) ||
- ((privilegeCfg->resourceBase < assignment->resourceBase) &&
- (resourceEnd > assignmentEnd)) ||
- ((resourceEnd >= assignment->resourceBase) &&
- (resourceEnd <= assignmentEnd))) {
-
- permission = permissionStart = policyGetAssignmentPermissions(assignment, result);
- while (permission) {
- if ((strncmp(permission->instName, privilegeCfg->validInstNode->name, RM_NAME_MAX_CHARS) == 0) ||
- (strncmp(permission->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) == 0)) {
- foundInstance = RM_TRUE;
-
- /* Check instance's permissions */
- if (privilegeCfg->type == Rm_policyCheck_INIT) {
- if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
- policyFreeAssignmentPermissions(permissionStart);
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- return(RM_FALSE);
- }
- }
- else if (privilegeCfg->type == Rm_policyCheck_USE) {
- if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
- policyFreeAssignmentPermissions(permissionStart);
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- return(RM_FALSE);
- }
- }
- else if (privilegeCfg->type == Rm_policyCheck_EXCLUSIVE) {
- if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT)) {
- policyFreeAssignmentPermissions(permissionStart);
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- return(RM_FALSE);
- }
- }
- else if (privilegeCfg->type == Rm_policyCheck_SHARED_LINUX) {
- if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT)) {
- policyFreeAssignmentPermissions(permissionStart);
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- return(RM_FALSE);
- }
- }
- break;
- }
- permission = permission->nextPermission;
- }
-
- policyFreeAssignmentPermissions(permissionStart);
- if (!foundInstance) {
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- return(RM_FALSE);
- }
- }
- assignment = assignment->nextAssignment;
- }
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
- }
- else {
- return(RM_FALSE);
- }
-
- return(RM_TRUE);
+errorExit:
+ return(retVal);
}
-/* FUNCTION PURPOSE: Returns resource base value according to the Policy
+/* FUNCTION PURPOSE: Returns resource's allocation alignment from policy
***********************************************************************
- * DESCRIPTION: Returns a resource base value based on the resource
- * ranges assigned to the specified valid instance by the
- * Policy DTB.
+ * DESCRIPTION: Parses the policy DTB to find and return a resource's
+ * allocation alignment.
*/
-uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validInstNode,
- int32_t resourceOffset, Rm_PolicyCheckType policyCheckType,
- int32_t *result)
-
+static uint32_t policyGetDtbAllocAlign(void *policyDtb, int32_t resourceOffset)
{
- int32_t propertyOffset;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_PolicyAssignment *assignment = NULL;
- Rm_PolicyAssignment *assignmentStart = NULL;
- Rm_PolicyPermission *permission = NULL;
- Rm_PolicyPermission *permissionStart = NULL;
- int32_t resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
-
- *result = RM_OK;
-
- propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
- if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_ASSIGNMENTS) {
- assignment = assignmentStart = rmDtbUtilPolicyExtractAssignments(propertyData, propertyLen);
- break;
- }
- propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
- }
- }
-
- /* Search policy permissions for valid resource base */
- while (assignment) {
- permission = permissionStart = policyGetAssignmentPermissions(assignment, result);
- while (permission) {
- if ((strncmp(permission->instName, validInstNode->name, RM_NAME_MAX_CHARS) == 0) ||
- (strncmp(permission->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) == 0)) {
- /* Check instance's permissions */
- if ((policyCheckType == Rm_policyCheck_INIT) &&
- RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
- resourceBase = assignment->resourceBase;
- break;
- }
- else if ((policyCheckType == Rm_policyCheck_USE) &&
- RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
- resourceBase = assignment->resourceBase;
- break;
- }
- }
- permission = permission->nextPermission;
- }
- policyFreeAssignmentPermissions(permissionStart);
-
- if (resourceBase != RM_RESOURCE_BASE_UNSPECIFIED) {
+ int32_t offset;
+ const char *name;
+ int32_t len;
+ const void *data;
+ Rm_ResourceValue *alignList = NULL;
+ uint32_t align = 0;
+
+ offset = fdt_first_property_offset(policyDtb, resourceOffset);
+ while (offset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ data = fdt_getprop_by_offset(policyDtb, offset, &name, &len);
+ if (rmDtbUtilPolicyGetPropertyType(name) ==
+ Rm_policyPropType_ALLOCATION_ALIGNMENT) {
+ alignList = rmDtbUtilPolicyExtractResourceAlignments(data, len);
+ align = alignList->value;
break;
}
- else {
- assignment = assignment->nextAssignment;
- }
+ offset = fdt_next_property_offset(policyDtb, offset);
}
- if (assignmentStart) {
- rmDtbUtilPolicyFreeAssignments(assignmentStart);
+ if (alignList) {
+ rmDtbUtilPolicyFreeResourceAlignments(alignList);
}
-
- return(resourceBase);
-}
-/* FUNCTION PURPOSE: Returns resource alignment value according to the Policy
- ***********************************************************************
- * DESCRIPTION: Parses the policy DTB to find and return a resource's
- * alignment.
- */
-uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset)
-{
- int32_t propertyOffset;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_ResourceValue *alignmentList;
- uint32_t resourceAlignment = 0;
-
- propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
- if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_ALLOCATION_ALIGNMENT) {
- alignmentList = rmDtbUtilPolicyExtractResourceAlignments(propertyData, propertyLen);
- resourceAlignment = alignmentList->value;
- rmDtbUtilPolicyFreeResourceAlignments(alignmentList);
- }
- propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
- }
- }
-
- if (resourceAlignment == 0) {
- resourceAlignment = 1;
+ if (align == 0) {
+ align = 1;
}
- return(resourceAlignment);
+ return(align);
}
-/* FUNCTION PURPOSE: Returns resource CD allocation size according to the Policy
+/* FUNCTION PURPOSE: Returns resource CD allocation size defined in policy
***********************************************************************
* DESCRIPTION: Parses the policy DTB to find and return a resource's
* allocation size.
*/
-uint32_t rmPolicyGetResourceCdAllocSize(void *policyDtb, int32_t resourceOffset)
+static uint32_t policyGetDtbCdAllocSize(void *policyDtb, int32_t resourceOffset)
{
- int32_t propertyOffset;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_ResourceValue *allocSizeList;
- uint32_t resourceAllocSize = 0;
-
- propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
- if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_CD_ALLOCATION_SIZE) {
- allocSizeList = rmDtbUtilPolicyExtractCdAllocationSizes(propertyData, propertyLen);
- resourceAllocSize = allocSizeList->value;
- rmDtbUtilPolicyFreeCdAllocationSizes(allocSizeList);
- }
- propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+ int32_t offset;
+ const char *name;
+ int32_t len;
+ const void *data;
+ Rm_ResourceValue *allocSizeList = NULL;
+ uint32_t allocSize = 0;
+
+ offset = fdt_first_property_offset(policyDtb, resourceOffset);
+ while (offset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ data = fdt_getprop_by_offset(policyDtb, offset, &name, &len);
+ if (rmDtbUtilPolicyGetPropertyType(name) ==
+ Rm_policyPropType_CD_ALLOCATION_SIZE) {
+ allocSizeList = rmDtbUtilPolicyExtractCdAllocationSizes(data, len);
+ allocSize = allocSizeList->value;
+ break;
}
+ offset = fdt_next_property_offset(policyDtb, offset);
}
- return(resourceAllocSize);
-}
+ if (allocSizeList) {
+ rmDtbUtilPolicyFreeCdAllocationSizes(allocSizeList);
+ }
+ return(allocSize);
+}
-/* FUNCTION PURPOSE: Get a resource's offset into a Policy
+/* FUNCTION PURPOSE: Get a resource's offset into a policy
***********************************************************************
* DESCRIPTION: Returns the location of the specified resource node
* within the specified Policy in the form of an offset
* into the DTB. The resourceName and the Policy
* node name must match.
*/
-int32_t rmPolicyGetResourceOffset(void *policyDtb, char *resourceName)
+static int32_t policyGetDtbResourceOffset(void *policyDtb,
+ const char *resourceName)
{
int32_t nodeOffset;
int32_t depth;
if (policyDtb) {
depth = RM_DTB_UTIL_STARTING_DEPTH;
- nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+ nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
/* Find node offset for provided resource name */
while (nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
/* Resource name not found */
- nodeOffset = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ nodeOffset = RM_ERROR_RES_DOES_NOT_EXIST_IN_POLICY;
break;
- }
- else {
+ } else {
nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
if (strncmp(nodeName, resourceName, RM_NAME_MAX_CHARS) == 0) {
break;
}
}
}
- }
- else {
+ } else {
nodeOffset = RM_ERROR_INSTANCE_HAS_NO_POLICY;
}
return(nodeOffset);
}
-/* FUNCTION PURPOSE: Validates a Policy's resource node names
+/**********************************************************************
+ ************************ Internal Policy APIs ************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Get a valid instace node from the valid inst tree
***********************************************************************
- * DESCRIPTION: Returns RM_OK if all of a Policy's resource node names
- * match a node name specified in the "valid-instances"
- * list specified at the top of the Policy. Otherwise,
- * returns error
+ * DESCRIPTION: Returns a valid instance node from the valid instance
+ * tree that matches the specified instName
*/
-int32_t rmPolicyValidateResNames(Rm_Handle rmHandle)
+Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle,
+ const char *instName)
{
- void *policyDtb = rmPolicyGetPolicy(rmHandle);
- int32_t nodeOffset;
- int32_t depth;
- const char *nodeName;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_PolicyValidInstTree *treeRoot = rmInst->validInstTree;
+ Rm_PolicyValidInstNode findNode;
- depth = RM_DTB_UTIL_STARTING_DEPTH;
- nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+ rm_strncpy(findNode.name, instName, RM_NAME_MAX_CHARS);
+ return(RB_FIND(_Rm_PolicyValidInstTree, treeRoot, &findNode));
+}
+
+/* FUNCTION PURPOSE: Gets the Linux Valid instance node
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the valid instance node in the
+ * valid instance tree that matches the instance name
+ * reserved for resource assigned to the Linux kernel.
+ */
+Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle)
+{
+ const char linuxName[] = RM_ALLOCATED_TO_LINUX;
+
+ return (rmPolicyGetValidInstNode(rmHandle, linuxName));
+}
- /* 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) {
- nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
- if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+/* FUNCTION PURPOSE: Validates resource permissions against a Policy DTB
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the instance name has the specified
+ * permissions for the specified resource in the Policy
+ * DTB. Otherwise, returns FALSE.
+ */
+int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
+{
+ uint32_t permShift = RM_POLICY_PERM_INIT_SHIFT;
+ uint32_t globPermIdx;
+ uint32_t globPermOffset;
+ uint32_t instPermIdx;
+ uint32_t instPermOffset;
+ Rm_PolicyNode findNode;
+ Rm_PolicyNode *matchNode = NULL;
+ uint32_t findEnd;
+ uint32_t matchEnd;
+ int32_t isApproved = RM_FALSE;
+
+ switch (privilegeCfg->type) {
+ case Rm_policyCheck_INIT:
+ permShift = RM_POLICY_PERM_INIT_SHIFT;
+ break;
+ case Rm_policyCheck_USE:
+ permShift = RM_POLICY_PERM_USE_SHIFT;
+ break;
+ case Rm_policyCheck_EXCLUSIVE:
+ permShift = RM_POLICY_PERM_EXCLUSIVE_SHIFT;
break;
+ case Rm_policyCheck_SHARED_LINUX:
+ permShift = RM_POLICY_PERM_SHARED_LINUX_SHIFT;
+ break;
+ default:
+ return(isApproved);
+ }
+
+ /* Calculate the word indices and offsets for the global permissions and
+ * the specific instance */
+ globPermIdx = RM_policy_PERM_INDEX(RM_POLICY_GLOBAL_PERM_INDEX);
+ globPermOffset = RM_policy_PERM_OFFSET(RM_POLICY_GLOBAL_PERM_INDEX);
+ instPermIdx = RM_policy_PERM_INDEX(privilegeCfg->validInstNode->instIdx);
+ instPermOffset = RM_policy_PERM_OFFSET(privilegeCfg->validInstNode->instIdx);
+
+ memset((void *)&findNode, 0, sizeof(findNode));
+ findNode.base = privilegeCfg->resourceBase;
+ findNode.len = privilegeCfg->resourceLength;
+ /* Get first matching node. */
+ matchNode = RB_FIND(_Rm_AllocatorPolicyTree, privilegeCfg->polTree,
+ &findNode);
+ if (matchNode) {
+ /* Request range may not be completely contained within the first
+ * matching node. Find furthest left matching node for the request
+ * range */
+ while (findNode.base < matchNode->base) {
+ matchNode = RB_PREV(_Rm_AllocatorPolicyTree,
+ privilegeCfg->polTree, matchNode);
+ }
+ }
+
+ /* Check permissions across all policy nodes which the request range
+ * spans */
+ while (matchNode) {
+ /* Not approved if any matching node has permission denial */
+ if ((!RM_policy_PERM_GET(matchNode->perms, globPermIdx, globPermOffset,
+ permShift)) &&
+ (!RM_policy_PERM_GET(matchNode->perms, instPermIdx, instPermOffset,
+ permShift))) {
+ isApproved = RM_FALSE;
+ break;
+ } else {
+ /* Approve until find otherwise */
+ isApproved = RM_TRUE;
}
- nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
- if (fdt_first_property_offset(policyDtb, nodeOffset) > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- if (rmAllocatorFind(rmHandle, nodeName) == NULL) {
- /* No allocator tied to resource name */
- return(RM_ERROR_UNKNOWN_RESOURCE_IN_POLICY);
- }
+
+ matchEnd = matchNode->base + matchNode->len - 1;
+ findEnd = findNode.base + findNode.len - 1;
+
+ /* Check node to right if request range spans matching node to right */
+ if (findEnd > matchEnd) {
+ matchNode = RB_NEXT(_Rm_AllocatorPolicyTree, privilegeCfg->polTree,
+ matchNode);
+ } else {
+ break;
}
}
- return(RM_OK);
+
+ return(isApproved);
}
-/* FUNCTION PURPOSE: Validates a Policy DTB
+/* FUNCTION PURPOSE: Returns resource base value according to the Policy
***********************************************************************
- * DESCRIPTION: Returns RM_OK if the input Policy satisfies the
- * following conditions:
- * a) All "assignment" permission string parse okay
- * b) All RM instance names specified in the permission
- * strings match an instance name in the valid instance
- * list
- * c) All resource node names match a resource allocator
+ * DESCRIPTION: Returns a resource base value based on the resource
+ * ranges assigned to the specified valid instance by the
+ * Policy DTB.
*/
-int32_t rmPolicyValidatePolicy(Rm_Handle rmHandle)
+uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
+ Rm_PolicyValidInstNode *validInstNode,
+ Rm_PolicyCheckType checkType)
{
- void *policyDtb = rmPolicyGetPolicy(rmHandle);
- int32_t nodeOffset;
- int32_t propertyOffset;
- int32_t depth;
- const char *resourceName;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_PolicyPropType propertyType;
- Rm_PolicyAssignment *assignmentList;
- int32_t result;
-
- depth = RM_DTB_UTIL_STARTING_DEPTH;
- nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
-
- /* 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) {
- nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
- if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+ uint32_t permShift = RM_POLICY_PERM_INIT_SHIFT;
+ uint32_t globPermIdx;
+ uint32_t globPermOffset;
+ uint32_t instPermIdx;
+ uint32_t instPermOffset;
+ Rm_PolicyNode *polNode;
+ int32_t resBase = RM_RESOURCE_BASE_UNSPECIFIED;
+
+ if (checkType == Rm_policyCheck_INIT) {
+ permShift = RM_POLICY_PERM_INIT_SHIFT;
+ } else if (checkType == Rm_policyCheck_USE) {
+ permShift = RM_POLICY_PERM_USE_SHIFT;
+ }
+
+ /* Calculate the word indices and offsets for the global permissions and
+ * the specific instance */
+ globPermIdx = RM_policy_PERM_INDEX(RM_POLICY_GLOBAL_PERM_INDEX);
+ globPermOffset = RM_policy_PERM_OFFSET(RM_POLICY_GLOBAL_PERM_INDEX);
+ instPermIdx = RM_policy_PERM_INDEX(validInstNode->instIdx);
+ instPermOffset = RM_policy_PERM_OFFSET(validInstNode->instIdx);
+
+ RB_FOREACH(polNode, _Rm_AllocatorPolicyTree, policyTree) {
+ if (RM_policy_PERM_GET(polNode->perms, globPermIdx, globPermOffset,
+ permShift) ||
+ RM_policy_PERM_GET(polNode->perms, instPermIdx, instPermOffset,
+ permShift)) {
+ resBase = polNode->base;
break;
}
-
- resourceName = fdt_get_name(policyDtb, nodeOffset, NULL);
- if ((strlen(resourceName) + 1) > RM_NAME_MAX_CHARS) {
- return(RM_ERROR_RESOURCE_NAME_TOO_LONG);
- }
-
- propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
- propertyType = rmDtbUtilPolicyGetPropertyType(propertyName);
- if (propertyType == Rm_policyPropType_ASSIGNMENTS) {
- assignmentList = rmDtbUtilPolicyExtractAssignments(propertyData, propertyLen);
-
- if ((result = policyValidateAssignmentPermissions(rmHandle, assignmentList)) != RM_OK) {
- rmDtbUtilPolicyFreeAssignments(assignmentList);
- return(result);
- }
- rmDtbUtilPolicyFreeAssignments(assignmentList);
- }
- else if (propertyType == Rm_policyPropType_UNKNOWN) {
- return(RM_ERROR_UNKNOWN_POLICY_RESOURCE_PROPERTY);
- }
- propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
- }
}
- return(RM_OK);
+
+ return(resBase);
+}
+
+/* FUNCTION PURPOSE: Returns resource's allocation alignment
+ ***********************************************************************
+ * DESCRIPTION: Returns a resource's allocation alignment.
+ */
+uint32_t rmPolicyGetAllocAlign(Rm_PolicyTree *policyTree)
+{
+ Rm_PolicyNode *node = NULL;
+ uint32_t align = 1;
+
+ /* Resource's alignment is global at the moment so all policy tree nodes
+ * store the same value. Just get the min node and return the allocation
+ * alignment from it */
+ node = RB_MIN(_Rm_AllocatorPolicyTree, policyTree);
+ if (node) {
+ align = node->allocAlign;
+ }
+
+ return(align);
+}
+
+/* FUNCTION PURPOSE: Returns resource's CD allocation size
+ ***********************************************************************
+ * DESCRIPTION: Returns a resource's CD allocation size.
+ */
+uint32_t rmPolicyGetCdAllocSize(Rm_PolicyTree *policyTree)
+{
+ Rm_PolicyNode *node = NULL;
+ uint32_t allocSize = 0;
+
+ /* Resource's CD allocation size is global at the moment so all policy
+ * tree nodes store the same value. Just get the min node and return
+ * allocation size from it */
+ node = RB_MIN(_Rm_AllocatorPolicyTree, policyTree);
+ if (node) {
+ allocSize = node->cdAllocSize;
+ }
+
+ return(allocSize);
}
-/* FUNCTION PURPOSE: Creates the valid instance tree for a RM instance
+/* FUNCTION PURPOSE: Initializes the valid instance tree for a RM instance
***********************************************************************
* DESCRIPTION: Creates the valid instance tree for a RM instance
* that has been provided a global or static policy
* "valid-instances" property at the top of the Policy.
* The root entry of the valid instance tree is returned.
*/
-Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(Rm_Handle rmHandle,
- int addLinux,
- int32_t *result)
+Rm_PolicyValidInstTree *rmPolicyVInstTreeInit(Rm_Handle rmHandle,
+ void *policyDtb,
+ int addLinux,
+ int32_t *result)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- void *policyDtb = rmPolicyGetPolicy(rmHandle);
int32_t validInstOffset;
const char *validInstName = NULL;
int32_t validInstLen;
RB_INIT(rootEntry);
vInstListStart = validInstList;
- instIndex = 0;
+ /* Zeroeth index is reserved for global permissions */
+ instIndex = 1;
while (validInstList) {
newNode = rmPolicyValidInstNodeNew(validInstList->instName,
instIndex);
/* Add the Linux kernel node */
if (addLinux) {
- newNode = rmPolicyValidInstNodeNew(linuxName, instIndex);
+ newNode = rmPolicyValidInstNodeNew(linuxName, instIndex++);
RB_INSERT(_Rm_PolicyValidInstTree, rootEntry, newNode);
}
- if (rmInst->instType == Rm_instType_SHARED_SERVER) {
- /* Writeback the valid instance tree */
- rmPolicyValidInstTreeWb(rootEntry);
- }
+ /* Save the max index for proper accounting when validating against
+ * policy */
+ rmInst->maxInstIdx = instIndex;
*result = RM_OK;
return(rootEntry);
* DESCRIPTION: Frees all memory associated with a Policy valid
* instance tree.
*/
-void rmPolicyFreeValidInstTree(Rm_Handle rmHandle)
+void rmPolicyVInstTreeDelete(Rm_Handle rmHandle)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_PolicyValidInstTree *treeRoot = policyGetValidInstTree(rmHandle);
+ Rm_PolicyValidInstTree *treeRoot = rmInst->validInstTree;
Rm_PolicyValidInstNode *node;
Rm_PolicyValidInstNode *nextNode;
rmPolicyValidInstTreeInv(treeRoot);
}
- for (node = RB_MIN(_Rm_PolicyValidInstTree, treeRoot); node != NULL; node = nextNode) {
+ for (node = RB_MIN(_Rm_PolicyValidInstTree, treeRoot);
+ node != NULL;
+ node = nextNode) {
nextNode = RB_NEXT(_Rm_PolicyValidInstTree, treeRoot, node);
RB_REMOVE(_Rm_PolicyValidInstTree, treeRoot, node);
rmPolicyValidInstNodeFree(node);
}
- /* Don't need to writeback tree node changes since valid instance will be made
- * NULL in instance */
-
+ /* Don't need to writeback tree node changes since valid instance will
+ * be made NULL in instance */
+
if (RB_MIN(_Rm_PolicyValidInstTree, treeRoot) == NULL) {
/* No more valid instance nodes in tree */
- Rm_osalFree((void *)treeRoot, sizeof(Rm_PolicyValidInstTree));
+ Rm_osalFree((void *)treeRoot, sizeof(treeRoot));
}
- if ((rmInst->instType == Rm_instType_SERVER) ||
- (rmInst->instType == Rm_instType_SHARED_SERVER)) {
- rmInst->u.server.validInstTree = NULL;
+ rmInst->validInstTree = NULL;
+ }
+}
+
+/* FUNCTION PURPOSE: Populates an allocator's policy tree
+ ***********************************************************************
+ * DESCRIPTION: Populates an allocator's policy tree using the policy
+ * DTB
+ */
+int32_t rmPolicyPopulateTree(Rm_Handle rmHandle, Rm_PolicyTree *policyTree,
+ void *policyDtb, const char *resName)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ int32_t resOffset;
+ uint32_t allocAlignment;
+ uint32_t cdAllocSize;
+ uint32_t permBufSizeBytes = 0;
+ int32_t propOffset;
+ const void *propData;
+ const char *propName;
+ int32_t propLen;
+ Rm_PolicyAssignment *assign = NULL;
+ Rm_PolicyAssignment *assignStart = NULL;
+ Rm_PolicyNode *polNode = NULL;
+ Rm_PolicyPermission *extractedPerms = NULL;
+ int32_t retVal = RM_OK;
+
+ /* Offset of resource in policy DTB */
+ resOffset = policyGetDtbResourceOffset(policyDtb, resName);
+ if (resOffset < 0) {
+ retVal = resOffset;
+ goto errorExit;
+ }
+
+ /* Get the allocation alignment and the CD allocation size since these
+ * will be stored in each tree node */
+ allocAlignment = policyGetDtbAllocAlign(policyDtb, resOffset);
+ cdAllocSize = policyGetDtbCdAllocSize(policyDtb, resOffset);
+ permBufSizeBytes = policyGetPermBufSize(polNode->perms, rmInst->maxInstIdx);
+
+ /* Get the resource assignments - should only be one per resource node */
+ propOffset = fdt_first_property_offset(policyDtb, resOffset);
+ while (propOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ propData = fdt_getprop_by_offset(policyDtb, propOffset, &propName,
+ &propLen);
+ if (rmDtbUtilPolicyGetPropertyType(propName) ==
+ Rm_policyPropType_ASSIGNMENTS) {
+ assign = assignStart = rmDtbUtilPolicyExtractAssignments(propData,
+ propLen);
+ break;
}
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- rmInst->u.cd.validInstTree = NULL;
+ propOffset = fdt_next_property_offset(policyDtb, propOffset);
+ }
+
+ /* Insert a new node into resource's allocator for each assignment range */
+ while (assign) {
+ polNode = rmPolicyNodeNew(assign->resourceBase,
+ assign->resourceLength);
+ polNode->allocAlign = allocAlignment;
+ polNode->cdAllocSize = cdAllocSize;
+ polNode->perms = Rm_osalMalloc(permBufSizeBytes);
+ polNode->permsLen = permBufSizeBytes;
+
+ memset(polNode->perms, 0, polNode->permsLen);
+
+ extractedPerms = policyGetAssignmentPermissions(assign, &retVal);
+ if (retVal != RM_OK) {
+ goto errorExit;
}
- else if (rmInst->instType == Rm_instType_CLIENT) {
- rmInst->u.client.staticValidInstTree = NULL;
+
+ retVal = policyStorePermissions(rmInst, polNode, extractedPerms);
+ if (retVal != RM_OK) {
+ goto errorExit;
}
+ RB_INSERT(_Rm_AllocatorPolicyTree, policyTree, polNode);
+
+ policyFreeAssignmentPermissions(extractedPerms);
+ extractedPerms = NULL;
+ polNode = NULL;
+
+ assign = assign->nextAssignment;
+ }
+
+errorExit:
+ if (polNode) {
+ rmPolicyNodeFree(polNode);
+ }
+ if (extractedPerms) {
+ policyFreeAssignmentPermissions(extractedPerms);
+ }
+ if (assignStart) {
+ rmDtbUtilPolicyFreeAssignments(assignStart);
}
-}
+ return(retVal);
+}
diff --git a/src/rm_tree.c b/src/rm_tree.c
index ef2a26aeaf8d43006bb2526e29b7cab32af5e373..a0cc76ad7cc640e0243b0c47444475929bfbf204 100644 (file)
--- a/src/rm_tree.c
+++ b/src/rm_tree.c
newNode->len = resourceLength;
newNode->perms = NULL;
newNode->permsLen = 0;
+ newNode->allocAlign = 1;
+ newNode->cdAllocSize = 0;
}
return(newNode);
}
/* FUNCTION PURPOSE: Compares two policy tree nodes
***********************************************************************
- * DESCRIPTION: Returns the result of a comparison of two
+ * DESCRIPTION: Returns the result of a comparison of two
* policy tree node value ranges.
*
* |node1 range||node2 range| --> return < 0
/* Walk the tree which will invalidate each element in the tree */
node = RB_MIN_CACHED(_Rm_AllocatorTree, treeRoot);
while (node) {
+ rmResourceTreeInv(node->resourceRoot);
+ rmPolicyTreeInv(node->policyRoot);
node = RB_NEXT_CACHED(_Rm_AllocatorTree, treeRoot, node);
}
}
/* Writeback each element in the tree */
node = RB_MIN(_Rm_AllocatorTree, treeRoot);
do {
+ rmResourceTreeWb(node->resourceRoot);
+ rmPolicyTreeWb(node->policyRoot);
+
Rm_osalEndMemAccess((void *)node, sizeof(*node));
node = RB_NEXT(_Rm_AllocatorTree, treeRoot, node);
} while (node);