]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blob - src/rm_dtb_util.c
Integrated red-black tree algorithm for tree allocators
[keystone-rtos/rm-lld.git] / src / rm_dtb_util.c
1 /**
2  *   @file  rm_dtb_util.c
3  *
4  *   @brief   
5  *      This is the Resource Manager Resource List and Policy DTB parsing 
6  *      utility source
7  *
8  *  \par
9  *  ============================================================================
10  *  @n   (C) Copyright 2012, Texas Instruments, Inc.
11  * 
12  *  Redistribution and use in source and binary forms, with or without 
13  *  modification, are permitted provided that the following conditions 
14  *  are met:
15  *
16  *    Redistributions of source code must retain the above copyright 
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  *    Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the 
21  *    documentation and/or other materials provided with the   
22  *    distribution.
23  *
24  *    Neither the name of Texas Instruments Incorporated nor the names of
25  *    its contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
29  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
30  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
32  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
33  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
34  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
37  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
38  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  *  \par
41 */
43 /* RM Types */
44 #include <ti/drv/rm/rm_types.h>
46 /* RM internal API includes */
47 #include <ti/drv/rm/include/rm_dtb_utilloc.h>
49 /* RM OSAL layer */
50 #include <rm_osal.h>
52 /* LIBFDT includes */
53 #include <ti/drv/rm/src/libfdt/libfdt.h>
54 #include <ti/drv/rm/src/libfdt/libfdt_env.h>
56 /**********************************************************************
57  ********************Common DTB Parsing Functions**********************
58  **********************************************************************/
60 char rmDtbStartingNode[] = "\0";
61  
62 char *Rm_commonExtractName(const void *dtbDataPtr, int32_t dtbDataLen)
63 {
64     char *resourceName = NULL;
65     
66     resourceName = (char *) Rm_osalMalloc(dtbDataLen);
68     /* The resource name is stored as a null terminated string in the DTB
69      * so it's just a straightforward string copy operation to a local
70      * buffer to extract it. */
71     strcpy(resourceName, (char *)dtbDataPtr);
73     return(resourceName);
74 }
76 /* Free memory that was allocated to extract a name property string */
77 void Rm_commonFreeName(char *resourceName)
78 {
79     int32_t nameSize;
80     
81     /* Free the character array memory */
82     nameSize = strlen(resourceName);
83     /* Add one for the NULL character */
84     Rm_osalFree((void *)resourceName, nameSize+1);
85 }
87 /* Construct and return a list of ranges as specified in either the Resource
88  * DTB or a Policy DTB */
89 Rm_ResourceRange *Rm_commonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
90 {
91     uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
92     Rm_ResourceRange *startRange = NULL;
93     Rm_ResourceRange *newRange = NULL;
94     Rm_ResourceRange *prevRange = NULL;
95     uint32_t i;
96     
97     /* Ranges are stored in the DTB as a list of 32-bit words.  The number of 32-bit
98      * words in the DTB ranges field should be even since ranges are specified in a 
99      * base, lenth format. The DTB gives properties lengths in bytes so the length
100      * returned from the DTB should be a multiple of the number of bytes in two
101      * uint32_ts. */
102     if (dtbDataLen % (2 * sizeof(uint32_t)))
103     {
104         /* Return NULL if there are an odd number of range values */
105         return (NULL);
106     }
108     /* Extract the range data from the DTB */
109     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2)
110     {
111         /* Creat a new range entry */
112         newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
113         /* Populate the new range entry.  The endianness of the value extracted must
114          * be flipped */
115         newRange->base = fdt32_to_cpu(dtbRangeData[i]);
116         newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
117         newRange->nextRange = NULL;
118         
119         /* Range linked list pointer accounting */
120         if (prevRange == NULL)
121         {
122             /* Save the first entry so it can be returned */
123             startRange = newRange;
124         }
125         else
126         {
127             prevRange->nextRange = (void *) newRange;
128         }
130         prevRange = newRange;
131     }
133     /* Return a pointer to the start of the range list */
134     return (startRange);
137 /* Function to clean up the memory allocated for a linked list of extracted ranges */
138 void Rm_commonFreeRangeList(Rm_ResourceRange *rangeList)
140     Rm_ResourceRange *nextRange;
141     
142     while (rangeList != NULL)
143     {
144         nextRange = rangeList->nextRange;
145         Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
146         rangeList = nextRange;
147     }
150 /**********************************************************************
151  ***********Resource List DTB Parsing Defines and Functions************
152  **********************************************************************/
154 /* Resource List Properties - These are the property values used
155  * by an application integrator to define the properties of resources
156  * listed in the Device Resource List */
157 char rmResourceDeviceNameProp[] = "device-name";
158 char rmResourceResourceRangeProp[] = "resource-range";
159 char rmResourceResourceAllocatorProp[] = "allocator";
160 char rmResourceNsAssignmentProp[] = "ns-assignment";
162 Rm_ResourcePropType Rm_resourceGetPropertyType(const char * propertyName)
164     Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
166     if(strcmp(rmResourceDeviceNameProp, propertyName) == 0)
167     {
168         propertyType = Rm_resourcePropType_DEVICE_NAME;
169     }    
170     else if(strcmp(rmResourceResourceRangeProp, propertyName) == 0)
171     {
172         propertyType = Rm_resourcePropType_RESOURCE_RANGE;
173     }
174     else if(strcmp(rmResourceResourceAllocatorProp, propertyName) == 0)
175     {
176         propertyType = Rm_resourcePropType_RESOURCE_ALLOCATOR;
177     }
178     else if(strcmp(rmResourceNsAssignmentProp, propertyName) == 0)
179     {
180         propertyType = Rm_resourcePropType_NSASSIGNMENT;
181     }
183     return (propertyType);
186 char *Rm_resourceExtractDeviceName(const void *dtbDataPtr, int32_t dtbDataLen)
188     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
191 void Rm_resourceFreeDeviceName(char *deviceName)
193     Rm_commonFreeName(deviceName);
196 Rm_ResourceRange *Rm_resourceExtractResourceRange(const void *dtbDataPtr, int32_t dtbDataLen)
198     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
201 void Rm_resourceFreeResourceRange(Rm_ResourceRange *rangeList)
203     Rm_commonFreeRangeList(rangeList);
206 /* MODIFY TO RETURN AN ALLOCATOR TYPE INSTEAD OF A STRING??? */
207 char *Rm_resourceExtractResourceAllocator(const void *dtbDataPtr, int32_t dtbDataLen)
209     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
212 void Rm_resourceFreeResourceAllocator(char *resourceAllocatorType)
214     Rm_commonFreeName(resourceAllocatorType);
217 /* Construct and return a list of NameServer assignments as specified in the Resource DTB */
218 Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen)
220     uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
221     uint32_t nameLenBytes;
222     uint32_t extractedValue;
223     uint8_t *extractedValueBytePtr;        
224     Rm_NsAssignment *startAssignment = NULL;
225     Rm_NsAssignment *newAssignment = NULL;
226     Rm_NsAssignment *prevAssignment = NULL;
227     int8_t i = 0;
228     uint16_t j;
229     
230     /* NameServer assignments are stored in the DTB as a null-terminated character
231      * string followed by a 32-bit word containing the value to be assigned to the
232      * name in the string.  There is no padding between the string and the 32-bit 
233      * word.  Therefore the 32-bit word may not be on a 4-byte boundary and must
234      * be constructed upon extraction */
236     /* Extract the NameServer assignment data from the DTB */
237     while(i < dtbDataLen)
238     {
239         /* Creat a new NameServer assignment entry */
240         newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
241         
242         /* Populate the new assignment entry.  Allocate a buffer for the assignment
243          * name string (adding one for the null character). */
244         nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
245         newAssignment->nsName = (char *) Rm_osalMalloc(nameLenBytes);
246         strcpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]));
247         
248         /* Extract the 32-bit value */
249         i += nameLenBytes;
250         extractedValueBytePtr = (uint8_t *)&extractedValue;
251         for (j = 0; j < sizeof(uint32_t); j++, i++)
252         {
253             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
254         }
255         /* flip the endianness */
256         newAssignment->resourceValue = fdt32_to_cpu(extractedValue);
258         newAssignment->nextNsAssignment = NULL;
260         if (prevAssignment == NULL)
261         {
262             /* Save the first entry so it can be returned */
263             startAssignment = newAssignment;
264         }
265         else
266         {
267             prevAssignment->nextNsAssignment = (void *) newAssignment;
268         }
269         prevAssignment = newAssignment;
270     }
272     /* Return a pointer to the start of the NameServer assignment list */
273     return (startAssignment);
276 /* Function to clean up the memory allocated for a linked list of extracted NameServer
277  * assignments. */
278 void Rm_resourceFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
280     Rm_NsAssignment *nextAssignment;
281     int32_t nameSize;
282     
283     while (nsAssignmentList != NULL)
284     {
285         nextAssignment = nsAssignmentList->nextNsAssignment;
286         /* Free the character array memory first */
287         nameSize = strlen(nsAssignmentList->nsName);
288         /* Add one for the NULL character */
289         Rm_osalFree((void *)nsAssignmentList->nsName, nameSize+1);
290         /* Free the list element */
291         Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
292         nsAssignmentList = nextAssignment;
293     }
296 /**********************************************************************
297  ***************Policy DTB Parsing Defines and Functions***************
298  **********************************************************************/
300 /* Policy Properties - These are the property values used
301  * by an application integrator to define the properties of resources
302  * listed in a Resource Manager Policy */
303 char rmPolicyPolicyTypeProp[] = "policy-type";
304 char rmPolicyResourceAssignedRangesProp[] = "assigned-ranges";
305 char rmPolicyResourceAllocationSizesProp[] = "allocation-sizes";
306 char rmPolicyResourceAssignedNsNamesProp[] = "assigned-ns-names";
308 Rm_PolicyPropType Rm_policyGetPropertyType(const char * propertyName)
310     Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
312     if(strcmp(rmPolicyPolicyTypeProp, propertyName) == 0)
313     {
314         propertyType = Rm_policyPropType_POLICY_TYPE;
315     } 
316     else if(strcmp(rmPolicyResourceAssignedRangesProp, propertyName) == 0)
317     {
318         propertyType = Rm_policyPropType_RESOURCE_ASSIGNED_RANGES;
319     }
320     else if(strcmp(rmPolicyResourceAllocationSizesProp, propertyName) == 0)
321     {
322         propertyType = Rm_policyPropType_RESOURCE_ALLOCATION_SIZES;
323     }
324     else if(strcmp(rmPolicyResourceAssignedNsNamesProp, propertyName) == 0)
325     {
326         propertyType = Rm_policyPropType_ASSIGNED_NS_NAMES;
327     }
329     return (propertyType);
332 /* MODIFY TO RETURN A POLICY TYPE INSTEAD OF A STRING??? */
333 char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen)
335     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
338 void Rm_policyFreePolicyType(char *policyType)
340     Rm_commonFreeName(policyType);
343 Rm_ResourceRange *Rm_policyExtractResourceAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen)
345     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
348 void Rm_policyFreeResourceAssignedRanges(Rm_ResourceRange *rangeList)
350     Rm_commonFreeRangeList(rangeList);
353 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
354 Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
356     uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
357     Rm_AllocationSize *startAllocationSize = NULL;
358     Rm_AllocationSize *newAllocationSize = NULL;
359     Rm_AllocationSize *prevAllocationSize = NULL;
360     uint32_t i;
361     
362     /* Allocation sizes are stored in the DTB as a list of 32-bit words. The DTB 
363      * gives properties lengths in bytes so the length returned from the DTB 
364      * should be a multiple of the number of bytes a uint32_t. */
365     if (dtbDataLen % sizeof(uint32_t))
366     {
367         return (NULL);
368     }
370     /* Extract the allocation size data from the DTB */
371     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
372     {
373         /* Creat a new allocation size entry */
374         newAllocationSize = (Rm_AllocationSize *) Rm_osalMalloc(sizeof(Rm_AllocationSize));
375         /* Populate the new allocation size entry.  The endianness of the value extracted must
376          * be flipped */
377         newAllocationSize->allocationSize = fdt32_to_cpu(dtbRangeData[i]);
378         newAllocationSize->nextAllocationSize = NULL;
379         
380         /* Allocation size linked list pointer accounting */
381         if (prevAllocationSize == NULL)
382         {
383             /* Save the first entry so it can be returned */
384             startAllocationSize = newAllocationSize;
385         }
386         else
387         {
388             prevAllocationSize->nextAllocationSize = (void *) newAllocationSize;
389         }
391         prevAllocationSize = newAllocationSize;
392     }
394     /* Return a pointer to the start of the allocation size list */
395     return (startAllocationSize);
398 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
399 void Rm_policyFreeAllocationSizesList (Rm_AllocationSize *allocationSizeList)
401     Rm_AllocationSize *nextAllocationSize;
402     
403     while (allocationSizeList != NULL)
404     {
405         nextAllocationSize = allocationSizeList->nextAllocationSize;
406         Rm_osalFree((void *)allocationSizeList, sizeof(Rm_AllocationSize));
407         allocationSizeList = nextAllocationSize;
408     }
411 /* Construct and return a list of assigned NameServer names as specified in the Policy DTB */
412 Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int32_t dtbDataLen)
414     uint8_t *dtbAssignedNsNamesData = (uint8_t *)dtbDataPtr;
415     uint32_t nameLenBytes;        
416     Rm_AssignedNsNames *startAssignedName = NULL;
417     Rm_AssignedNsNames *newAssignedName = NULL;
418     Rm_AssignedNsNames *prevAssignedName = NULL;
419     int8_t i = 0;
420     
421     /* Assigned NameServer names are stored in the DTB as a block of null-terminated 
422      * character strings.  There is no padding between the strings. */
424     /* Extract the assigned NameServer name data from the DTB */
425     while(i < dtbDataLen)
426     {
427         /* Creat a new assigned NameServer name entry */
428         newAssignedName = (Rm_AssignedNsNames *) Rm_osalMalloc(sizeof(Rm_AssignedNsNames));
429         
430         /* Populate the new assigned name entry.  Allocate a buffer for the assigned
431          * name string (adding one for the null character). */
432         nameLenBytes = strlen((char *) &dtbAssignedNsNamesData[i]) + 1;
433         newAssignedName->assignedName = (char *) Rm_osalMalloc(nameLenBytes);
434         strcpy(newAssignedName->assignedName, ((char *) &dtbAssignedNsNamesData[i]));
436         newAssignedName->nextAssignedName = NULL;
438         if (prevAssignedName == NULL)
439         {
440             /* Save the first entry so it can be returned */
441             startAssignedName = newAssignedName;
442         }
443         else
444         {
445             prevAssignedName->nextAssignedName = (void *) newAssignedName;
446         }
447         prevAssignedName = newAssignedName;
448     }
450     /* Return a pointer to the start of the assigned NameServer names list */
451     return (startAssignedName);
454 /* Function to clean up the memory allocated for a linked list of extracted 
455  * assigned NameServer names. */
456 void Rm_policyFreeAssignmentNsNamesList (Rm_AssignedNsNames *assignedNsNamesList)
458     Rm_AssignedNsNames *nextAssignedName;
459     int32_t nameSize;
460     
461     while (assignedNsNamesList != NULL)
462     {
463         nextAssignedName = assignedNsNamesList->nextAssignedName;
464         /* Free the character array memory first */
465         nameSize = strlen(assignedNsNamesList->assignedName);
466         /* Add one for the NULL character */
467         Rm_osalFree((void *)assignedNsNamesList->assignedName, nameSize+1);
468         /* Free the list element */
469         Rm_osalFree((void *)assignedNsNamesList, sizeof(Rm_AssignedNsNames));
470         assignedNsNamesList = nextAssignedName;
471     }
474 /**
475 @}
476 */