From e0828e2414d52a1f9ca38ddd9688e7ff18a39751 Mon Sep 17 00:00:00 2001 From: Justin Sobota Date: Fri, 30 Nov 2012 11:51:02 -0500 Subject: [PATCH] Missed a file... --- src/rm_dtb_util.c | 511 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 src/rm_dtb_util.c diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c new file mode 100644 index 0000000..d5bda93 --- /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 + +/* RM internal API includes */ +#include + +/* RM OSAL layer */ +#include + +/* LIBFDT includes */ +#include +#include + +/********************************************************************** + ********************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; + } +} + +/** +@} +*/ + + -- 2.39.2