Missed a file...
[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 *Rm_commonExtractName(const void *dtbDataPtr, int32_t dtbDataLen)
61 {
62     char *resourceName = NULL;
63     
64     resourceName = (char *) Rm_osalMalloc(dtbDataLen);
66     /* The resource name is stored as a null terminated string in the DTB
67      * so it's just a straightforward string copy operation to a local
68      * buffer to extract it. */
69     strcpy(resourceName, (char *)dtbDataPtr);
71     return(resourceName);
72 }
74 /* Free memory that was allocated to extract a name property string */
75 void Rm_commonFreeName(char *resourceName)
76 {
77     int32_t nameSize;
78     
79     /* Free the character array memory */
80     nameSize = strlen(resourceName);
81     /* Add one for the NULL character */
82     Rm_osalFree((void *)resourceName, nameSize+1);
83 }
85 /* Construct and return a list of ranges as specified in either the Resource
86  * DTB or a Policy DTB */
87 Rm_ResourceRange *Rm_commonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
88 {
89     uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
90     Rm_ResourceRange *startRange = NULL;
91     Rm_ResourceRange *newRange = NULL;
92     Rm_ResourceRange *prevRange = NULL;
93     uint32_t i;
94     
95     /* Ranges are stored in the DTB as a list of 32-bit words.  The number of 32-bit
96      * words in the DTB ranges field should be even since ranges are specified in a 
97      * base, lenth format. The DTB gives properties lengths in bytes so the length
98      * returned from the DTB should be a multiple of the number of bytes in two
99      * uint32_ts. */
100     if (dtbDataLen % (2 * sizeof(uint32_t)))
101     {
102         /* Return NULL if there are an odd number of range values */
103         return (NULL);
104     }
106     /* Extract the range data from the DTB */
107     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2)
108     {
109         /* Creat a new range entry */
110         newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
111         /* Populate the new range entry.  The endianness of the value extracted must
112          * be flipped */
113         newRange->base = fdt32_to_cpu(dtbRangeData[i]);
114         newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
115         newRange->nextRange = NULL;
116         
117         /* Range linked list pointer accounting */
118         if (prevRange == NULL)
119         {
120             /* Save the first entry so it can be returned */
121             startRange = newRange;
122         }
123         else
124         {
125             prevRange->nextRange = (void *) newRange;
126         }
128         prevRange = newRange;
129     }
131     /* Return a pointer to the start of the range list */
132     return (startRange);
135 /* Function to clean up the memory allocated for a linked list of extracted ranges */
136 void Rm_commonFreeRangeList(Rm_ResourceRange *rangeList)
138     Rm_ResourceRange *nextRange;
139     
140     while (rangeList != NULL)
141     {
142         nextRange = rangeList->nextRange;
143         Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
144         rangeList = nextRange;
145     }
148 /**********************************************************************
149  ***********Resource List DTB Parsing Defines and Functions************
150  **********************************************************************/
152 /* Resource List Properties - These are the property values used
153  * by an application integrator to define the properties of resources
154  * listed in the Device Resource List */
155 char rmResourceDeviceNameProp[] = "device-name";
156 char rmResourceResourceNameProp[] = "resource-name";
157 char rmResourceResourceRangeProp[] = "resource-range";
158 char rmResourceResourceAllocatorProp[] = "allocator";
159 char rmResourceNsAssignmentProp[] = "ns-assignment";
161 Rm_ResourcePropType Rm_resourceGetPropertyType(const char * propertyName)
163     Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
165     if(strcmp(rmResourceDeviceNameProp, propertyName) == 0)
166     {
167         propertyType = Rm_resourcePropType_DEVICE_NAME;
168     }    
169     else if(strcmp(rmResourceResourceNameProp, propertyName) == 0)
170     {
171         propertyType = Rm_resourcePropType_RESOURCE_NAME;
172     }
173     else if(strcmp(rmResourceResourceRangeProp, propertyName) == 0)
174     {
175         propertyType = Rm_resourcePropType_RESOURCE_RANGE;
176     }
177     else if(strcmp(rmResourceResourceAllocatorProp, propertyName) == 0)
178     {
179         propertyType = Rm_resourcePropType_RESOURCE_ALLOCATOR;
180     }
181     else if(strcmp(rmResourceNsAssignmentProp, propertyName) == 0)
182     {
183         propertyType = Rm_resourcePropType_NSASSIGNMENT;
184     }
186     return (propertyType);
189 char *Rm_resourceExtractDeviceName(const void *dtbDataPtr, int32_t dtbDataLen)
191     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
194 void Rm_resourceFreeDeviceName(char *deviceName)
196     Rm_commonFreeName(deviceName);
199 char *Rm_resourceExtractResourceName(const void *dtbDataPtr, int32_t dtbDataLen)
201     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
204 void Rm_resourceFreeResourceName(char *resourceName)
206     Rm_commonFreeName(resourceName);
209 Rm_ResourceRange *Rm_resourceExtractResourceRange(const void *dtbDataPtr, int32_t dtbDataLen)
211     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
214 void Rm_resourceFreeResourceRange(Rm_ResourceRange *rangeList)
216     Rm_commonFreeRangeList(rangeList);
219 /* MODIFY TO RETURN AN ALLOCATOR TYPE INSTEAD OF A STRING??? */
220 char *Rm_resourceExtractResourceAllocator(const void *dtbDataPtr, int32_t dtbDataLen)
222     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
225 void Rm_resourceFreeResourceAllocator(char *resourceAllocatorType)
227     Rm_commonFreeName(resourceAllocatorType);
230 /* Construct and return a list of NameServer assignments as specified in the Resource DTB */
231 Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen)
233     uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
234     uint32_t nameLenBytes;
235     uint32_t extractedValue;
236     uint8_t *extractedValueBytePtr;        
237     Rm_NsAssignment *startAssignment = NULL;
238     Rm_NsAssignment *newAssignment = NULL;
239     Rm_NsAssignment *prevAssignment = NULL;
240     int8_t i = 0;
241     uint16_t j;
242     
243     /* NameServer assignments are stored in the DTB as a null-terminated character
244      * string followed by a 32-bit word containing the value to be assigned to the
245      * name in the string.  There is no padding between the string and the 32-bit 
246      * word.  Therefore the 32-bit word may not be on a 4-byte boundary and must
247      * be constructed upon extraction */
249     /* Extract the NameServer assignment data from the DTB */
250     while(i < dtbDataLen)
251     {
252         /* Creat a new NameServer assignment entry */
253         newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
254         
255         /* Populate the new assignment entry.  Allocate a buffer for the assignment
256          * name string (adding one for the null character). */
257         nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
258         newAssignment->nsName = (char *) Rm_osalMalloc(nameLenBytes);
259         strcpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]));
260         
261         /* Extract the 32-bit value */
262         i += nameLenBytes;
263         extractedValueBytePtr = (uint8_t *)&extractedValue;
264         for (j = 0; j < sizeof(uint32_t); j++, i++)
265         {
266             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
267         }
268         /* flip the endianness */
269         newAssignment->resourceValue = fdt32_to_cpu(extractedValue);
271         newAssignment->nextNsAssignment = NULL;
273         if (prevAssignment == NULL)
274         {
275             /* Save the first entry so it can be returned */
276             startAssignment = newAssignment;
277         }
278         else
279         {
280             prevAssignment->nextNsAssignment = (void *) newAssignment;
281         }
282         prevAssignment = newAssignment;
283     }
285     /* Return a pointer to the start of the NameServer assignment list */
286     return (startAssignment);
289 /* Function to clean up the memory allocated for a linked list of extracted NameServer
290  * assignments. */
291 void Rm_resourceFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
293     Rm_NsAssignment *nextAssignment;
294     int32_t nameSize;
295     
296     while (nsAssignmentList != NULL)
297     {
298         nextAssignment = nsAssignmentList->nextNsAssignment;
299         /* Free the character array memory first */
300         nameSize = strlen(nsAssignmentList->nsName);
301         /* Add one for the NULL character */
302         Rm_osalFree((void *)nsAssignmentList->nsName, nameSize+1);
303         /* Free the list element */
304         Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
305         nsAssignmentList = nextAssignment;
306     }
309 /**********************************************************************
310  ***************Policy DTB Parsing Defines and Functions***************
311  **********************************************************************/
313 /* Policy Properties - These are the property values used
314  * by an application integrator to define the properties of resources
315  * listed in a Resource Manager Policy */
316 char rmPolicyPolicyTypeProp[] = "policy-type";
317 char rmPolicyInstanceNameProp[] = "instance-name";
318 char rmPolicyResourceNameProp[] = "resource-name";
319 char rmPolicyResourceAssignedRangesProp[] = "assigned-ranges";
320 char rmPolicyResourceAllocationSizesProp[] = "allocation-sizes";
321 char rmPolicyResourceAssignedNsNamesProp[] = "assigned-ns-names";
323 Rm_PolicyPropType Rm_policyGetPropertyType(const char * propertyName)
325     Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
327     if(strcmp(rmPolicyPolicyTypeProp, propertyName) == 0)
328     {
329         propertyType = Rm_policyPropType_POLICY_TYPE;
330     } 
331     else if(strcmp(rmPolicyInstanceNameProp, propertyName) == 0)
332     {
333         propertyType = Rm_policyPropType_INSTANCE_NAME;
334     }    
335     else if(strcmp(rmPolicyResourceNameProp, propertyName) == 0)
336     {
337         propertyType = Rm_policyPropType_RESOURCE_NAME;
338     }
339     else if(strcmp(rmPolicyResourceAssignedRangesProp, propertyName) == 0)
340     {
341         propertyType = Rm_policyPropType_RESOURCE_ASSIGNED_RANGES;
342     }
343     else if(strcmp(rmPolicyResourceAllocationSizesProp, propertyName) == 0)
344     {
345         propertyType = Rm_policyPropType_RESOURCE_ALLOCATION_SIZES;
346     }
347     else if(strcmp(rmPolicyResourceAssignedNsNamesProp, propertyName) == 0)
348     {
349         propertyType = Rm_policyPropType_ASSIGNED_NS_NAMES;
350     }
352     return (propertyType);
355 /* MODIFY TO RETURN A POLICY TYPE INSTEAD OF A STRING??? */
356 char *Rm_policyExtractPolicyType(const void *dtbDataPtr, int32_t dtbDataLen)
358     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
361 void Rm_policyFreePolicyType(char *policyType)
363     Rm_commonFreeName(policyType);
366 char *Rm_policyExtractInstanceName(const void *dtbDataPtr, int32_t dtbDataLen)
368     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
371 void Rm_policyFreeInstanceName(char *instanceName)
373     Rm_commonFreeName(instanceName);
376 Rm_ResourceRange *Rm_policyExtractResourceAssignedRanges(const void *dtbDataPtr, int32_t dtbDataLen)
378     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
381 void Rm_policyFreeResourceAssignedRanges(Rm_ResourceRange *rangeList)
383     Rm_commonFreeRangeList(rangeList);
386 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
387 Rm_AllocationSize *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
389     uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
390     Rm_AllocationSize *startAllocationSize = NULL;
391     Rm_AllocationSize *newAllocationSize = NULL;
392     Rm_AllocationSize *prevAllocationSize = NULL;
393     uint32_t i;
394     
395     /* Allocation sizes are stored in the DTB as a list of 32-bit words. The DTB 
396      * gives properties lengths in bytes so the length returned from the DTB 
397      * should be a multiple of the number of bytes a uint32_t. */
398     if (dtbDataLen % sizeof(uint32_t))
399     {
400         return (NULL);
401     }
403     /* Extract the allocation size data from the DTB */
404     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
405     {
406         /* Creat a new allocation size entry */
407         newAllocationSize = (Rm_AllocationSize *) Rm_osalMalloc(sizeof(Rm_AllocationSize));
408         /* Populate the new allocation size entry.  The endianness of the value extracted must
409          * be flipped */
410         newAllocationSize->allocationSize = fdt32_to_cpu(dtbRangeData[i]);
411         newAllocationSize->nextAllocationSize = NULL;
412         
413         /* Allocation size linked list pointer accounting */
414         if (prevAllocationSize == NULL)
415         {
416             /* Save the first entry so it can be returned */
417             startAllocationSize = newAllocationSize;
418         }
419         else
420         {
421             prevAllocationSize->nextAllocationSize = (void *) newAllocationSize;
422         }
424         prevAllocationSize = newAllocationSize;
425     }
427     /* Return a pointer to the start of the allocation size list */
428     return (startAllocationSize);
431 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
432 void Rm_policyFreeAllocationSizesList (Rm_AllocationSize *allocationSizeList)
434     Rm_AllocationSize *nextAllocationSize;
435     
436     while (allocationSizeList != NULL)
437     {
438         nextAllocationSize = allocationSizeList->nextAllocationSize;
439         Rm_osalFree((void *)allocationSizeList, sizeof(Rm_AllocationSize));
440         allocationSizeList = nextAllocationSize;
441     }
444 /* Construct and return a list of assigned NameServer names as specified in the Policy DTB */
445 Rm_AssignedNsNames *Rm_policyExtractAssignedNsNames(const void *dtbDataPtr, int32_t dtbDataLen)
447     uint8_t *dtbAssignedNsNamesData = (uint8_t *)dtbDataPtr;
448     uint32_t nameLenBytes;        
449     Rm_AssignedNsNames *startAssignedName = NULL;
450     Rm_AssignedNsNames *newAssignedName = NULL;
451     Rm_AssignedNsNames *prevAssignedName = NULL;
452     int8_t i = 0;
453     
454     /* Assigned NameServer names are stored in the DTB as a block of null-terminated 
455      * character strings.  There is no padding between the strings. */
457     /* Extract the assigned NameServer name data from the DTB */
458     while(i < dtbDataLen)
459     {
460         /* Creat a new assigned NameServer name entry */
461         newAssignedName = (Rm_AssignedNsNames *) Rm_osalMalloc(sizeof(Rm_AssignedNsNames));
462         
463         /* Populate the new assigned name entry.  Allocate a buffer for the assigned
464          * name string (adding one for the null character). */
465         nameLenBytes = strlen((char *) &dtbAssignedNsNamesData[i]) + 1;
466         newAssignedName->assignedName = (char *) Rm_osalMalloc(nameLenBytes);
467         strcpy(newAssignedName->assignedName, ((char *) &dtbAssignedNsNamesData[i]));
469         newAssignedName->nextAssignedName = NULL;
471         if (prevAssignedName == NULL)
472         {
473             /* Save the first entry so it can be returned */
474             startAssignedName = newAssignedName;
475         }
476         else
477         {
478             prevAssignedName->nextAssignedName = (void *) newAssignedName;
479         }
480         prevAssignedName = newAssignedName;
481     }
483     /* Return a pointer to the start of the assigned NameServer names list */
484     return (startAssignedName);
487 /* Function to clean up the memory allocated for a linked list of extracted 
488  * assigned NameServer names. */
489 void Rm_policyFreeAssignmentNsNamesList (Rm_AssignedNsNames *assignedNsNamesList)
491     Rm_AssignedNsNames *nextAssignedName;
492     int32_t nameSize;
493     
494     while (assignedNsNamesList != NULL)
495     {
496         nextAssignedName = assignedNsNamesList->nextAssignedName;
497         /* Free the character array memory first */
498         nameSize = strlen(assignedNsNamesList->assignedName);
499         /* Add one for the NULL character */
500         Rm_osalFree((void *)assignedNsNamesList->assignedName, nameSize+1);
501         /* Free the list element */
502         Rm_osalFree((void *)assignedNsNamesList, sizeof(Rm_AssignedNsNames));
503         assignedNsNamesList = nextAssignedName;
504     }
507 /**
508 @}
509 */