]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blob - src/rm_dtb_util.c
Rewriting policy definition feature
[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 /* Construct and return a list of values as specified in the Policy DTB */
151 Rm_ResourceValue *Rm_commonExtractValueList(const void *dtbDataPtr, int32_t dtbDataLen)
153     uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
154     Rm_ResourceValue *startValue = NULL;
155     Rm_ResourceValue *newValue = NULL;
156     Rm_ResourceValue *prevValue = NULL;
157     uint32_t i;
158     
159     /* Values are stored in the DTB as a list of 32-bit words. The DTB 
160      * gives properties lengths in bytes so the length returned from the DTB 
161      * should be a multiple of the number of bytes a uint32_t. */
162     if (dtbDataLen % sizeof(uint32_t))
163     {
164         return (NULL);
165     }
167     /* Extract the value data from the DTB */
168     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
169     {
170         /* Creat a new allocation size entry */
171         newValue = (Rm_ResourceValue *) Rm_osalMalloc(sizeof(Rm_ResourceValue));
172         /* Populate the new allocation size entry.  The endianness of the value extracted must
173          * be flipped */
174         newValue->value = fdt32_to_cpu(dtbRangeData[i]);
175         newValue->nextValue = NULL;
176         
177         /* Resource value linked list pointer accounting */
178         if (prevValue == NULL)
179         {
180             /* Save the first entry so it can be returned */
181             startValue = newValue;
182         }
183         else
184         {
185             prevValue->nextValue = (void *) newValue;
186         }
188         prevValue = newValue;
189     }
191     /* Return a pointer to the start of the resource value list */
192     return (startValue);
195 /* Function to clean up the memory allocated for a linked list of extracted values */
196 void Rm_commonFreeValueList (Rm_ResourceValue *valueList)
198     Rm_ResourceValue *nextValue;
199     
200     while (valueList != NULL)
201     {
202         nextValue = valueList->nextValue;
203         Rm_osalFree((void *)valueList, sizeof(Rm_ResourceValue));
204         valueList = nextValue;
205     }
209 /**********************************************************************
210  ***********Resource List DTB Parsing Defines and Functions************
211  **********************************************************************/
213 /* Resource List Properties - These are the property values used
214  * by an application integrator to define the properties of resources
215  * listed in the Device Resource List */
216 char rmResourceDeviceNameProp[] = "device-name";
217 char rmResourceRangeProp[] = "resource-range";
218 char rmResourceLinuxAliasProp[] = "linux-dtb-alias";
219 char rmResourceNsAssignmentProp[] = "ns-assignment";
221 Rm_ResourcePropType Rm_resourceGetPropertyType(const char * propertyName)
223     Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
225     if(strcmp(rmResourceDeviceNameProp, propertyName) == 0)
226     {
227         propertyType = Rm_resourcePropType_DEVICE_NAME;
228     }    
229     else if(strcmp(rmResourceRangeProp, propertyName) == 0)
230     {
231         propertyType = Rm_resourcePropType_RESOURCE_RANGE;
232     }
233     else if(strcmp(rmResourceLinuxAliasProp, propertyName) == 0)
234     {
235         propertyType = Rm_resourcePropType_RESOURCE_LINUX_ALIAS;
236     }    
237     else if(strcmp(rmResourceNsAssignmentProp, propertyName) == 0)
238     {
239         propertyType = Rm_resourcePropType_NSASSIGNMENT;
240     }
242     return (propertyType);
245 char *Rm_resourceExtractDeviceName(const void *dtbDataPtr, int32_t dtbDataLen)
247     return(Rm_commonExtractName(dtbDataPtr, dtbDataLen));
250 void Rm_resourceFreeDeviceName(char *deviceName)
252     Rm_commonFreeName(deviceName);
255 Rm_ResourceRange *Rm_resourceExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
257     return(Rm_commonExtractRange(dtbDataPtr, dtbDataLen));
260 void Rm_resourceFreeRange(Rm_ResourceRange *rangeList)
262     Rm_commonFreeRangeList(rangeList);
265 Rm_LinuxAlias *Rm_resourceExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen)
267     uint8_t *dtbAliasData = (uint8_t *)dtbDataPtr;
268     uint32_t pathLenBytes;
269     uint32_t extractedValue;
270     uint8_t *extractedValueBytePtr;        
271     Rm_LinuxAlias *startAlias = NULL;
272     Rm_LinuxAlias *newAlias = NULL;
273     Rm_LinuxAlias *prevAlias = NULL;
274     uint32_t numOffsets;
275     int32_t i = 0;
276     uint16_t j;
277     
278     /* Linux aliases are stored in the DTB as a list space-separated path node names within
279      * null terminated string.  Following the path string 
280      * will be two or three values specifying the fields in the linux DTB property
281      * that contain the relevant data.  The first value specifies the number of offsets
282      * that follow.  If two field offsets are specified the 
283      * Linux DTB contains a base + length. If   one field offset is specified the 
284      * Linux DTB contains a single value for reservation.  There is no padding between
285      * the path string and the 32-bit offsets.  Therefore the 32-bit offsets may not be on
286      * a 4-byte boundary and must be constructed upon extraction */
288     /* Extract the alias data from the DTB */
289     while(i < dtbDataLen)
290     {
291         /* Creat a new alias entry */
292         newAlias = (Rm_LinuxAlias *) Rm_osalMalloc(sizeof(Rm_LinuxAlias));
293         
294         /* Populate the new alias entry.  Allocate a buffer for the path
295          * string (adding one for the null character). */
296         pathLenBytes = strlen((char *) &dtbAliasData[i]) + 1;
297         newAlias->path = (char *) Rm_osalMalloc(pathLenBytes);
298         strcpy(newAlias->path, ((char *) &dtbAliasData[i]));
299         
300         /* Extract the 32-bit value specifying the number of offsets that follow */
301         i += pathLenBytes;
302         extractedValueBytePtr = (uint8_t *)&extractedValue;
303         for (j = 0; j < sizeof(uint32_t); j++, i++)
304         {
305             extractedValueBytePtr[j] = dtbAliasData[i];
306         }
307         /* flip the endianness */
308         numOffsets = fdt32_to_cpu(extractedValue);
310         /* numOffsets should always be either 1 or 2 */
311         if ((numOffsets == 1) || (numOffsets == 2))
312         {
313             /* Always extract the base value */
314             extractedValueBytePtr = (uint8_t *)&extractedValue;
315             for (j = 0; j < sizeof(uint32_t); j++, i++)
316             {
317                 extractedValueBytePtr[j] = dtbAliasData[i];
318             }            
319             newAlias->baseOffset = fdt32_to_cpu(extractedValue);
321             if (numOffsets == 2)
322             {
323                 /* Extract the 32-bit length value if two offsets were specified */
324                 for (j = 0; j < sizeof(uint32_t); j++, i++)
325                 {
326                     extractedValueBytePtr[j] = dtbAliasData[i];
327                 }
328                 /* flip the endianness */
329                 newAlias->lengthOffset = fdt32_to_cpu(extractedValue);
330             }
331             else
332             {
333                 newAlias->lengthOffset = RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET;
334             }            
335             
336             newAlias->nextLinuxAlias = NULL;
337             
338             if (prevAlias == NULL)
339             {
340                 /* Save the first entry so it can be returned */
341                 startAlias = newAlias;
342             }
343             else
344             {
345                 prevAlias->nextLinuxAlias = (void *) newAlias;
346             }
347             prevAlias = newAlias;
348         }
349         else
350         {
351             /* Return NULL */
352             startAlias = NULL;
353             break;
354         }
355     }
357     /* Return a pointer to the start of the NameServer assignment list */
358     return (startAlias);
361 /* Function to clean up the memory allocated for a linked list of extracted Linux
362  * aliases. */
363 void Rm_resourceFreeLinuxAlias(Rm_LinuxAlias *aliasList)
365     Rm_LinuxAlias *nextAlias;
366     int32_t pathSize;
367        
368     while (aliasList != NULL)
369     {
370         nextAlias = aliasList->nextLinuxAlias;
371         /* Free the path string memory first */
372         pathSize = strlen(aliasList->path);        
373         Rm_osalFree((void *)aliasList->path, pathSize + 1);
374         /* Free the list element */
375         Rm_osalFree((void *)aliasList, sizeof(Rm_LinuxAlias));
376         aliasList = nextAlias;
377     }
380 /* Construct and return a list of NameServer assignments as specified in the Resource DTB */
381 Rm_NsAssignment *Rm_resourceExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen)
383     uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
384     uint32_t nameLenBytes;
385     uint32_t extractedValue;
386     uint8_t *extractedValueBytePtr;        
387     Rm_NsAssignment *startAssignment = NULL;
388     Rm_NsAssignment *newAssignment = NULL;
389     Rm_NsAssignment *prevAssignment = NULL;
390     int8_t i = 0;
391     uint16_t j;
392     
393     /* NameServer assignments are stored in the DTB as a null-terminated character
394      * string followed by a 32-bit word containing the value to be assigned to the
395      * name in the string.  There is no padding between the string and the 32-bit 
396      * word.  Therefore the 32-bit word may not be on a 4-byte boundary and must
397      * be constructed upon extraction */
399     /* Extract the NameServer assignment data from the DTB */
400     while(i < dtbDataLen)
401     {
402         /* Creat a new NameServer assignment entry */
403         newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
404         
405         /* Populate the new assignment entry.  Allocate a buffer for the assignment
406          * name string (adding one for the null character). */
407         nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
408         newAssignment->nsName = (char *) Rm_osalMalloc(nameLenBytes);
409         strcpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]));
410         
411         /* Extract the 32-bit base value */
412         i += nameLenBytes;
413         extractedValueBytePtr = (uint8_t *)&extractedValue;
414         for (j = 0; j < sizeof(uint32_t); j++, i++)
415         {
416             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
417         }
418         /* flip the endianness */
419         newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
421         /* Extract the 32-bit length value */
422         for (j = 0; j < sizeof(uint32_t); j++, i++)
423         {
424             extractedValueBytePtr[j] = dtbNsAssignmentData[i];
425         }
426         /* flip the endianness */
427         newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
429         newAssignment->nextNsAssignment = NULL;
431         if (prevAssignment == NULL)
432         {
433             /* Save the first entry so it can be returned */
434             startAssignment = newAssignment;
435         }
436         else
437         {
438             prevAssignment->nextNsAssignment = (void *) newAssignment;
439         }
440         prevAssignment = newAssignment;
441     }
443     /* Return a pointer to the start of the NameServer assignment list */
444     return (startAssignment);
447 /* Function to clean up the memory allocated for a linked list of extracted NameServer
448  * assignments. */
449 void Rm_resourceFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
451     Rm_NsAssignment *nextAssignment;
452     int32_t nameSize;
453     
454     while (nsAssignmentList != NULL)
455     {
456         nextAssignment = nsAssignmentList->nextNsAssignment;
457         /* Free the character array memory first */
458         nameSize = strlen(nsAssignmentList->nsName);
459         /* Add one for the NULL character */
460         Rm_osalFree((void *)nsAssignmentList->nsName, nameSize+1);
461         /* Free the list element */
462         Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
463         nsAssignmentList = nextAssignment;
464     }
467 /**********************************************************************
468  ***************Policy DTB Parsing Defines and Functions***************
469  **********************************************************************/
471 /* Policy Properties - These are the property values used
472  * by an application integrator to define the properties of resources
473  * listed in a Resource Manager Policy */
474 char rmPolicyValidInstances[] = "valid-instances";
475 char rmPolicyAssignments[] = "assignments";
476 char rmPolicyAllocationSizes[] = "allocation-sizes";
477 char rmPolicyAllocationAlignments[] = "allocation-alignments";
479 Rm_PolicyPropType Rm_policyGetPropertyType(const char * propertyName)
481     Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
483     if(strcmp(rmPolicyAssignments, propertyName) == 0)
484     {
485         propertyType = Rm_policyPropType_ASSIGNMENTS;
486     }
487     else if(strcmp(rmPolicyAllocationSizes, propertyName) == 0)
488     {
489         propertyType = Rm_policyPropType_ALLOCATION_SIZES;
490     }
491     else if(strcmp(rmPolicyAllocationAlignments, propertyName) == 0)
492     {
493         propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENTS;
494     }    
495     else if(strcmp(rmPolicyValidInstances, propertyName) == 0)
496     {
497         propertyType = Rm_policyPropType_VALID_INSTANCES;
498     }       
500     return (propertyType);
503 Rm_PolicyAssignment *Rm_policyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen)
505     uint8_t *dtbAssignmentData = (uint8_t *)dtbDataPtr;
506     uint32_t permissionsLenBytes;
507     uint32_t extractedValue;
508     uint8_t *extractedValueBytePtr;        
509     Rm_PolicyAssignment *startAssignment = NULL;
510     Rm_PolicyAssignment *newAssignment = NULL;
511     Rm_PolicyAssignment *prevAssignment = NULL;
512     int8_t i = 0;
513     uint16_t j;
514     
515     /* Policy assignments are stored in the DTB as two 32-bit words containing a 
516      * resource base and length to be assigned the permissions in the defined in
517      * the string that follows.  There is no padding between the 32-bit words and the 
518      * string.  Therefore the 32-bit word may not be on a 4-byte boundary and must
519      * be constructed upon extraction */
521     /* Extract the policy assignment data from the DTB */
522     while(i < dtbDataLen)
523     {
524         /* Creat a new NameServer assignment entry */
525         newAssignment = (Rm_PolicyAssignment *) Rm_osalMalloc(sizeof(Rm_PolicyAssignment));
527         /* Extract the 32-bit resource base value */
528         extractedValueBytePtr = (uint8_t *)&extractedValue;
529         for (j = 0; j < sizeof(uint32_t); j++, i++)
530         {
531             extractedValueBytePtr[j] = dtbAssignmentData[i];
532         }
533         /* flip the endianness */
534         newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
536         /* Extract the 32-bit resource length value */
537         for (j = 0; j < sizeof(uint32_t); j++, i++)
538         {
539             extractedValueBytePtr[j] = dtbAssignmentData[i];
540         }
541         /* flip the endianness */
542         newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
544         /* Allocate a buffer for the assignment permissions string (adding one for 
545          * the null character). */
546         permissionsLenBytes = strlen((char *) &dtbAssignmentData[i]) + 1;
547         newAssignment->permissionsList = (char *) Rm_osalMalloc(permissionsLenBytes);
548         strcpy(newAssignment->permissionsList, ((char *) &dtbAssignmentData[i]));
549         i += permissionsLenBytes;
551         newAssignment->nextAssignment = NULL;
553         if (prevAssignment == NULL)
554         {
555             /* Save the first entry so it can be returned */
556             startAssignment = newAssignment;
557         }
558         else
559         {
560             prevAssignment->nextAssignment = newAssignment;
561         }
562         prevAssignment = newAssignment;
563     }
565     /* Return a pointer to the start of the policy assignment list */
566     return (startAssignment);
569 void Rm_policyFreeAssignments(Rm_PolicyAssignment *assignmentList)
571     Rm_PolicyAssignment *nextAssignment;
572     int32_t permissionsSize;
573     
574     while (assignmentList != NULL)
575     {
576         nextAssignment = assignmentList->nextAssignment;
577         /* Free the character array memory first */
578         permissionsSize = strlen(assignmentList->permissionsList);
579         /* Add one for the NULL character */
580         Rm_osalFree((void *)assignmentList->permissionsList, permissionsSize+1);
581         /* Free the list element */
582         Rm_osalFree((void *)assignmentList, sizeof(Rm_PolicyAssignment));
583         assignmentList = nextAssignment;
584     }
587 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
588 Rm_ResourceValue *Rm_policyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
590     return(Rm_commonExtractValueList(dtbDataPtr, dtbDataLen));
593 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
594 void Rm_policyFreeAllocationSizes (Rm_ResourceValue *allocationSizeList)
596     Rm_commonFreeValueList(allocationSizeList);
599 /* Construct and return a list of allocation alignments as specified in the Policy DTB */
600 Rm_ResourceValue *Rm_policyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
602     return(Rm_commonExtractValueList(dtbDataPtr, dtbDataLen));
605 /* Function to clean up the memory allocated for a linked list of extracted allocation alignments */
606 void Rm_policyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
608     Rm_commonFreeValueList(alignmentList);
611 Rm_PolicyValidInst *Rm_policyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen)
613     uint8_t *dtbValidInstData = (uint8_t *)dtbDataPtr;
614     uint32_t instLenBytes;       
615     Rm_PolicyValidInst *startInst = NULL;
616     Rm_PolicyValidInst *newInst = NULL;
617     Rm_PolicyValidInst *prevInst = NULL;
618     int8_t i = 0;
619     
620     /* Valid RM instances are stored in the DTB as a list of null-terminated character
621      * strings. */
623     /* Extract the valid instance data from the DTB */
624     while(i < dtbDataLen)
625     {
626         /* Creat a new valid instance entry */
627         newInst = (Rm_PolicyValidInst *) Rm_osalMalloc(sizeof(Rm_PolicyValidInst));
628         
629         /* Populate the new instance entry.  Allocate a buffer for the instance
630          * name string (adding one for the null character). */
631         instLenBytes = strlen((char *) &dtbValidInstData[i]) + 1;
632         newInst->instName = (char *) Rm_osalMalloc(instLenBytes);
633         strcpy(newInst->instName, ((char *) &dtbValidInstData[i]));
634         
635         i += instLenBytes;
637         newInst->nextValidInst = NULL;
639         if (prevInst == NULL)
640         {
641             /* Save the first entry so it can be returned */
642             startInst = newInst;
643         }
644         else
645         {
646             prevInst->nextValidInst = newInst;
647         }
648         prevInst = newInst;
649     }
651     /* Return a pointer to the start of the valid instance list */
652     return (startInst);
655 void Rm_policyFreeValidInstances (Rm_PolicyValidInst *validInstList)
657     Rm_PolicyValidInst *nextInst;
658     int32_t instSize;
659     
660     while (validInstList != NULL)
661     {
662         nextInst = validInstList->nextValidInst;
663         /* Free the character array memory first */
664         instSize = strlen(validInstList->instName);
665         /* Add one for the NULL character */
666         Rm_osalFree((void *)validInstList->instName, instSize+1);
667         /* Free the list element */
668         Rm_osalFree((void *)validInstList, sizeof(Rm_PolicyValidInst));
669         validInstList = nextInst;
670     }
673 /**********************************************************************
674  ****************Linux DTB Parsing Defines and Functions***************
675  **********************************************************************/
677 Rm_LinuxValueRange *Rm_linuxExtractValues(const void *dtbDataPtr, int32_t dtbDataLen)
679     uint32_t *dtbValueData = (uint32_t *)dtbDataPtr;
680     Rm_LinuxValueRange *startValue = NULL;
681     Rm_LinuxValueRange *newValue = NULL;
682     Rm_LinuxValueRange *prevValue = NULL;
683     uint32_t i;
684     
685     /* Values are stored in the Linux DTB as a list of 32-bit words.  The number of 32-bit
686      * words in the value field can differ.  depending on the number of values specified. */
688     /* Extract the value data from the Linux DTB */
689     for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++)
690     {
691         /* Creat a new value entry */
692         newValue = (Rm_LinuxValueRange *) Rm_osalMalloc(sizeof(Rm_LinuxValueRange));
693         /* Populate the new value entry.  The endianness of the value extracted must
694          * be flipped */
695         newValue->value = fdt32_to_cpu(dtbValueData[i]);
696         newValue->nextValue = NULL;
697         
698         /* Value linked list pointer accounting */
699         if (prevValue == NULL)
700         {
701             /* Save the first entry so it can be returned */
702             startValue = newValue;
703         }
704         else
705         {
706             prevValue->nextValue = (void *) newValue;
707         }
709         prevValue = newValue;
710     }
712     /* Return a pointer to the start of the value list */
713     return (startValue);
716 void Rm_linuxFreeValues(Rm_LinuxValueRange *valueList)
718     Rm_LinuxValueRange *nextValue;
719     
720     while (valueList != NULL)
721     {
722         nextValue = valueList->nextValue;
723         Rm_osalFree((void *)valueList, sizeof(Rm_LinuxValueRange));
724         valueList = nextValue;
725     }
728 /**
729 @}
730 */