summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f535014)
raw | patch | inline | side by side (parent: f535014)
author | Justin Sobota <jsobota@ti.com> | |
Tue, 4 Dec 2012 23:09:00 +0000 (18:09 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Tue, 4 Dec 2012 23:09:00 +0000 (18:09 -0500) |
diff --git a/device/resources2.dtb b/device/resources2.dtb
index 43ee8c710b0aa86bf616f5e4abf5b57681bbc6cb..30801478c1a665eb63457ba43e9729d7d1cb6848 100644 (file)
Binary files a/device/resources2.dtb and b/device/resources2.dtb differ
Binary files a/device/resources2.dtb and b/device/resources2.dtb differ
index 6ff1de2c88c9d3b7541ea0a64ecdc7fe091dfe9a..7f5c9acf9bb5d96885adb741d30e1972657f8251 100644 (file)
unrestricted {
/* System resources with resource-name that matches a resource name
* provided in both the global device list and by components
- * utilizing RM */
+ * utilizing RM. The resource node name must match a resource node name
+ * defined in a component utilizing RM and in the global resource list. */
timers {
- /* resource name property where the name provided must match a
- * resource name defined in a component utilizing RM */
- resource-name = "timers";
/* assigned range property - defines the range of this resource
* available to the instance node.
* The format is <base num> - base = the first value in the range
};
qmss {
qmss-gp-queues {
- resource-name = "general-queues";
assigned-ranges = <0 2000>;
allocation-sizes = <32>;
};
qmss-accum-queues {
- resource-name = "accumulator-queues";
assigned-ranges = <4000 32>;
allocation-sizes = <1>;
};
};
/* Format for assigning resources to specific RM instances */
- rm-inst0 {
- /* instance-name must match the instName provided to the Rm_init
- * API when creating the RM instance */
- instance-name = "RM_Server";
+ /* instance node name must match an instName provided to the Rm_init
+ * API when creating the RM instance */
+ RM_Server {
timers {
- resource-name = "timers";
assigned-ranges = <14 15>;
allocation-sizes = <1>;
};
qmss {
qmss-gp-queues {
- resource-name = "general-queues";
assigned-range = <2000 1000>;
allocation-sizes = <32>;
};
};
/* Format for assigning resources to specific RM instances */
- rm-inst1 {
- instance-name = "RM_Client";
-
+ RM_Client {
qmss {
qmss-gp-queues {
- resource-name = "general-queues";
assigned-ranges = <3000 1000>;
allocation-sizes = <32>;
};
};
};
- /* Format for assigning resources to specific system tasks */
- system-task0 {
- /* [BIOS-ONLY] task-name must match the taskName provided to BIOS
- * when creating the task */
- task-name = "test-task";
- /* [LINUX-ONLY] task-id must match the PID assigned by Linux when
- * a task is created */
- // task-id = <n>;
-
+ test-task {
timers {
- resource-name = "timers";
assigned-ranges = <16>;
allocation-sizes = <1>;
};
index 3b5749b625dc64ddba56b19bf5a7a57fa87fad63..82031280d0f27806cd030909cbfb383181cc27d5 100644 (file)
--- a/include/rm_dtb_utilloc.h
+++ b/include/rm_dtb_utilloc.h
*************Common RM DTB Parsing Defines and Functions**************
**********************************************************************/
+/**
+* @brief LIBFDT's return codes start at 1. Map a return value of 0 to an okay result
+* from the LIBFDT APIs
+*/
+#define RM_DTB_UTIL_RESULT_OKAY 0
+/**
+* @brief DTB starting node offset for parsing
+*/
+#define RM_DTB_UTIL_STARTING_NODE_OFFSET 0
+/**
+* @brief DTB starting depth for parsing
+*/
+#define RM_DTB_UTIL_STARTING_DEPTH 0
+
typedef struct {
uint32_t base;
uint32_t length;
Rm_resourcePropType_UNKNOWN = 0,
/** Resource DTB device name property type */
Rm_resourcePropType_DEVICE_NAME = 1,
- /** Resource DTB resource name property type */
- Rm_resourcePropType_RESOURCE_NAME = 2,
/** Resource DTB resource range property type */
- Rm_resourcePropType_RESOURCE_RANGE = 3,
+ Rm_resourcePropType_RESOURCE_RANGE = 2,
/** Resource DTB resource allocator property type */
- Rm_resourcePropType_RESOURCE_ALLOCATOR = 4,
+ Rm_resourcePropType_RESOURCE_ALLOCATOR = 3,
/** Resource DTB NameServer assignment property type */
- Rm_resourcePropType_NSASSIGNMENT = 5,
+ Rm_resourcePropType_NSASSIGNMENT = 4,
} Rm_ResourcePropType;
typedef struct {
Rm_ResourcePropType Rm_resourceGetPropertyType(const char *propertyName);
char *Rm_resourceExtractDeviceName(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_resourceFreeDeviceName(char *deviceName);
-char *Rm_resourceExtractResourceName(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_resourceFreeResourceName(char *resourceName);
Rm_ResourceRange *Rm_resourceExtractResourceRange(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_resourceFreeResourceRange(Rm_ResourceRange *rangeList);
char *Rm_resourceExtractResourceAllocator(const void *dtbDataPtr, int32_t dtbDataLen);
/** Policy DTB unknown property type */
Rm_policyPropType_UNKNOWN = 0,
/** Policy DTB policy type property type */
- Rm_policyPropType_POLICY_TYPE = 1,
- /** Policy DTB instance name property type */
- Rm_policyPropType_INSTANCE_NAME = 2,
- /** Policy DTB resource name property type */
- Rm_policyPropType_RESOURCE_NAME = 3,
+ Rm_policyPropType_POLICY_TYPE = 1,
/** Policy DTB resource assigned ranges property type */
- Rm_policyPropType_RESOURCE_ASSIGNED_RANGES = 4,
+ Rm_policyPropType_RESOURCE_ASSIGNED_RANGES = 2,
/** Policy DTB resource allocation sizes property type */
- Rm_policyPropType_RESOURCE_ALLOCATION_SIZES = 5,
+ Rm_policyPropType_RESOURCE_ALLOCATION_SIZES = 3,
/** Policy DTB assigned NameServer names property type */
- Rm_policyPropType_ASSIGNED_NS_NAMES = 6,
+ Rm_policyPropType_ASSIGNED_NS_NAMES = 4,
} Rm_PolicyPropType;
typedef struct {
Rm_PolicyPropType Rm_policyGetPropertyType(const char *propertyName);
char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_policyFreePolicyType(char *policyType);
-char *Rm_policyExtractInstanceName(const void *dtbDataPtr, int32_t dtbDataLen);
-void Rm_policyFreeInstanceName(char *instanceName);
Rm_ResourceRange *Rm_policyExtractResourceAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen);
void Rm_policyFreeResourceAssignedRanges(Rm_ResourceRange *rangeList);
Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen);
diff --git a/include/rm_loc.h b/include/rm_loc.h
index e047bf8b43052d71749de22d11d3a907d4aa0579..bebad4543fee3e30ca5a64394746da9931199bb7 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
/** Pointer to RM instance's transaction queue */
typedef void *Rm_TransactionQueue;
+/** Pointer to the RM instance's allocators */
+typedef void *Rm_Allocators;
+
/**
* @brief RM transaction details values. Details values provide more fine-grained
* information regarding a transaction request or response
void *nextTransaction;
} Rm_Transaction;
+typedef struct {
+ const void *allocatorData;
+ int32_t allocatorLen;
+ const void *rangeData;
+ int32_t rangeLen;
+ const void *nsAssignData;
+ int32_t nsAssignLen;
+} Rm_ResourceProperties;
+
+typedef enum {
+ Rm_allocatorType_INTEGER = 0,
+ Rm_allocatorType_TREE = 1,
+} Rm_AllocatorType;
+
+typedef struct {
+ uint32_t value;
+ bool allocated;
+ char allocatedTo[RM_INSTANCE_NAME_MAX_CHARS];
+} Rm_IntegerEntry;
+
+typedef struct {
+ uint32_t numResourceElements;
+ Rm_IntegerEntry *resourceArrayBase;
+} Rm_IntegerAllocatorRootEntry;
+
+typedef struct {
+ char resourceName[RM_RESOURCE_NAME_MAX_CHARS];
+ Rm_AllocatorType type;
+ /** Pointer to the first resource entry in the allocator */
+ void *allocatorRootEntry;
+ /** Pointer to next resource allocator */
+ void *nextAllocator;
+} Rm_Allocator;
+
typedef struct {
char name[RM_INSTANCE_NAME_MAX_CHARS];
Rm_InstType instType;
bool registeredWithDelegateOrServer;
- Rm_PolicyHandle instPolicy;
+ Rm_PolicyHandle policyDtb;
+ Rm_Allocators allocators;
/* RM instance transport parameters */
Rm_TransportRouteMap routeMap;
/* RM Transaction sequence number counter */
index 2fe9382ed0759c784d93b4d8d10ac6510aff605c..a8f68c10c6198d3cfab521a7fb0e1408e11674d1 100644 (file)
/* RM internal includes */
#include <ti/drv/rm/include/rm_loc.h>
-void Rm_nsAddObject(Rm_Inst *rmInst, Rm_Transaction *transaction);
-void Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_Transaction *transaction);
+#define RM_NS_ACTION_APPROVED 0
+#define RM_NS_ACTION_DENIED -1
+
+int32_t Rm_nsAddObject(Rm_Inst *rmInst, char *objectString, uint32_t objectValue);
+int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, char *objectString);
#ifdef __cplusplus
}
index 29cdba13991a538a5ce8e3e2dcb37dd07fb638a9..69775ea8c6eb7175c9ef4a04e7439a5e96a943a9 100644 (file)
--- a/rm.h
+++ b/rm.h
* Note: This parameter will be ignored when the instance type is either
* Client Delegate or Client */
void *globalResourceList;
+ /** [Server Parameter When Running on ARM Linux] Pointer to the Linux DTB.
+ * The Linux DTB will be parsed for all tracked resources reserved for use
+ * by Linux.
+ *
+ * Note: This parameter will be ignored when the instance type is either
+ * Client Delegate or Client */
+ void *linuxDtb;
/** [Server/Client Delegate Paramter] Pointer to the startup allocation
* policy. RM Servers should be initialized with the global policy
* listing for all RM instances within the system. RM Client Delegates
diff --git a/src/rm.c b/src/rm.c
index 05370e5618d914369460cd598d98ff4169ec53ef..64a9dafa2025076d5dcf36341d9835d33e25be30 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
Rm_Perms rmQmssPdspFirmwarePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_FIRMWARE_PDSPS, Rm_Perms)];\r
#endif\r
\r
+char rmIntegerAllocator[] = "integer";\r
+char rmTreeAllocator[] = "tree";\r
+\r
+extern char rmDtbStartingNode[];\r
+\r
/** @brief Global Variable which describes the RM Version Information */\r
const char rmVersionStr[] = RM_VERSION_STR ":" __DATE__ ":" __TIME__;\r
\r
********************** Internal Functions ****************************\r
**********************************************************************/\r
\r
-/* At the very least the transaction ID needs to be provided to create a transaction */\r
Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst)\r
{\r
Rm_Transaction *transactionQueue = (Rm_Transaction *)rmInst->transactionQueue;\r
/* Return if the memory allocated for the transaction entry is NULL */\r
if (newTransaction == NULL)\r
{\r
- Rm_osalMtCsExit(key);\r
- return(newTransaction);\r
- }\r
-\r
- /* Clear the transaction */\r
- memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
-\r
- /* Create an ID for the new transaction. The ID will be used for two purposes:\r
- * 1) Matching responses from higher level RM agents to requests\r
- * 2) Provided to the component that requested the service so that it can match its\r
- * request with the response it receives via its callback function it provided */\r
- newTransaction->localId = Rm_transactionGetSequenceNum(rmInst);\r
- /* New transaction's nextTransaction pointer will always be NULL */\r
- newTransaction->nextTransaction = NULL; \r
+ /* Clear the transaction */\r
+ memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
+\r
+ /* Create an ID for the new transaction. The ID will be used for two purposes:\r
+ * 1) Matching responses from higher level RM agents to requests\r
+ * 2) Provided to the component that requested the service so that it can match its\r
+ * request with the response it receives via its callback function it provided */\r
+ newTransaction->localId = Rm_transactionGetSequenceNum(rmInst);\r
+ /* New transaction's nextTransaction pointer will always be NULL */\r
+ newTransaction->nextTransaction = NULL; \r
+\r
+ /* Check if there are any transactions in the transaction queue */\r
+ if (transactionQueue)\r
+ {\r
+ /* At least one transaction in the transaction queue. Add the new entry to the \r
+ * end of the transaction queue */\r
+ while (transactionQueue->nextTransaction != NULL)\r
+ {\r
+ /* Traverse the list until arriving at the last transaction */\r
+ transactionQueue = transactionQueue->nextTransaction;\r
+ }\r
\r
- /* Check if there are any transactions in the transaction queue */\r
- if (transactionQueue)\r
- {\r
- /* At least one transaction in the transaction queue. Add the new entry to the \r
- * end of the transaction queue */\r
- while (transactionQueue->nextTransaction != NULL)\r
+ /* Add the new transaction to the end of the queue */\r
+ transactionQueue->nextTransaction = newTransaction;\r
+ }\r
+ else\r
{\r
- /* Traverse the list until arriving at the last transaction */\r
- transactionQueue = transactionQueue->nextTransaction;\r
+ /* The transaction queue does not currently exist. The new transaction is the \r
+ * first transaction */\r
+ rmInst->transactionQueue = newTransaction;\r
}\r
-\r
- /* Add the new transaction to the end of the queue */\r
- transactionQueue->nextTransaction = newTransaction;\r
- }\r
- else\r
- {\r
- /* The transaction queue does not currently exist. The new transaction is the \r
- * first transaction */\r
- rmInst->transactionQueue = newTransaction;\r
}\r
\r
Rm_osalMtCsExit(key);\r
else\r
{\r
/* Delete the transaction */\r
- if (prevTransaction == NULL)\r
+ if ((prevTransaction == NULL) && transaction->nextTransaction)\r
{\r
/* Transaction to be deleted exists at start of transaction queue. Map second\r
- * transaction to be start of transaction queue. This covers case where there is\r
- * only one transaction in the queue since the nextTransaction will be NULL */\r
+ * transaction to be start of transaction queue as long as there are more than\r
+ * one transactions. */\r
rmInst->transactionQueue = transaction->nextTransaction;\r
}\r
else\r
Rm_transactionQueueDelete(rmInst, transaction->localId);\r
}\r
\r
+Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName, Rm_AllocatorType type)\r
+{\r
+ Rm_Allocator *allocators = (Rm_Allocator *)rmInst->allocators;\r
+ Rm_Allocator *newAllocator = NULL;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance's allocator list */\r
+ key = Rm_osalMtCsEnter();\r
+\r
+ /* Get memory for a new allocator from local memory */\r
+ newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));\r
+\r
+ /* Return if the memory allocated for the allocator is NULL */\r
+ if (newAllocator != NULL)\r
+ {\r
+ /* Clear the allocator */\r
+ memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
+\r
+ /* Populate the allocator */\r
+ newAllocator->type = type;\r
+ strcpy(newAllocator->resourceName, resourceName);\r
+ /* allocator's root entry will be created by the invoking function */\r
+ newAllocator->allocatorRootEntry = NULL;\r
+ /* New allocator's nextAllocator pointer will always be NULL */\r
+ newAllocator->nextAllocator = NULL; \r
+\r
+ /* Check if there are any allocators in the allocator list */\r
+ if (allocators)\r
+ {\r
+ /* At least one allocator in the allocator list. Add the new allocator to the \r
+ * end of the allocator list */\r
+ while (allocators->nextAllocator != NULL)\r
+ {\r
+ /* Traverse the list until arriving at the last allocator */\r
+ allocators = allocators->nextAllocator;\r
+ }\r
+\r
+ /* Add the new allocator to the end of the list */\r
+ allocators->nextAllocator = newAllocator;\r
+ }\r
+ else\r
+ {\r
+ /* The allocator list does not currently exist. The new allocator is the \r
+ * first allocator */\r
+ rmInst->allocators = newAllocator;\r
+ }\r
+ }\r
+\r
+ Rm_osalMtCsExit(key);\r
+ return (newAllocator);\r
+}\r
+\r
+int32_t Rm_allocatorDelete(Rm_Inst *rmInst, char *resourceName)\r
+{\r
+ Rm_Allocator *allocator = (Rm_Allocator *) rmInst->allocators;\r
+ Rm_Allocator *prevAllocator = NULL;\r
+ int32_t retVal = RM_SERVICE_STATE_OKAY;\r
+ void *key;\r
+\r
+ /* Lock access to the RM instance's allocator list */\r
+ key = Rm_osalMtCsEnter();\r
+\r
+ /* Find the resource within the specified RM instance's allocator list. */\r
+ while (allocator != NULL)\r
+ {\r
+ if (strcmp(allocator->resourceName, resourceName) == 0)\r
+ {\r
+ /* Match: break out of loop and delete the transaction */\r
+ break; \r
+ }\r
+\r
+ prevAllocator = allocator;\r
+ allocator = allocator->nextAllocator;\r
+ }\r
+\r
+ /* Traversed entire list but did not find allocator. */\r
+ if (allocator == NULL)\r
+ {\r
+ retVal = -22; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ else\r
+ {\r
+ /* Delete the allocator */\r
+ if ((prevAllocator == NULL) && allocator->nextAllocator)\r
+ {\r
+ /* Allocator to be deleted exists at start of allocator list. Map second\r
+ * allocator to be start of allocator list as long as there are more than\r
+ * one allocators. */\r
+ rmInst->allocators = allocator->nextAllocator;\r
+ }\r
+ else\r
+ {\r
+ /* Allocator to be deleted is in the middle or at end of the list. Adjust \r
+ * adjacent allocator pointers. This covers the case where the allocator to be \r
+ * removed is at the end of the list. */\r
+ prevAllocator->nextAllocator = allocator->nextAllocator;\r
+ }\r
+\r
+ /* Free the memory associated with the allocator. */\r
+ Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));\r
+ }\r
+\r
+ Rm_osalMtCsExit(key);\r
+ return (retVal);\r
+}\r
+\r
+int32_t Rm_createIntegerAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
+{\r
+ Rm_Allocator *allocator = NULL;\r
+ Rm_ResourceRange *rangeBasePtr = range;\r
+ Rm_IntegerAllocatorRootEntry *intRootEntry = NULL;\r
+ uint16_t i, entryIndex;\r
+\r
+ /* Create the new base integer allocator */\r
+ allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_INTEGER);\r
+\r
+ /* Construct the integer allocator root entry */\r
+ intRootEntry = Rm_osalMalloc(sizeof(Rm_IntegerAllocatorRootEntry));\r
+ intRootEntry->numResourceElements = 0;\r
+\r
+ /* Get the number of entries to allocate based on the lengths in the ranges */\r
+ while (range != NULL)\r
+ {\r
+ intRootEntry->numResourceElements += range->length;\r
+ range = range->nextRange;\r
+ }\r
+\r
+ /* Initialize the entries using the range information */\r
+ if (intRootEntry->numResourceElements)\r
+ {\r
+ intRootEntry->resourceArrayBase = Rm_osalMalloc(sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
+ memset((void *)intRootEntry->resourceArrayBase, 0, sizeof(Rm_IntegerEntry) * intRootEntry->numResourceElements);\r
+\r
+ /* Reset the range pointer */\r
+ range = rangeBasePtr;\r
+ entryIndex = 0;\r
+\r
+ while (range != NULL)\r
+ {\r
+ /* Initialize each entry */\r
+ for (i = range->base; i < (range->base + range->length); i++, entryIndex++)\r
+ {\r
+ intRootEntry->resourceArrayBase[entryIndex].value = i;\r
+ }\r
+ \r
+ range = range->nextRange;\r
+ }\r
+ \r
+ allocator->allocatorRootEntry = intRootEntry;\r
+ }\r
+ else\r
+ {\r
+ /* No resource entries were created. Free the memory associated with the\r
+ * allocator and the root entry */\r
+ Rm_osalFree((void *)intRootEntry, sizeof(Rm_IntegerAllocatorRootEntry));\r
+ Rm_allocatorDelete(rmInst, allocator->resourceName);\r
+ }\r
+\r
+ return(0); /* TODO: FIX THIS RETURN */\r
+}\r
+\r
+int32_t Rm_createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, \r
+ Rm_ResourceProperties *resourceProperties)\r
+{\r
+ char *allocatorType = NULL;\r
+ Rm_ResourceRange *range = NULL;\r
+ Rm_ResourceRange *rangeBasePtr = NULL;\r
+ Rm_NsAssignment *nsAssignments = NULL;\r
+ Rm_NsAssignment *nsAssignmentBasePtr = NULL;\r
+ int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+ /* TODO: NEED CHECKS FOR VALIDITY OF ALL THE resourceProperties FIELDS */\r
+\r
+ /* Extract the resource properties from the DTB */\r
+ allocatorType = Rm_resourceExtractResourceAllocator(resourceProperties->allocatorData, \r
+ resourceProperties->allocatorLen);\r
+ range = rangeBasePtr = Rm_resourceExtractResourceRange(resourceProperties->rangeData, \r
+ resourceProperties->rangeLen);\r
+\r
+ /* Create an allocator based on the allocator type specified */\r
+ if (strcmp(allocatorType, &rmIntegerAllocator[0]) == 0)\r
+ {\r
+ /* Create an integer allocator using the resource properties */\r
+ retVal = Rm_createIntegerAllocator(rmInst, resourceName, range); \r
+ }\r
+ else if (strcmp(allocatorType, &rmTreeAllocator[0]) == 0)\r
+ {\r
+ /* Create a tree allocator using the resource properties */\r
+ }\r
+ else\r
+ {\r
+ /* Allocator type not recognized. Free the resource properties and return */\r
+ retVal = -21; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ \r
+ if (retVal >= RM_DTB_UTIL_RESULT_OKAY)\r
+ {\r
+ /* Create entries in the NameServer if any NameServer assignments were specified */\r
+ if (resourceProperties->nsAssignData && resourceProperties->nsAssignLen)\r
+ {\r
+ nsAssignments = Rm_resourceExtractNsAssignment(resourceProperties->nsAssignData, \r
+ resourceProperties->nsAssignLen);\r
+\r
+ /* Cycle through the list of assignments and add them to the NameServer */\r
+ nsAssignmentBasePtr = nsAssignments;\r
+ while (nsAssignments)\r
+ {\r
+ /* TODO: RETURN IF ANY OF THE ADDS FAIL??? */\r
+ Rm_nsAddObject(rmInst, nsAssignments->nsName, nsAssignments->resourceValue);\r
+ nsAssignments = nsAssignments->nextNsAssignment;\r
+ }\r
+ /* Free the memory allocated for the NameServer assignments */\r
+ Rm_resourceFreeNsAssignmentList(nsAssignmentBasePtr);\r
+ }\r
+ }\r
+\r
+ /* Free the memory allocated for the resource properties */\r
+ Rm_resourceFreeResourceAllocator(allocatorType);\r
+ Rm_resourceFreeResourceRange(rangeBasePtr);\r
+\r
+ return(retVal);\r
+}\r
+\r
+int32_t Rm_parseResourceProperty(void *globalResourceDtb, int32_t offset, Rm_ResourceProperties *propertyInfo)\r
+{\r
+ int32_t propertyLen;\r
+ const char *propertyName;\r
+ const void *propertyData;\r
+ Rm_ResourcePropType propertyType;\r
+ int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+ /* Get the property data and store it in the corresponding propertyInfo field */\r
+ propertyData = fdt_getprop_by_offset(globalResourceDtb, offset, &propertyName, &propertyLen);\r
+ if (propertyData)\r
+ {\r
+ propertyType = Rm_resourceGetPropertyType(propertyName);\r
+ if (propertyType == Rm_resourcePropType_RESOURCE_ALLOCATOR)\r
+ {\r
+ if (propertyInfo->allocatorData || propertyInfo->allocatorLen)\r
+ {\r
+ /* The allocator fields have already been populated. Return an error.\r
+ * The resource list has specified a property field more than once\r
+ * for a resource node */\r
+ retVal = -17; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ else\r
+ {\r
+ propertyInfo->allocatorData = propertyData;\r
+ propertyInfo->allocatorLen = propertyLen;\r
+ }\r
+ }\r
+ else if (propertyType == Rm_resourcePropType_RESOURCE_RANGE)\r
+ {\r
+ if (propertyInfo->rangeData || propertyInfo->rangeLen)\r
+ {\r
+ /* The range fields have already been populated. Return an error.\r
+ * The resource list has specified a property field more than once\r
+ * for a resource node */\r
+ retVal = -18; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ else\r
+ {\r
+ propertyInfo->rangeData = propertyData;\r
+ propertyInfo->rangeLen = propertyLen;\r
+ }\r
+ }\r
+ else if (propertyType == Rm_resourcePropType_NSASSIGNMENT)\r
+ {\r
+ if (propertyInfo->nsAssignData || propertyInfo->nsAssignLen)\r
+ {\r
+ /* The nsAssign fields have already been populated. Return an error.\r
+ * The resource list has specified a property field more than once\r
+ * for a resource node */\r
+ retVal = -19; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ else\r
+ {\r
+ propertyInfo->nsAssignData = propertyData;\r
+ propertyInfo->nsAssignLen = propertyLen;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ retVal = -20; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+ }\r
+ else\r
+ {\r
+ retVal = -16; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
+\r
+ /* Don't get anymore properties if error occurred */\r
+ if (retVal == RM_DTB_UTIL_RESULT_OKAY)\r
+ {\r
+ offset = fdt_next_property_offset(globalResourceDtb, offset);\r
+ if (offset >= 0)\r
+ {\r
+ retVal = Rm_parseResourceProperty(globalResourceDtb, offset, propertyInfo);\r
+ }\r
+ else if (offset != -FDT_ERR_NOTFOUND)\r
+ {\r
+ /* Error was returned by LIBFDT when parsing the properties */\r
+ retVal = offset;\r
+ }\r
+ }\r
+ \r
+ return (retVal);\r
+}\r
+\r
+int32_t Rm_parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t nodeOffset, int32_t depth)\r
+{\r
+ const char *resourceName = fdt_get_name(globalResourceDtb, nodeOffset, NULL);\r
+ Rm_ResourceProperties resourceProperties;\r
+ int32_t error = RM_DTB_UTIL_RESULT_OKAY;\r
+ int32_t offset;\r
+\r
+ /* Initialize the resource properties structure */\r
+ memset((void *)&resourceProperties, 0, sizeof(Rm_ResourceProperties));\r
+\r
+ /* Ignore properties of the base node */\r
+ if (strcmp(resourceName, rmDtbStartingNode))\r
+ {\r
+ /* Get the properties for the resource node if any exist */\r
+ offset = fdt_first_property_offset(globalResourceDtb, nodeOffset);\r
+ if (offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET)\r
+ {\r
+ /* Since at least one property exists attempt to parse the property nodes and \r
+ * use them to create and initialize a resource allocator */\r
+ error = Rm_parseResourceProperty(globalResourceDtb, offset, &resourceProperties);\r
+ if (error < -FDT_ERR_NOTFOUND)\r
+ {\r
+ return (error);\r
+ }\r
+ \r
+ /* Initialize an allocator with the resource properties if no error was returned */\r
+ Rm_createAndInitAllocator(rmInst, resourceName, &resourceProperties);\r
+ }\r
+ else if (offset != -FDT_ERR_NOTFOUND)\r
+ {\r
+ /* Error was returned by LIBFDT when parsing the properties */\r
+ return (offset);\r
+ }\r
+ }\r
+ \r
+ /* Get the next resource node */\r
+ offset = fdt_next_node(globalResourceDtb, nodeOffset, &depth);\r
+ /* Check the offset and depth of the next node to make sure the current node\r
+ * wasn't the last node in the Resource List. A depth less than the depth set\r
+ * at the start of the recursion will signal the end of the resource list */\r
+ if ((offset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH))\r
+ {\r
+ error = Rm_parseResourceNode(rmInst, globalResourceDtb, offset, depth);\r
+ if (error < -FDT_ERR_NOTFOUND)\r
+ {\r
+ return (error);\r
+ }\r
+ }\r
+ else if (offset != -FDT_ERR_NOTFOUND)\r
+ {\r
+ /* Error was returned by LIBFDT when parsing the nodes */\r
+ return (offset);\r
+ }\r
+\r
+ return (RM_DTB_UTIL_RESULT_OKAY);\r
+}\r
+\r
+int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb)\r
+{\r
+ int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+ int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
+ int32_t result = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+ /* Recursively parse the Global Resource List, creating an allocator for\r
+ * each resource as specified in the node */\r
+ result = Rm_parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth);\r
+\r
+ return(result);\r
+}\r
+ \r
+int32_t Rm_reserveLinuxResources(void *linuxResourceDtb)\r
+{\r
+ return(0);\r
+\r
+}\r
+\r
void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
{\r
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
{\r
/* Create a new NameServer object with the request transaction information.\r
* Transaction will contain the state result of the NameServer addition. */\r
- Rm_nsAddObject(rmInst, transaction);\r
+ if (Rm_nsAddObject(rmInst, transaction->resourceInfo.nsName,\r
+ transaction->resourceInfo.base) == RM_NS_ACTION_APPROVED)\r
+ {\r
+ transaction->state = RM_SERVICE_APPROVED;\r
+ }\r
+ else\r
+ {\r
+ /* TEMP: UPDATE THIS STATE VALUE */\r
+ transaction->state = RM_SERVICE_DENIED_BEGIN;\r
+ }\r
}\r
else\r
{\r
/* Delete an existing NameServer object with the request transaction information\r
* Transaction will contain the state result of the NameServer addition. */\r
- Rm_nsDeleteObject(rmInst, transaction);\r
+ if (Rm_nsDeleteObject(rmInst, transaction->resourceInfo.nsName) == \r
+ RM_NS_ACTION_APPROVED)\r
+ {\r
+ transaction->state = RM_SERVICE_APPROVED;\r
+ }\r
+ else\r
+ {\r
+ /* TEMP: UPDATE THIS STATE VALUE */\r
+ transaction->state = RM_SERVICE_DENIED_BEGIN;\r
+ }\r
}\r
\r
/* If source instance name does not match the local instance\r
}\r
}\r
\r
-void get_property(void *fdt, int32_t offset)\r
-{\r
- int32_t len;\r
- const char *name;\r
- char *resourceName, *allocator;\r
- const void *data;\r
- Rm_ResourceRange *range = NULL;\r
- Rm_ResourceRange *startOfRange = NULL;\r
- Rm_NsAssignment *nsAssignment = NULL;\r
- Rm_NsAssignment *startOfNsAssignment = NULL;\r
- Rm_ResourcePropType propType;\r
-\r
- data = fdt_getprop_by_offset(fdt, offset, &name, &len);\r
- if (!data)\r
- Rm_osalLog("Error traverse_properties fdt_getprop_by_offset: %d\n", len);\r
- else\r
- {\r
- Rm_osalLog("Property name: %s with length: %d offset: %d and address: %x\n", name, len, offset, data);\r
-\r
- propType = Rm_resourceGetPropertyType(name);\r
- if (propType == Rm_resourcePropType_RESOURCE_NAME)\r
- {\r
- Rm_osalLog("Resource Name: %s\n", resourceName = Rm_resourceExtractResourceName(data, len));\r
- Rm_resourceFreeResourceName(resourceName);\r
- }\r
- else if (propType == Rm_resourcePropType_RESOURCE_RANGE)\r
- {\r
- startOfRange = range = Rm_resourceExtractResourceRange(data, len);\r
- while (range != NULL)\r
- {\r
- Rm_osalLog("Resource base: %d and length: %d\n", range->base, range->length);\r
- range = (Rm_ResourceRange *) range->nextRange;\r
- }\r
- Rm_resourceFreeResourceRange(startOfRange);\r
- }\r
- else if (propType == Rm_resourcePropType_NSASSIGNMENT)\r
- {\r
- startOfNsAssignment = nsAssignment = Rm_resourceExtractNsAssignment(data, len);\r
- while (nsAssignment != NULL)\r
- {\r
- Rm_osalLog("NameServer assignment name: %s and value: %d\n", nsAssignment->nsName, nsAssignment->resourceValue);\r
- nsAssignment = (Rm_NsAssignment *) nsAssignment->nextNsAssignment;\r
- }\r
- Rm_resourceFreeNsAssignmentList(startOfNsAssignment);\r
- } \r
- else if (propType == Rm_resourcePropType_RESOURCE_ALLOCATOR)\r
- {\r
- Rm_osalLog("Resource Allocator: %s\n", allocator = Rm_resourceExtractResourceAllocator(data, len));\r
- Rm_resourceFreeResourceAllocator(allocator);\r
- }\r
- }\r
-\r
- offset = fdt_next_property_offset(fdt, offset);\r
- if (offset >= 0)\r
- get_property(fdt, offset);\r
- else if (offset != -FDT_ERR_NOTFOUND)\r
- Rm_osalLog("Error traverse_properties fdt_next_property_offset: %d\n", offset);\r
-}\r
-\r
-void get_node(void *fdt, int32_t nodeOffset, int32_t depth)\r
-{\r
- const char *nodeName = fdt_get_name(fdt, nodeOffset, NULL);\r
- char path[256];\r
- int32_t error;\r
- int32_t offset;\r
-\r
- error = fdt_get_path(fdt, nodeOffset, path, sizeof(path));\r
- if (error)\r
- Rm_osalLog("Error traverse_node fdt_get_path: %d\n", error);\r
- else\r
- Rm_osalLog("Node path: %s with name %s\n", path, nodeName);\r
-\r
- /* Get the properties for the node if any exist */\r
- offset = fdt_first_property_offset(fdt, nodeOffset);\r
- if (offset >= 0)\r
- get_property(fdt, offset);\r
- else if (offset != -FDT_ERR_NOTFOUND)\r
- Rm_osalLog("Error traverse_node fdt_first_property_offset: %d\n", offset);\r
-\r
- /* Get the next node */\r
- offset = fdt_next_node(fdt, nodeOffset, &depth);\r
- if ((offset >= 0) && (depth >= 0))\r
- {\r
- Rm_osalLog("Next node offset: %d with depth: %d\n", offset, depth);\r
- get_node(fdt, offset, depth);\r
- }\r
- else if (offset < 0)\r
- Rm_osalLog("Error traverse_node fdt_next_node: %d\n", offset);\r
-\r
- Rm_osalLog("Last node offset: %d and depth: %d\n", offset, depth);\r
-}\r
-\r
-void traverseFdt (void *fdt)\r
-{\r
- int32_t nodeOffset = 0; /* offset starts at 0, beginning of tree */\r
- int32_t startDepth = 0; /* depth starts at 0, beginning of tree */\r
-\r
- get_node(fdt, nodeOffset, startDepth);\r
-}\r
-\r
-\r
/**********************************************************************\r
********************** Application visible APIs **********************\r
**********************************************************************/\r
Rm_Handle Rm_init(Rm_InitCfg *initCfg)\r
{\r
Rm_Inst *rmInst;\r
- void *fdt = initCfg->globalResourceList; \r
+ void *globalResourceDtb = NULL;\r
+ void *linuxResourceDtb = NULL;\r
\r
/* Instance creation checks. Add one to strlen calculation for null character */\r
if ((strlen(initCfg->instName) + 1) > RM_INSTANCE_NAME_MAX_CHARS)\r
strcpy (&rmInst->name[0], initCfg->instName);\r
rmInst->instType = initCfg->instType;\r
rmInst->registeredWithDelegateOrServer = false;\r
+ rmInst->policyDtb = NULL;\r
\r
/* Initialize the transport routing map linked list pointer to NULL. The linked list\r
* nodes will be created when the application registers transports */\r
rmInst->routeMap = NULL;\r
\r
+ /* Initialize the allocators linked list pointer to NULL. The linked list nodes will\r
+ * be created on the Server instance when the application reads in the resource list.\r
+ * Nodes will also be created on Client Delegates when blocks of resources are requested\r
+ * for allocation to clients. */\r
+ rmInst->allocators = NULL;\r
+\r
/* Initialize the transaction queue elements. */\r
rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
rmInst->transactionQueue= NULL;\r
/* RM Server specific actions */\r
if (rmInst->instType == Rm_instType_SERVER)\r
{\r
- /* Open the ResourceList file */\r
- fdt_open_into(initCfg->globalResourceList, fdt, fdt_totalsize(initCfg->globalResourceList));\r
+ /* Open the ResourceList file and provide it to the resource initializer. */\r
+ if (initCfg->globalResourceList)\r
+ {\r
+ globalResourceDtb = initCfg->globalResourceList;\r
+ fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb)); \r
+ Rm_initializeAllocators(rmInst, globalResourceDtb);\r
+ }\r
\r
- /* TEST: Try to parse the entire fdt */\r
- traverseFdt(fdt);\r
+ /* Parse the Linux DTB for the resources reserved by the Linux kernel. These resources\r
+ * will be marked as used in the resource allocators. */\r
+ if (initCfg->linuxDtb)\r
+ {\r
+ linuxResourceDtb = initCfg->linuxDtb;\r
+ fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb)); \r
+ Rm_reserveLinuxResources(linuxResourceDtb);\r
+ }\r
}\r
\r
/* Instance startup policies are only used for Servers and Client Delegates */\r
if (rmInst->instType != Rm_instType_CLIENT)\r
{\r
- rmInst->instPolicy = initCfg->startupPolicy;\r
+ /* Open the instance's policy and store it */\r
+ if (initCfg->startupPolicy)\r
+ {\r
+ rmInst->policyDtb = initCfg->startupPolicy;\r
+ fdt_open_into(rmInst->policyDtb, rmInst->policyDtb, fdt_totalsize(rmInst->policyDtb)); \r
+ }\r
\r
/* Store policy via policy APIs ... */\r
}\r
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index d5bda9389e9a32438882649417e1419a905b7e79..7a0f779a029ff8de71470782146003e09258c299 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
********************Common DTB Parsing Functions**********************
**********************************************************************/
+char rmDtbStartingNode[] = "\0";
+
char *Rm_commonExtractName(const void *dtbDataPtr, int32_t dtbDataLen)
{
char *resourceName = NULL;
* by an application integrator to define the properties of resources
* listed in the Device Resource List */
char rmResourceDeviceNameProp[] = "device-name";
-char rmResourceResourceNameProp[] = "resource-name";
char rmResourceResourceRangeProp[] = "resource-range";
char rmResourceResourceAllocatorProp[] = "allocator";
char rmResourceNsAssignmentProp[] = "ns-assignment";
{
propertyType = Rm_resourcePropType_DEVICE_NAME;
}
- else if(strcmp(rmResourceResourceNameProp, propertyName) == 0)
- {
- propertyType = Rm_resourcePropType_RESOURCE_NAME;
- }
else if(strcmp(rmResourceResourceRangeProp, propertyName) == 0)
{
propertyType = Rm_resourcePropType_RESOURCE_RANGE;
Rm_commonFreeName(deviceName);
}
-char *Rm_resourceExtractResourceName(const void *dtbDataPtr, int32_t dtbDataLen)
-{
- return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
-}
-
-void Rm_resourceFreeResourceName(char *resourceName)
-{
- Rm_commonFreeName(resourceName);
-}
-
Rm_ResourceRange *Rm_resourceExtractResourceRange(const void *dtbDataPtr, int32_t dtbDataLen)
{
return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
* by an application integrator to define the properties of resources
* listed in a Resource Manager Policy */
char rmPolicyPolicyTypeProp[] = "policy-type";
-char rmPolicyInstanceNameProp[] = "instance-name";
-char rmPolicyResourceNameProp[] = "resource-name";
char rmPolicyResourceAssignedRangesProp[] = "assigned-ranges";
char rmPolicyResourceAllocationSizesProp[] = "allocation-sizes";
char rmPolicyResourceAssignedNsNamesProp[] = "assigned-ns-names";
{
propertyType = Rm_policyPropType_POLICY_TYPE;
}
- else if(strcmp(rmPolicyInstanceNameProp, propertyName) == 0)
- {
- propertyType = Rm_policyPropType_INSTANCE_NAME;
- }
- else if(strcmp(rmPolicyResourceNameProp, propertyName) == 0)
- {
- propertyType = Rm_policyPropType_RESOURCE_NAME;
- }
else if(strcmp(rmPolicyResourceAssignedRangesProp, propertyName) == 0)
{
propertyType = Rm_policyPropType_RESOURCE_ASSIGNED_RANGES;
Rm_commonFreeName(policyType);
}
-char *Rm_policyExtractInstanceName(const void *dtbDataPtr, int32_t dtbDataLen)
-{
- return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
-}
-
-void Rm_policyFreeInstanceName(char *instanceName)
-{
- Rm_commonFreeName(instanceName);
-}
-
Rm_ResourceRange *Rm_policyExtractResourceAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen)
{
return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
diff --git a/src/rm_nameserver.c b/src/rm_nameserver.c
index a4ac48618336690bcaa2fd80b076e2c2a6864130..9abbe2b325a95c745c762b0ba459b884c3093f4c 100644 (file)
--- a/src/rm_nameserver.c
+++ b/src/rm_nameserver.c
********************** Internal Functions ****************************
**********************************************************************/
-void Rm_nsAddObject(Rm_Inst *rmInst, Rm_Transaction *transaction)
+int32_t Rm_nsAddObject(Rm_Inst *rmInst, char *objectString, uint32_t objectValue)
{
/* STUB APPROVED FOR NOW */
- transaction->state = RM_SERVICE_APPROVED;
+ return(RM_NS_ACTION_APPROVED);
}
-void Rm_nsDeleteObject(Rm_Inst *rmInst, Rm_Transaction *transaction)
+int32_t Rm_nsDeleteObject(Rm_Inst *rmInst, char *objectString)
{
/* STUB APPROVED FOR NOW */
- transaction->state = RM_SERVICE_APPROVED;
+ return(RM_NS_ACTION_APPROVED);
}
diff --git a/test/rm_test.cfg b/test/rm_test.cfg
index 0af281fbf9a2cf185c061c87932596e135e0ae21..d78ad4883ed1b9cff2472f2810761e25b49823eb 100644 (file)
--- a/test/rm_test.cfg
+++ b/test/rm_test.cfg
/* BIOS/XDC modules */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
-BIOS.heapSize = 0x8000;
+BIOS.heapSize = 0x10000;
var Task = xdc.useModule('ti.sysbios.knl.Task');
/* Synchronize all processors (this will be done in Ipc_start) */