Coverity bug fixes
[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-2013, 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 external API includes */
44 #include <ti/drv/rm/rm.h>
46 /* RM internal API includes */
47 #include <ti/drv/rm/include/rm_internal.h>
48 #include <ti/drv/rm/include/rm_dtb_utilloc.h>
50 /* RM OSAL layer */
51 #include <rm_osal.h>
53 /* LIBFDT includes */
54 #include <ti/drv/rm/util/libfdt/libfdt.h>
55 #include <ti/drv/rm/util/libfdt/libfdt_env.h>
57 /**********************************************************************
58  ************ Global Resource List (GRL) Parsing Globals **************
59  **********************************************************************/
61 /* Resource List Properties - These are the property values used
62  * by an application integrator to define the properties of resources
63  * listed in the Device Global Resource List (GRL) */
64 const char dtbUtilResRangeProp[]        = "resource-range";
65 const char dtbUtilResLinuxAliasProp[]   = "linux-dtb-alias";
66 const char dtbUtilResNsAssignmentProp[] = "ns-assignment";
68 /**********************************************************************
69  *********************** Policy Parsing Globals ***********************
70  **********************************************************************/
72 /* Policy Properties - These are the property values used
73  * by an application integrator to define the properties of resources
74  * listed in a Resource Manager Policy */
75 const char dtbUtilPolicyValidInstances[]      = "valid-instances";
76 const char dtbUtilPolicyAssignments[]         = "assignments";
77 const char dtbUtilPolicyCdAllocationSize[]    = "cd-allocation-size";
78 const char dtbUtilPolicyAllocationAlignment[] = "allocation-alignment";
80 /**********************************************************************
81  ******************* Common DTB Parsing Functions *********************
82  **********************************************************************/
84 /* FUNCTION PURPOSE: Extracts ranges from a DTB
85  ***********************************************************************
86  * DESCRIPTION: Returns a list of ranges extracted from a DTB
87  *              file.  A range in the DTB is specified as <x y> where
88  *              x is a base value and y is a length value.  Ranges can
89  *              be chained in the DTB with comma separation.
90  *              Example:
91  *                  <0 10>,
92  *                  <20 100>,
93  *                  <200 100>;
94  *                  Results in a list of three ranges.
95  */
96 static Rm_ResourceRange *dtbUtilCommonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
97 {
98     uint32_t         *dtbRangeData = (uint32_t *)dtbDataPtr;
99     Rm_ResourceRange *startRange = NULL;
100     Rm_ResourceRange *newRange = NULL;
101     Rm_ResourceRange *prevRange = NULL;
102     uint32_t i;
103     
104     /* Ranges are stored in the DTB as a list of 32-bit words.  The number of 32-bit
105      * words in the DTB ranges field should be even since ranges are specified in a 
106      * base, lenth format. The DTB gives properties lengths in bytes so the length
107      * returned from the DTB should be a multiple of the number of bytes in two
108      * uint32_ts. */
109     if (dtbDataLen % (2 * sizeof(uint32_t))) {
110         return (NULL);
111     }
113     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2) {
114         newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
115         newRange->base = fdt32_to_cpu(dtbRangeData[i]);
116         newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
117         newRange->nextRange = NULL;
118         
119         if (prevRange == NULL) {
120             startRange = newRange;
121         }
122         else {
123             prevRange->nextRange = newRange;
124         }
125         prevRange = newRange;
126     }
127     return (startRange);
130 /* FUNCTION PURPOSE: Deletes a range list
131  ***********************************************************************
132  * DESCRIPTION: Frees the memory associated with a list of ranges 
133  *              that were extracted from a DTB.
134  */
135 static void dtbUtilCommonFreeRangeList(Rm_ResourceRange *rangeList)
137     Rm_ResourceRange *nextRange;
138     
139     while (rangeList) {
140         nextRange = rangeList->nextRange;
141         Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
142         rangeList = nextRange;
143     }
146 /* FUNCTION PURPOSE: Extracts values from a DTB
147  ***********************************************************************
148  * DESCRIPTION: Returns a list of values extracted from a DTB
149  *              file.  A value in the DTB is specified as <x> where
150  *              x is a numerical value.  Values can be chained in the 
151  *              DTB with comma separation.
152  *              Example:
153  *                  <10>,
154  *                  <20>,
155  *                  <30>;
156  *                  Results in a list of three values.
157  */
158 static Rm_ResourceValue *dtbUtilCommonExtractValueList(const void *dtbDataPtr, int32_t dtbDataLen)
160     uint32_t         *dtbRangeData = (uint32_t *)dtbDataPtr;
161     Rm_ResourceValue *startValue = NULL;
162     Rm_ResourceValue *newValue = NULL;
163     Rm_ResourceValue *prevValue = NULL;
164     uint32_t          i;
165     
166     /* Values are stored in the DTB as a list of 32-bit words. The DTB 
167      * gives properties lengths in bytes so the length returned from the DTB 
168      * should be a multiple of the number of bytes a uint32_t. */
169     if (dtbDataLen % sizeof(uint32_t)) {
170         return (NULL);
171     }
172     
173     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
174         newValue = (Rm_ResourceValue *) Rm_osalMalloc(sizeof(Rm_ResourceValue));
175         newValue->value = fdt32_to_cpu(dtbRangeData[i]);
176         newValue->nextValue = NULL;
177         
178         if (prevValue == NULL) {
179             startValue = newValue;
180         }
181         else {
182             prevValue->nextValue = newValue;
183         }
184         prevValue = newValue;
185     }
186     return (startValue);
189 /* FUNCTION PURPOSE: Deletes a value list
190  ***********************************************************************
191  * DESCRIPTION: Frees the memory associated with a list of values 
192  *              that were extracted from a DTB.
193  */
194 static void dtbUtilCommonFreeValueList (Rm_ResourceValue *valueList)
196     Rm_ResourceValue *nextValue;
197     
198     while (valueList) {
199         nextValue = valueList->nextValue;
200         Rm_osalFree((void *)valueList, sizeof(Rm_ResourceValue));
201         valueList = nextValue;
202     }
205 /**********************************************************************
206  ************** Global Resource List Parsing Functions ****************
207  **********************************************************************/
209 /* FUNCTION PURPOSE: Returns the GRL property type
210  ***********************************************************************
211  * DESCRIPTION: Returns the GRL property type associated with the 
212  *              property name specified.
213  */
214 Rm_ResourcePropType rmDtbUtilResGetPropertyType(const char * propertyName)
216     Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
218     if(strcmp(dtbUtilResRangeProp, propertyName) == 0) {
219         propertyType = Rm_resourcePropType_RESOURCE_RANGE;
220     }
221     else if(strcmp(dtbUtilResLinuxAliasProp, propertyName) == 0) {
222         propertyType = Rm_resourcePropType_RESOURCE_LINUX_ALIAS;
223     }    
224     else if(strcmp(dtbUtilResNsAssignmentProp, propertyName) == 0) {
225         propertyType = Rm_resourcePropType_NSASSIGNMENT;
226     }
227     return (propertyType);
230 /* FUNCTION PURPOSE: Extracts a resource range list from a GRL DTB
231  ***********************************************************************
232  * DESCRIPTION: Returns a list of resource ranges extracted from a GRL
233  *              DTB.  A resource range in the DTB is specified as <x y> 
234  *              where x is resource base and y is a resource length
235  *              starting from x.  Resource ranges can be chained in the 
236  *              GRL DTB with comma separation.
237  *              Example:
238  *                  <0 10>,
239  *                  <10 10>,
240  *                  <20 10>;
241  *                  Results in a list of three resource ranges.
242  */
243 Rm_ResourceRange *rmDtbUtilResExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
245     return(dtbUtilCommonExtractRange(dtbDataPtr, dtbDataLen));
248 /* FUNCTION PURPOSE: Deletes a resource range list
249  ***********************************************************************
250  * DESCRIPTION: Frees the memory associated with a list of resource 
251  *              ranges that were extracted from a GRL DTB.
252  */
253 void rmDtbUtilResFreeRange(Rm_ResourceRange *rangeList)
255     dtbUtilCommonFreeRangeList(rangeList);
258 /* FUNCTION PURPOSE: Extracts a Linux alias list from a GRL DTB
259  ***********************************************************************
260  * DESCRIPTION: Returns a list of Linux alias paths extracted from a GRL
261  *              DTB.  A Linux alias path in the DTB is specified as a 
262  *              space separated string following by list of numerical 
263  *              values.  Each word within the space separated string 
264  *              defines a node from the Linux DTB in the path to the
265  *              Linux alias value for the resource.  The numerical values
266  *              specify the number of values at the end of the path in
267  *              the Linux DTB.  Linux alias paths can be chained in the 
268  *              GRL DTB with comma separation.
269  *              Example:
270  *                  "LinuxDtbNode1 LinuxDtbNode2 resourcehere", <1 1>,
271  *                  "LinuxDtbNode1 LinuxDtbNode2 anotherRes", <2 2 3>,
272  *                  Results in a list of two Linux alias paths.
273  */
274 Rm_LinuxAlias *rmDtbUtilResExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
276     uint8_t       *dtbAliasData = (uint8_t *)dtbDataPtr;
277     uint32_t       pathLenBytes;
278     uint32_t       extractedValue;
279     uint8_t       *extractedValueBytePtr;        
280     Rm_LinuxAlias *startAlias = NULL;
281     Rm_LinuxAlias *newAlias = NULL;
282     Rm_LinuxAlias *prevAlias = NULL;
283     uint32_t       numOffsets;
284     int32_t        i = 0;
285     uint16_t       j;
286     
287     /* Linux aliases are stored in the DTB as a list space-separated path node names within
288      * null terminated string.  Following the path string 
289      * will be two or three values specifying the fields in the linux DTB property
290      * that contain the relevant data.  The first value specifies the number of offsets
291      * that follow.  If two field offsets are specified the 
292      * Linux DTB contains a base + length. If   one field offset is specified the 
293      * Linux DTB contains a single value for reservation.  There is no padding between
294      * the path string and the 32-bit offsets.  Therefore the 32-bit offsets may not be on
295      * a 4-byte boundary and must be constructed upon extraction */
296     while(i < dtbDataLen) {
297         newAlias = (Rm_LinuxAlias *) Rm_osalMalloc(sizeof(Rm_LinuxAlias));
298         
299         pathLenBytes = strlen((char *) &dtbAliasData[i]) + 1;
300         newAlias->path = (char *) Rm_osalMalloc(pathLenBytes);
301         rm_strncpy(newAlias->path, ((char *) &dtbAliasData[i]), pathLenBytes);
302         
303         /* Extract 32-bit value specifying number of offsets that follow */
304         i += pathLenBytes;
305         extractedValueBytePtr = (uint8_t *)&extractedValue;
306         for (j = 0; j < sizeof(uint32_t); j++, i++) {
307             extractedValueBytePtr[j] = dtbAliasData[i];
308         }
309         numOffsets = fdt32_to_cpu(extractedValue);
311         if ((numOffsets == 1) || (numOffsets == 2)) {
312             /* Always extract the base value */
313             extractedValueBytePtr = (uint8_t *)&extractedValue;
314             for (j = 0; j < sizeof(uint32_t); j++, i++) {
315                 extractedValueBytePtr[j] = dtbAliasData[i];
316             }            
317             newAlias->baseOffset = fdt32_to_cpu(extractedValue);
319             if (numOffsets == 2) {
320                 for (j = 0; j < sizeof(uint32_t); j++, i++) {
321                     extractedValueBytePtr[j] = dtbAliasData[i];
322                 }
323                 newAlias->lengthOffset = fdt32_to_cpu(extractedValue);
324             }
325             else {
326                 newAlias->lengthOffset = RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET;
327             }            
328             
329             newAlias->nextLinuxAlias = NULL;
330             if (prevAlias == NULL) {
331                 startAlias = newAlias;
332             }
333             else {
334                 prevAlias->nextLinuxAlias = newAlias;
335             }
336             prevAlias = newAlias;
337         }
338         else {
339             Rm_osalFree((void *)newAlias->path, pathLenBytes);
340             Rm_osalFree((void *)newAlias, sizeof(Rm_LinuxAlias));
341             while (startAlias) {
342                 newAlias = startAlias->nextLinuxAlias;
343                 pathLenBytes = strlen(startAlias->path);        
344                 Rm_osalFree((void *)startAlias->path, pathLenBytes + 1);
345                 Rm_osalFree((void *)startAlias, sizeof(Rm_LinuxAlias));
346                 startAlias = newAlias;
347             }   
348             *result = RM_ERROR_GRL_INVALID_LINUX_ALIAS_FORMAT;
349             return(NULL);
350         }
351     }
352     return (startAlias);
355 /* FUNCTION PURPOSE: Deletes a Linux Alias list
356  ***********************************************************************
357  * DESCRIPTION: Frees the memory associated with a list of Linux 
358  *              aliases that were extracted from a GRL DTB.
359  */
360 void rmDtbUtilResFreeLinuxAlias(Rm_LinuxAlias *aliasList)
362     Rm_LinuxAlias *nextAlias;
363     int32_t        pathSize;
364        
365     while (aliasList) {
366         nextAlias = aliasList->nextLinuxAlias;
367         pathSize = strlen(aliasList->path);        
368         Rm_osalFree((void *)aliasList->path, pathSize + 1);
369         Rm_osalFree((void *)aliasList, sizeof(Rm_LinuxAlias));
370         aliasList = nextAlias;
371     }
374 /* FUNCTION PURPOSE: Extracts a NS assignment list from a GRL DTB
375  ***********************************************************************
376  * DESCRIPTION: Returns a list of NameServer assignments extracted from
377  *              a GRL DTB.  A NameServer assignment is specified with
378  *              a string representing the NameServer name following by
379  *              a range in <base length> format.  NameServer assignments
380  *              can be chained in the GRL DTB with comma separation.
381  *              Example:
382  *                  "Name1", <0 10>,
383  *                  "Name2", <10 10>,
384  *                  "Another Name", <20 10>;
385  *                  Results in a list of three NameServer assignments.
386  */
387 Rm_NsAssignment *rmDtbUtilResExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
389     uint8_t         *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
390     uint32_t         nameLenBytes;
391     uint32_t         extractedValue;
392     uint8_t         *extractedValueBytePtr;        
393     Rm_NsAssignment *startAssignment = NULL;
394     Rm_NsAssignment *newAssignment = NULL;
395     Rm_NsAssignment *prevAssignment = NULL;
396     int32_t          i = 0;
397     uint16_t         j;
398     
399     /* NameServer assignments are stored in the DTB as a null-terminated character
400      * string followed by a 32-bit word containing the value to be assigned to the
401      * name in the string.  There is no padding between the string and the 32-bit 
402      * word.  Therefore the 32-bit word may not be on a 4-byte boundary and must
403      * be constructed upon extraction */
404     while(i < dtbDataLen) {
405         newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
406         
407         nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
408         if (nameLenBytes > RM_NAME_MAX_CHARS) {
409             Rm_osalFree((void *)newAssignment, sizeof(Rm_NsAssignment));
410             while (startAssignment) {
411                 newAssignment = startAssignment->nextNsAssignment;
412                 Rm_osalFree((void *)startAssignment, sizeof(Rm_NsAssignment));
413                 startAssignment = newAssignment;
414             }
415             *result = RM_ERROR_GRL_NS_ASSIGNMENT_NAME_TOO_LONG;
416             return(NULL);
417         }        
418         rm_strncpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]), RM_NAME_MAX_CHARS);
419         
420         /* Extract 32-bit base value and flip endian */
421         i += nameLenBytes;
422         extractedValueBytePtr = (uint8_t *)&extractedValue;
423         for (j = 0; j < sizeof(uint32_t); j++, i++) {
424             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
425         }
426         newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
428         /* Extract 32-bit length value and flip endian */
429         for (j = 0; j < sizeof(uint32_t); j++, i++) {
430             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
431         }
432         newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
433         
434         newAssignment->nextNsAssignment = NULL;
435         if (prevAssignment == NULL) {
436             startAssignment = newAssignment;
437         }
438         else {
439             prevAssignment->nextNsAssignment = newAssignment;
440         }
441         prevAssignment = newAssignment;
442     }
443     
444     return (startAssignment);
447 /* FUNCTION PURPOSE: Deletes a NameServer assignment list
448  ***********************************************************************
449  * DESCRIPTION: Frees the memory associated with a list of NameServer 
450  *              assignments that were extracted from a GRL DTB.
451  */
452 void rmDtbUtilResFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
454     Rm_NsAssignment *nextAssignment;
455     
456     while (nsAssignmentList) {
457         nextAssignment = nsAssignmentList->nextNsAssignment;
458         Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
459         nsAssignmentList = nextAssignment;
460     }
463 /**********************************************************************
464  ********************** Policy Parsing Functions **********************
465  **********************************************************************/
467 /* FUNCTION PURPOSE: Returns the Policy property type
468  ***********************************************************************
469  * DESCRIPTION: Returns the Policy property type associated with the 
470  *              property name specified.
471  */
472 Rm_PolicyPropType rmDtbUtilPolicyGetPropertyType(const char * propertyName)
474     Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
476     if(strcmp(dtbUtilPolicyAssignments, propertyName) == 0) {
477         propertyType = Rm_policyPropType_ASSIGNMENTS;
478     }
479     else if(strcmp(dtbUtilPolicyCdAllocationSize, propertyName) == 0) {
480         propertyType = Rm_policyPropType_CD_ALLOCATION_SIZE;
481     }
482     else if(strcmp(dtbUtilPolicyAllocationAlignment, propertyName) == 0) {
483         propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENT;
484     }    
485     else if(strcmp(dtbUtilPolicyValidInstances, propertyName) == 0) {
486         propertyType = Rm_policyPropType_VALID_INSTANCES;
487     }       
488     return (propertyType);
491 /* FUNCTION PURPOSE: Extracts a policy assignment list from a Policy DTB
492  ***********************************************************************
493  * DESCRIPTION: Returns a list of policy assignments extracted from a 
494  *              Policy DTB.  A policy assignment in the DTB is 
495  *              specified as <x y>, "permissions string" where x is 
496  *              resource base and y is a resource length starting 
497  *              from x.  "permissions string" is string specifying
498  *              which RM instances are allowed to use the resource
499  *              range.  Policy assignments can be chained in the 
500  *              Policy DTB with comma separation.
501  *              Example:
502  *                  <0 10>, "iux = (Rm_Client)",
503  *                  <10 10>, "iu = (*);
504  *                  Results in a list of two policy assignments.
505  */
506 Rm_PolicyAssignment *rmDtbUtilPolicyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen)
508     uint8_t             *dtbAssignmentData = (uint8_t *)dtbDataPtr;
509     uint32_t             permissionsLenBytes;
510     uint32_t             extractedValue;
511     uint8_t             *extractedValueBytePtr;        
512     Rm_PolicyAssignment *startAssignment = NULL;
513     Rm_PolicyAssignment *newAssignment = NULL;
514     Rm_PolicyAssignment *prevAssignment = NULL;
515     int32_t              i = 0;
516     uint16_t             j;
517     
518     /* Policy assignments are stored in the DTB as two 32-bit words containing a 
519      * resource base and length to be assigned the permissions in the defined in
520      * the string that follows.  There is no padding between the 32-bit words and the 
521      * string.  Therefore the 32-bit word may not be on a 4-byte boundary and must
522      * be constructed upon extraction */
523     while(i < dtbDataLen) {
524         newAssignment = (Rm_PolicyAssignment *) Rm_osalMalloc(sizeof(Rm_PolicyAssignment));
526         /* Extract 32-bit resource base value and flip endianness */
527         extractedValueBytePtr = (uint8_t *)&extractedValue;
528         for (j = 0; j < sizeof(uint32_t); j++, i++) {
529             extractedValueBytePtr[j] = dtbAssignmentData[i];
530         }
531         newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
533         /* Extract 32-bit resource length value and flip endianness */
534         for (j = 0; j < sizeof(uint32_t); j++, i++) {
535             extractedValueBytePtr[j] = dtbAssignmentData[i];
536         }
537         newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
539         permissionsLenBytes = strlen((char *) &dtbAssignmentData[i]) + 1;
540         newAssignment->permissionsList = (char *) Rm_osalMalloc(permissionsLenBytes);
541         rm_strncpy(newAssignment->permissionsList, ((char *) &dtbAssignmentData[i]), permissionsLenBytes);
542         i += permissionsLenBytes;
544         newAssignment->nextAssignment = NULL;
545         if (prevAssignment == NULL) {
546             startAssignment = newAssignment;
547         }
548         else {
549             prevAssignment->nextAssignment = newAssignment;
550         }
551         prevAssignment = newAssignment;
552     }
553     return (startAssignment);
556 /* FUNCTION PURPOSE: Deletes a policy assignment list
557  ***********************************************************************
558  * DESCRIPTION: Frees the memory associated with a list of policy 
559  *              assignments that were extracted from a Policy DTB.
560  */
561 void rmDtbUtilPolicyFreeAssignments(Rm_PolicyAssignment *assignmentList)
563     Rm_PolicyAssignment *nextAssignment;
564     int32_t              permissionsSize;
565     
566     while (assignmentList) {
567         nextAssignment = assignmentList->nextAssignment;
568         permissionsSize = strlen(assignmentList->permissionsList);
569         Rm_osalFree((void *)assignmentList->permissionsList, permissionsSize+1);
570         Rm_osalFree((void *)assignmentList, sizeof(Rm_PolicyAssignment));
571         assignmentList = nextAssignment;
572     }
575 /* FUNCTION PURPOSE: Extracts a CD allocation size from a Policy DTB
576  ***********************************************************************
577  * DESCRIPTION: Returns a list of allocation sizes extracted from a
578  *              Policy DTB.  A allocation size in the DTB is specified
579  *              as <x> where x is the allocation size for a resource.
580  *              Allocation sizes can be chained in the Policy DTB with
581  *              comma separation.
582  *              Example:
583  *                  <10>,
584  *                  <100>;
585  *                  Results in a list of two allocation sizes.
586  */
587 Rm_ResourceValue *rmDtbUtilPolicyExtractCdAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
589     return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
592 /* FUNCTION PURPOSE: Deletes a CD allocation sizes list
593  ***********************************************************************
594  * DESCRIPTION: Frees the memory associated with a list of allocation
595  *              sizes that were extracted from a Policy DTB.
596  */
597 void rmDtbUtilPolicyFreeCdAllocationSizes (Rm_ResourceValue *allocationSizeList)
599     dtbUtilCommonFreeValueList(allocationSizeList);
602 /* FUNCTION PURPOSE: Extracts an resource alignment from a Policy DTB
603  ***********************************************************************
604  * DESCRIPTION: Returns a list of resource alignments extracted from a
605  *              Policy DTB.  A resource alignment in the DTB is specified
606  *              as <x> where x is the resource alignment for a resource.
607  *              Resource alignments can be chained in the Policy DTB with
608  *              comma separation.
609  *              Example:
610  *                  <10>,
611  *                  <100>;
612  *                  Results in a list of two resource alignments.
613  */
614 Rm_ResourceValue *rmDtbUtilPolicyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
616     return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
619 /* FUNCTION PURPOSE: Deletes a resource alignments list
620  ***********************************************************************
621  * DESCRIPTION: Frees the memory associated with a list of resource
622  *              alignments that were extracted from a Policy DTB.
623  */
624 void rmDtbUtilPolicyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
626     dtbUtilCommonFreeValueList(alignmentList);
629 /* FUNCTION PURPOSE: Extracts an valid instance list from a Policy DTB
630  ***********************************************************************
631  * DESCRIPTION: Returns a list of valid instances extracted from a
632  *              Policy DTB.  A valid instance in the DTB is specified
633  *              as "instName" where instName is the name of an RM
634  *              instance.  Valid instances can be chained in the 
635  *              Policy DTB with comma separation.
636  *              Example:
637  *                  <Rm_Client>,
638  *                  <Rm_Server>;
639  *                  Results in a list of two valid instances.
640  */
641 Rm_PolicyValidInst *rmDtbUtilPolicyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen,
642                                                          int32_t *result)
644     uint8_t            *dtbValidInstData = (uint8_t *)dtbDataPtr;
645     uint32_t            instLenBytes;       
646     Rm_PolicyValidInst *startInst = NULL;
647     Rm_PolicyValidInst *newInst = NULL;
648     Rm_PolicyValidInst *prevInst = NULL;
649     int32_t             i = 0;
650     
651     /* Valid RM instances are stored in the DTB as a list of null-terminated character
652      * strings. */
653     while(i < dtbDataLen) {
654         newInst = (Rm_PolicyValidInst *) Rm_osalMalloc(sizeof(Rm_PolicyValidInst));
656         instLenBytes = strlen((char *) &dtbValidInstData[i]) + 1;
657         if (instLenBytes > RM_NAME_MAX_CHARS) {
658             Rm_osalFree((void *)newInst, sizeof(Rm_PolicyValidInst));
659             while (startInst) {
660                 newInst = startInst->nextValidInst;
661                 Rm_osalFree((void *)startInst, sizeof(Rm_PolicyValidInst));
662                 startInst = newInst;
663             }
664             *result = RM_ERROR_VALID_INST_NAME_TOO_LONG;
665             return(NULL);
666         }
667         rm_strncpy(newInst->instName, ((char *) &dtbValidInstData[i]), instLenBytes);
668         
669         i += instLenBytes;
671         newInst->nextValidInst = NULL;
673         if (prevInst == NULL) {
674             startInst = newInst;
675         }
676         else {
677             prevInst->nextValidInst = newInst;
678         }
679         prevInst = newInst;
680     }
681     return (startInst);
684 /* FUNCTION PURPOSE: Deletes a valid instnace list
685  ***********************************************************************
686  * DESCRIPTION: Frees the memory associated with a list of valid
687  *              instances that were extracted from a Policy DTB.
688  */
689 void rmDtbUtilPolicyFreeValidInstances (Rm_PolicyValidInst *validInstList)
691     Rm_PolicyValidInst *nextInst;
692     
693     while (validInstList) {
694         nextInst = validInstList->nextValidInst;
695         Rm_osalFree((void *)validInstList, sizeof(Rm_PolicyValidInst));
696         validInstList = nextInst;
697     }
700 /**********************************************************************
701  ****************Linux DTB Parsing Defines and Functions***************
702  **********************************************************************/
704 /* FUNCTION PURPOSE: Extracts a linux value list from a Linux DTB
705  ***********************************************************************
706  * DESCRIPTION: Returns a list of values extracted from a Linux
707  *              DTB.  Linux value in the Linux DTB is specified
708  *              as <w x y z ...> where w x y z ... are a list of
709  *              numerical values.
710  *              Example:
711  *                  <1 5 10 15 20 25>;
712  *                  Results in a list of six Linux values.
713  */
714 Rm_LinuxValueRange *rmDtbUtilLinuxExtractValues(const void *dtbDataPtr, int32_t dtbDataLen)
716     uint32_t           *dtbValueData = (uint32_t *)dtbDataPtr;
717     Rm_LinuxValueRange *startValue = NULL;
718     Rm_LinuxValueRange *newValue = NULL;
719     Rm_LinuxValueRange *prevValue = NULL;
720     uint32_t            i;
721     
722     /* Values are stored in the Linux DTB as a list of 32-bit words.  The number of 32-bit
723      * words in the value field can differ.  depending on the number of values specified. */
724     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
725         newValue = (Rm_LinuxValueRange *) Rm_osalMalloc(sizeof(Rm_LinuxValueRange));
726         /* Endianness of extracted value must be flipped */
727         newValue->value = fdt32_to_cpu(dtbValueData[i]);
728         newValue->nextValue = NULL;
729         
730         if (prevValue == NULL) {
731             startValue = newValue;
732         }
733         else {
734             prevValue->nextValue = newValue;
735         }
736         prevValue = newValue;
737     }
738     return (startValue);
741 /* FUNCTION PURPOSE: Deletes a Linux values list
742  ***********************************************************************
743  * DESCRIPTION: Frees the memory associated with a list of Linux
744  *              values that were extracted from a Linux DTB.
745  */
746 void rmDtbUtilLinuxFreeValues(Rm_LinuxValueRange *valueList)
748     Rm_LinuxValueRange *nextValue;
749     
750     while (valueList) {
751         nextValue = valueList->nextValue;
752         Rm_osalFree((void *)valueList, sizeof(Rm_LinuxValueRange));
753         valueList = nextValue;
754     }