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