summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: eba1969)
raw | patch | inline | side by side (parent: eba1969)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 30 Nov 2012 16:51:02 +0000 (11:51 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 30 Nov 2012 16:51:02 +0000 (11:51 -0500) |
src/rm_dtb_util.c | [new file with mode: 0644] | patch | blob |
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
--- /dev/null
+++ b/src/rm_dtb_util.c
@@ -0,0 +1,511 @@
+/**
+ * @file rm_dtb_util.c
+ *
+ * @brief
+ * This is the Resource Manager Resource List and Policy DTB parsing
+ * utility source
+ *
+ * \par
+ * ============================================================================
+ * @n (C) Copyright 2012, Texas Instruments, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \par
+*/
+
+/* RM Types */
+#include <ti/drv/rm/rm_types.h>
+
+/* RM internal API includes */
+#include <ti/drv/rm/include/rm_dtb_utilloc.h>
+
+/* RM OSAL layer */
+#include <rm_osal.h>
+
+/* LIBFDT includes */
+#include <ti/drv/rm/src/libfdt/libfdt.h>
+#include <ti/drv/rm/src/libfdt/libfdt_env.h>
+
+/**********************************************************************
+ ********************Common DTB Parsing Functions**********************
+ **********************************************************************/
+
+char *Rm_commonExtractName(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ char *resourceName = NULL;
+
+ resourceName = (char *) Rm_osalMalloc(dtbDataLen);
+
+ /* The resource name is stored as a null terminated string in the DTB
+ * so it's just a straightforward string copy operation to a local
+ * buffer to extract it. */
+ strcpy(resourceName, (char *)dtbDataPtr);
+
+ return(resourceName);
+}
+
+/* Free memory that was allocated to extract a name property string */
+void Rm_commonFreeName(char *resourceName)
+{
+ int32_t nameSize;
+
+ /* Free the character array memory */
+ nameSize = strlen(resourceName);
+ /* Add one for the NULL character */
+ Rm_osalFree((void *)resourceName, nameSize+1);
+}
+
+/* Construct and return a list of ranges as specified in either the Resource
+ * DTB or a Policy DTB */
+Rm_ResourceRange *Rm_commonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
+ Rm_ResourceRange *startRange = NULL;
+ Rm_ResourceRange *newRange = NULL;
+ Rm_ResourceRange *prevRange = NULL;
+ uint32_t i;
+
+ /* Ranges are stored in the DTB as a list of 32-bit words. The number of 32-bit
+ * words in the DTB ranges field should be even since ranges are specified in a
+ * base, lenth format. The DTB gives properties lengths in bytes so the length
+ * returned from the DTB should be a multiple of the number of bytes in two
+ * uint32_ts. */
+ if (dtbDataLen % (2 * sizeof(uint32_t)))
+ {
+ /* Return NULL if there are an odd number of range values */
+ return (NULL);
+ }
+
+ /* Extract the range data from the DTB */
+ for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2)
+ {
+ /* Creat a new range entry */
+ newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
+ /* Populate the new range entry. The endianness of the value extracted must
+ * be flipped */
+ newRange->base = fdt32_to_cpu(dtbRangeData[i]);
+ newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
+ newRange->nextRange = NULL;
+
+ /* Range linked list pointer accounting */
+ if (prevRange == NULL)
+ {
+ /* Save the first entry so it can be returned */
+ startRange = newRange;
+ }
+ else
+ {
+ prevRange->nextRange = (void *) newRange;
+ }
+
+ prevRange = newRange;
+ }
+
+ /* Return a pointer to the start of the range list */
+ return (startRange);
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted ranges */
+void Rm_commonFreeRangeList(Rm_ResourceRange *rangeList)
+{
+ Rm_ResourceRange *nextRange;
+
+ while (rangeList != NULL)
+ {
+ nextRange = rangeList->nextRange;
+ Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
+ rangeList = nextRange;
+ }
+}
+
+/**********************************************************************
+ ***********Resource List DTB Parsing Defines and Functions************
+ **********************************************************************/
+
+/* Resource List Properties - These are the property values used
+ * 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";
+
+Rm_ResourcePropType Rm_resourceGetPropertyType(const char * propertyName)
+{
+ Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
+
+ if(strcmp(rmResourceDeviceNameProp, propertyName) == 0)
+ {
+ 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;
+ }
+ else if(strcmp(rmResourceResourceAllocatorProp, propertyName) == 0)
+ {
+ propertyType = Rm_resourcePropType_RESOURCE_ALLOCATOR;
+ }
+ else if(strcmp(rmResourceNsAssignmentProp, propertyName) == 0)
+ {
+ propertyType = Rm_resourcePropType_NSASSIGNMENT;
+ }
+
+ return (propertyType);
+}
+
+char *Rm_resourceExtractDeviceName(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
+}
+
+void Rm_resourceFreeDeviceName(char *deviceName)
+{
+ 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));
+}
+
+void Rm_resourceFreeResourceRange(Rm_ResourceRange *rangeList)
+{
+ Rm_commonFreeRangeList(rangeList);
+}
+
+/* MODIFY TO RETURN AN ALLOCATOR TYPE INSTEAD OF A STRING??? */
+char *Rm_resourceExtractResourceAllocator(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
+}
+
+void Rm_resourceFreeResourceAllocator(char *resourceAllocatorType)
+{
+ Rm_commonFreeName(resourceAllocatorType);
+}
+
+/* Construct and return a list of NameServer assignments as specified in the Resource DTB */
+Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
+ uint32_t nameLenBytes;
+ uint32_t extractedValue;
+ uint8_t *extractedValueBytePtr;
+ Rm_NsAssignment *startAssignment = NULL;
+ Rm_NsAssignment *newAssignment = NULL;
+ Rm_NsAssignment *prevAssignment = NULL;
+ int8_t i = 0;
+ uint16_t j;
+
+ /* NameServer assignments are stored in the DTB as a null-terminated character
+ * string followed by a 32-bit word containing the value to be assigned to the
+ * name in the string. There is no padding between the string and the 32-bit
+ * word. Therefore the 32-bit word may not be on a 4-byte boundary and must
+ * be constructed upon extraction */
+
+ /* Extract the NameServer assignment data from the DTB */
+ while(i < dtbDataLen)
+ {
+ /* Creat a new NameServer assignment entry */
+ newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
+
+ /* Populate the new assignment entry. Allocate a buffer for the assignment
+ * name string (adding one for the null character). */
+ nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
+ newAssignment->nsName = (char *) Rm_osalMalloc(nameLenBytes);
+ strcpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]));
+
+ /* Extract the 32-bit value */
+ i += nameLenBytes;
+ extractedValueBytePtr = (uint8_t *)&extractedValue;
+ for (j = 0; j < sizeof(uint32_t); j++, i++)
+ {
+ extractedValueBytePtr[j] = dtbNsAssignmentData[i];
+ }
+ /* flip the endianness */
+ newAssignment->resourceValue = fdt32_to_cpu(extractedValue);
+
+ newAssignment->nextNsAssignment = NULL;
+
+ if (prevAssignment == NULL)
+ {
+ /* Save the first entry so it can be returned */
+ startAssignment = newAssignment;
+ }
+ else
+ {
+ prevAssignment->nextNsAssignment = (void *) newAssignment;
+ }
+ prevAssignment = newAssignment;
+ }
+
+ /* Return a pointer to the start of the NameServer assignment list */
+ return (startAssignment);
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted NameServer
+ * assignments. */
+void Rm_resourceFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
+{
+ Rm_NsAssignment *nextAssignment;
+ int32_t nameSize;
+
+ while (nsAssignmentList != NULL)
+ {
+ nextAssignment = nsAssignmentList->nextNsAssignment;
+ /* Free the character array memory first */
+ nameSize = strlen(nsAssignmentList->nsName);
+ /* Add one for the NULL character */
+ Rm_osalFree((void *)nsAssignmentList->nsName, nameSize+1);
+ /* Free the list element */
+ Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
+ nsAssignmentList = nextAssignment;
+ }
+}
+
+/**********************************************************************
+ ***************Policy DTB Parsing Defines and Functions***************
+ **********************************************************************/
+
+/* Policy Properties - These are the property values used
+ * by an application integrator to define the properties of resources
+ * listed in a Resource Manager Policy */
+char rmPolicyPolicyTypeProp[] = "policy-type";
+char rmPolicyInstanceNameProp[] = "instance-name";
+char rmPolicyResourceNameProp[] = "resource-name";
+char rmPolicyResourceAssignedRangesProp[] = "assigned-ranges";
+char rmPolicyResourceAllocationSizesProp[] = "allocation-sizes";
+char rmPolicyResourceAssignedNsNamesProp[] = "assigned-ns-names";
+
+Rm_PolicyPropType Rm_policyGetPropertyType(const char * propertyName)
+{
+ Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
+
+ if(strcmp(rmPolicyPolicyTypeProp, propertyName) == 0)
+ {
+ 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;
+ }
+ else if(strcmp(rmPolicyResourceAllocationSizesProp, propertyName) == 0)
+ {
+ propertyType = Rm_policyPropType_RESOURCE_ALLOCATION_SIZES;
+ }
+ else if(strcmp(rmPolicyResourceAssignedNsNamesProp, propertyName) == 0)
+ {
+ propertyType = Rm_policyPropType_ASSIGNED_NS_NAMES;
+ }
+
+ return (propertyType);
+}
+
+/* MODIFY TO RETURN A POLICY TYPE INSTEAD OF A STRING??? */
+char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
+}
+
+void Rm_policyFreePolicyType(char *policyType)
+{
+ Rm_commonFreeName(policyType);
+}
+
+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));
+}
+
+void Rm_policyFreeResourceAssignedRanges(Rm_ResourceRange *rangeList)
+{
+ Rm_commonFreeRangeList(rangeList);
+}
+
+/* Construct and return a list of allocation sizes as specified in the Policy DTB */
+Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
+ Rm_AllocationSize *startAllocationSize = NULL;
+ Rm_AllocationSize *newAllocationSize = NULL;
+ Rm_AllocationSize *prevAllocationSize = NULL;
+ uint32_t i;
+
+ /* Allocation sizes are stored in the DTB as a list of 32-bit words. The DTB
+ * gives properties lengths in bytes so the length returned from the DTB
+ * should be a multiple of the number of bytes a uint32_t. */
+ if (dtbDataLen % sizeof(uint32_t))
+ {
+ return (NULL);
+ }
+
+ /* Extract the allocation size data from the DTB */
+ for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
+ {
+ /* Creat a new allocation size entry */
+ newAllocationSize = (Rm_AllocationSize *) Rm_osalMalloc(sizeof(Rm_AllocationSize));
+ /* Populate the new allocation size entry. The endianness of the value extracted must
+ * be flipped */
+ newAllocationSize->allocationSize = fdt32_to_cpu(dtbRangeData[i]);
+ newAllocationSize->nextAllocationSize = NULL;
+
+ /* Allocation size linked list pointer accounting */
+ if (prevAllocationSize == NULL)
+ {
+ /* Save the first entry so it can be returned */
+ startAllocationSize = newAllocationSize;
+ }
+ else
+ {
+ prevAllocationSize->nextAllocationSize = (void *) newAllocationSize;
+ }
+
+ prevAllocationSize = newAllocationSize;
+ }
+
+ /* Return a pointer to the start of the allocation size list */
+ return (startAllocationSize);
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
+void Rm_policyFreeAllocationSizesList (Rm_AllocationSize *allocationSizeList)
+{
+ Rm_AllocationSize *nextAllocationSize;
+
+ while (allocationSizeList != NULL)
+ {
+ nextAllocationSize = allocationSizeList->nextAllocationSize;
+ Rm_osalFree((void *)allocationSizeList, sizeof(Rm_AllocationSize));
+ allocationSizeList = nextAllocationSize;
+ }
+}
+
+/* Construct and return a list of assigned NameServer names as specified in the Policy DTB */
+Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int32_t dtbDataLen)
+{
+ uint8_t *dtbAssignedNsNamesData = (uint8_t *)dtbDataPtr;
+ uint32_t nameLenBytes;
+ Rm_AssignedNsNames *startAssignedName = NULL;
+ Rm_AssignedNsNames *newAssignedName = NULL;
+ Rm_AssignedNsNames *prevAssignedName = NULL;
+ int8_t i = 0;
+
+ /* Assigned NameServer names are stored in the DTB as a block of null-terminated
+ * character strings. There is no padding between the strings. */
+
+ /* Extract the assigned NameServer name data from the DTB */
+ while(i < dtbDataLen)
+ {
+ /* Creat a new assigned NameServer name entry */
+ newAssignedName = (Rm_AssignedNsNames *) Rm_osalMalloc(sizeof(Rm_AssignedNsNames));
+
+ /* Populate the new assigned name entry. Allocate a buffer for the assigned
+ * name string (adding one for the null character). */
+ nameLenBytes = strlen((char *) &dtbAssignedNsNamesData[i]) + 1;
+ newAssignedName->assignedName = (char *) Rm_osalMalloc(nameLenBytes);
+ strcpy(newAssignedName->assignedName, ((char *) &dtbAssignedNsNamesData[i]));
+
+ newAssignedName->nextAssignedName = NULL;
+
+ if (prevAssignedName == NULL)
+ {
+ /* Save the first entry so it can be returned */
+ startAssignedName = newAssignedName;
+ }
+ else
+ {
+ prevAssignedName->nextAssignedName = (void *) newAssignedName;
+ }
+ prevAssignedName = newAssignedName;
+ }
+
+ /* Return a pointer to the start of the assigned NameServer names list */
+ return (startAssignedName);
+}
+
+/* Function to clean up the memory allocated for a linked list of extracted
+ * assigned NameServer names. */
+void Rm_policyFreeAssignmentNsNamesList (Rm_AssignedNsNames *assignedNsNamesList)
+{
+ Rm_AssignedNsNames *nextAssignedName;
+ int32_t nameSize;
+
+ while (assignedNsNamesList != NULL)
+ {
+ nextAssignedName = assignedNsNamesList->nextAssignedName;
+ /* Free the character array memory first */
+ nameSize = strlen(assignedNsNamesList->assignedName);
+ /* Add one for the NULL character */
+ Rm_osalFree((void *)assignedNsNamesList->assignedName, nameSize+1);
+ /* Free the list element */
+ Rm_osalFree((void *)assignedNsNamesList, sizeof(Rm_AssignedNsNames));
+ assignedNsNamesList = nextAssignedName;
+ }
+}
+
+/**
+@}
+*/
+
+