3754b6d0051b2fdad70c26ee463ce1a0c5625700
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 ******************** Common DTB Parsing Globals **********************
61 **********************************************************************/
63 /**********************************************************************
64 *************** Global Resource List Parsing Globals *****************
65 **********************************************************************/
67 /* Resource List Properties - These are the property values used
68 * by an application integrator to define the properties of resources
69 * listed in the Device Global Resource List */
70 const char dtbUtilResRangeProp[] = "resource-range";
71 const char dtbUtilResLinuxAliasProp[] = "linux-dtb-alias";
72 const char dtbUtilResNsAssignmentProp[] = "ns-assignment";
74 /**********************************************************************
75 *********************** Policy Parsing Globals ***********************
76 **********************************************************************/
78 /* Policy Properties - These are the property values used
79 * by an application integrator to define the properties of resources
80 * listed in a Resource Manager Policy */
81 const char dtbUtilPolicyValidInstances[] = "valid-instances";
82 const char dtbUtilPolicyAssignments[] = "assignments";
83 const char dtbUtilPolicyAllocationSize[] = "allocation-size";
84 const char dtbUtilPolicyAllocationAlignment[] = "allocation-alignment";
86 /**********************************************************************
87 ******************* Common DTB Parsing Functions *********************
88 **********************************************************************/
90 /* Construct and return a list of ranges as specified in either the Resource
91 * DTB or a Policy DTB */
92 static Rm_ResourceRange *dtbUtilCommonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
93 {
94 uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
95 Rm_ResourceRange *startRange = NULL;
96 Rm_ResourceRange *newRange = NULL;
97 Rm_ResourceRange *prevRange = NULL;
98 uint32_t i;
100 /* Ranges are stored in the DTB as a list of 32-bit words. The number of 32-bit
101 * words in the DTB ranges field should be even since ranges are specified in a
102 * base, lenth format. The DTB gives properties lengths in bytes so the length
103 * returned from the DTB should be a multiple of the number of bytes in two
104 * uint32_ts. */
105 if (dtbDataLen % (2 * sizeof(uint32_t))) {
106 return (NULL);
107 }
109 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2) {
110 newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
111 newRange->base = fdt32_to_cpu(dtbRangeData[i]);
112 newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
113 newRange->nextRange = NULL;
115 if (prevRange == NULL) {
116 startRange = newRange;
117 }
118 else {
119 prevRange->nextRange = newRange;
120 }
121 prevRange = newRange;
122 }
123 return (startRange);
124 }
126 /* Function to clean up the memory allocated for a linked list of extracted ranges */
127 static void dtbUtilCommonFreeRangeList(Rm_ResourceRange *rangeList)
128 {
129 Rm_ResourceRange *nextRange;
131 while (rangeList) {
132 nextRange = rangeList->nextRange;
133 Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
134 rangeList = nextRange;
135 }
136 }
138 /* Construct and return a list of values as specified in the Policy DTB */
139 static Rm_ResourceValue *dtbUtilCommonExtractValueList(const void *dtbDataPtr, int32_t dtbDataLen)
140 {
141 uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
142 Rm_ResourceValue *startValue = NULL;
143 Rm_ResourceValue *newValue = NULL;
144 Rm_ResourceValue *prevValue = NULL;
145 uint32_t i;
147 /* Values are stored in the DTB as a list of 32-bit words. The DTB
148 * gives properties lengths in bytes so the length returned from the DTB
149 * should be a multiple of the number of bytes a uint32_t. */
150 if (dtbDataLen % sizeof(uint32_t)) {
151 return (NULL);
152 }
154 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
155 newValue = (Rm_ResourceValue *) Rm_osalMalloc(sizeof(Rm_ResourceValue));
156 newValue->value = fdt32_to_cpu(dtbRangeData[i]);
157 newValue->nextValue = NULL;
159 if (prevValue == NULL) {
160 startValue = newValue;
161 }
162 else {
163 prevValue->nextValue = newValue;
164 }
165 prevValue = newValue;
166 }
167 return (startValue);
168 }
170 /* Function to clean up the memory allocated for a linked list of extracted values */
171 static void dtbUtilCommonFreeValueList (Rm_ResourceValue *valueList)
172 {
173 Rm_ResourceValue *nextValue;
175 while (valueList) {
176 nextValue = valueList->nextValue;
177 Rm_osalFree((void *)valueList, sizeof(Rm_ResourceValue));
178 valueList = nextValue;
179 }
180 }
182 /**********************************************************************
183 ************** Global Resource List Parsing Functions ****************
184 **********************************************************************/
186 Rm_ResourcePropType rmDtbUtilResGetPropertyType(const char * propertyName)
187 {
188 Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
190 if(strcmp(dtbUtilResRangeProp, propertyName) == 0) {
191 propertyType = Rm_resourcePropType_RESOURCE_RANGE;
192 }
193 else if(strcmp(dtbUtilResLinuxAliasProp, propertyName) == 0) {
194 propertyType = Rm_resourcePropType_RESOURCE_LINUX_ALIAS;
195 }
196 else if(strcmp(dtbUtilResNsAssignmentProp, propertyName) == 0) {
197 propertyType = Rm_resourcePropType_NSASSIGNMENT;
198 }
199 return (propertyType);
200 }
202 Rm_ResourceRange *rmDtbUtilResExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
203 {
204 return(dtbUtilCommonExtractRange(dtbDataPtr, dtbDataLen));
205 }
207 void rmDtbUtilResFreeRange(Rm_ResourceRange *rangeList)
208 {
209 dtbUtilCommonFreeRangeList(rangeList);
210 }
212 Rm_LinuxAlias *rmDtbUtilResExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
213 {
214 uint8_t *dtbAliasData = (uint8_t *)dtbDataPtr;
215 uint32_t pathLenBytes;
216 uint32_t extractedValue;
217 uint8_t *extractedValueBytePtr;
218 Rm_LinuxAlias *startAlias = NULL;
219 Rm_LinuxAlias *newAlias = NULL;
220 Rm_LinuxAlias *prevAlias = NULL;
221 uint32_t numOffsets;
222 int32_t i = 0;
223 uint16_t j;
225 /* Linux aliases are stored in the DTB as a list space-separated path node names within
226 * null terminated string. Following the path string
227 * will be two or three values specifying the fields in the linux DTB property
228 * that contain the relevant data. The first value specifies the number of offsets
229 * that follow. If two field offsets are specified the
230 * Linux DTB contains a base + length. If one field offset is specified the
231 * Linux DTB contains a single value for reservation. There is no padding between
232 * the path string and the 32-bit offsets. Therefore the 32-bit offsets may not be on
233 * a 4-byte boundary and must be constructed upon extraction */
234 while(i < dtbDataLen) {
235 newAlias = (Rm_LinuxAlias *) Rm_osalMalloc(sizeof(Rm_LinuxAlias));
237 pathLenBytes = strlen((char *) &dtbAliasData[i]) + 1;
238 newAlias->path = (char *) Rm_osalMalloc(pathLenBytes);
239 strncpy(newAlias->path, ((char *) &dtbAliasData[i]), pathLenBytes);
241 /* Extract 32-bit value specifying number of offsets that follow */
242 i += pathLenBytes;
243 extractedValueBytePtr = (uint8_t *)&extractedValue;
244 for (j = 0; j < sizeof(uint32_t); j++, i++) {
245 extractedValueBytePtr[j] = dtbAliasData[i];
246 }
247 numOffsets = fdt32_to_cpu(extractedValue);
249 if ((numOffsets == 1) || (numOffsets == 2)) {
250 /* Always extract the base value */
251 extractedValueBytePtr = (uint8_t *)&extractedValue;
252 for (j = 0; j < sizeof(uint32_t); j++, i++) {
253 extractedValueBytePtr[j] = dtbAliasData[i];
254 }
255 newAlias->baseOffset = fdt32_to_cpu(extractedValue);
257 if (numOffsets == 2) {
258 for (j = 0; j < sizeof(uint32_t); j++, i++) {
259 extractedValueBytePtr[j] = dtbAliasData[i];
260 }
261 newAlias->lengthOffset = fdt32_to_cpu(extractedValue);
262 }
263 else {
264 newAlias->lengthOffset = RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET;
265 }
267 newAlias->nextLinuxAlias = NULL;
268 if (prevAlias == NULL) {
269 startAlias = newAlias;
270 }
271 else {
272 prevAlias->nextLinuxAlias = newAlias;
273 }
274 prevAlias = newAlias;
275 }
276 else {
277 Rm_osalFree((void *)newAlias->path, pathLenBytes);
278 Rm_osalFree((void *)newAlias, sizeof(Rm_LinuxAlias));
279 while (startAlias) {
280 newAlias = startAlias->nextLinuxAlias;
281 pathLenBytes = strlen(startAlias->path);
282 Rm_osalFree((void *)startAlias->path, pathLenBytes + 1);
283 Rm_osalFree((void *)startAlias, sizeof(Rm_LinuxAlias));
284 startAlias = newAlias;
285 }
286 *result = RM_ERROR_GRL_INVALID_LINUX_ALIAS_FORMAT;
287 return(NULL);
288 }
289 }
290 return (startAlias);
291 }
293 /* Function to clean up the memory allocated for a linked list of extracted Linux
294 * aliases. */
295 void rmDtbUtilResFreeLinuxAlias(Rm_LinuxAlias *aliasList)
296 {
297 Rm_LinuxAlias *nextAlias;
298 int32_t pathSize;
300 while (aliasList) {
301 nextAlias = aliasList->nextLinuxAlias;
302 pathSize = strlen(aliasList->path);
303 Rm_osalFree((void *)aliasList->path, pathSize + 1);
304 Rm_osalFree((void *)aliasList, sizeof(Rm_LinuxAlias));
305 aliasList = nextAlias;
306 }
307 }
309 /* Construct and return a list of NameServer assignments as specified in the Resource DTB */
310 Rm_NsAssignment *rmDtbUtilResExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
311 {
312 uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
313 uint32_t nameLenBytes;
314 uint32_t extractedValue;
315 uint8_t *extractedValueBytePtr;
316 Rm_NsAssignment *startAssignment = NULL;
317 Rm_NsAssignment *newAssignment = NULL;
318 Rm_NsAssignment *prevAssignment = NULL;
319 int32_t i = 0;
320 uint16_t j;
322 /* NameServer assignments are stored in the DTB as a null-terminated character
323 * string followed by a 32-bit word containing the value to be assigned to the
324 * name in the string. There is no padding between the string and the 32-bit
325 * word. Therefore the 32-bit word may not be on a 4-byte boundary and must
326 * be constructed upon extraction */
327 while(i < dtbDataLen) {
328 newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
330 nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
331 if (nameLenBytes > RM_NAME_MAX_CHARS) {
332 Rm_osalFree((void *)newAssignment, sizeof(Rm_NsAssignment));
333 while (startAssignment) {
334 newAssignment = startAssignment->nextNsAssignment;
335 Rm_osalFree((void *)startAssignment, sizeof(Rm_NsAssignment));
336 startAssignment = newAssignment;
337 }
338 *result = RM_ERROR_GRL_NS_ASSIGNMENT_NAME_TOO_LONG;
339 return(NULL);
340 }
341 strncpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]), RM_NAME_MAX_CHARS);
343 /* Extract 32-bit base value and flip endian */
344 i += nameLenBytes;
345 extractedValueBytePtr = (uint8_t *)&extractedValue;
346 for (j = 0; j < sizeof(uint32_t); j++, i++) {
347 extractedValueBytePtr[j] = dtbNsAssignmentData[i];
348 }
349 newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
351 /* Extract 32-bit length value and flip endian */
352 for (j = 0; j < sizeof(uint32_t); j++, i++) {
353 extractedValueBytePtr[j] = dtbNsAssignmentData[i];
354 }
355 newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
357 newAssignment->nextNsAssignment = NULL;
358 if (prevAssignment == NULL) {
359 startAssignment = newAssignment;
360 }
361 else {
362 prevAssignment->nextNsAssignment = newAssignment;
363 }
364 prevAssignment = newAssignment;
365 }
367 return (startAssignment);
368 }
370 /* Function to clean up the memory allocated for a linked list of extracted NameServer
371 * assignments. */
372 void rmDtbUtilResFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
373 {
374 Rm_NsAssignment *nextAssignment;
376 while (nsAssignmentList) {
377 nextAssignment = nsAssignmentList->nextNsAssignment;
378 Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
379 nsAssignmentList = nextAssignment;
380 }
381 }
383 /**********************************************************************
384 ********************** Policy Parsing Functions **********************
385 **********************************************************************/
387 Rm_PolicyPropType rmDtbUtilPolicyGetPropertyType(const char * propertyName)
388 {
389 Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
391 if(strcmp(dtbUtilPolicyAssignments, propertyName) == 0) {
392 propertyType = Rm_policyPropType_ASSIGNMENTS;
393 }
394 else if(strcmp(dtbUtilPolicyAllocationSize, propertyName) == 0) {
395 propertyType = Rm_policyPropType_ALLOCATION_SIZE;
396 }
397 else if(strcmp(dtbUtilPolicyAllocationAlignment, propertyName) == 0) {
398 propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENT;
399 }
400 else if(strcmp(dtbUtilPolicyValidInstances, propertyName) == 0) {
401 propertyType = Rm_policyPropType_VALID_INSTANCES;
402 }
403 return (propertyType);
404 }
406 Rm_PolicyAssignment *rmDtbUtilPolicyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen)
407 {
408 uint8_t *dtbAssignmentData = (uint8_t *)dtbDataPtr;
409 uint32_t permissionsLenBytes;
410 uint32_t extractedValue;
411 uint8_t *extractedValueBytePtr;
412 Rm_PolicyAssignment *startAssignment = NULL;
413 Rm_PolicyAssignment *newAssignment = NULL;
414 Rm_PolicyAssignment *prevAssignment = NULL;
415 int32_t i = 0;
416 uint16_t j;
418 /* Policy assignments are stored in the DTB as two 32-bit words containing a
419 * resource base and length to be assigned the permissions in the defined in
420 * the string that follows. There is no padding between the 32-bit words and the
421 * string. Therefore the 32-bit word may not be on a 4-byte boundary and must
422 * be constructed upon extraction */
423 while(i < dtbDataLen) {
424 newAssignment = (Rm_PolicyAssignment *) Rm_osalMalloc(sizeof(Rm_PolicyAssignment));
426 /* Extract 32-bit resource base value and flip endianness */
427 extractedValueBytePtr = (uint8_t *)&extractedValue;
428 for (j = 0; j < sizeof(uint32_t); j++, i++) {
429 extractedValueBytePtr[j] = dtbAssignmentData[i];
430 }
431 newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
433 /* Extract 32-bit resource length value and flip endianness */
434 for (j = 0; j < sizeof(uint32_t); j++, i++) {
435 extractedValueBytePtr[j] = dtbAssignmentData[i];
436 }
437 newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
439 permissionsLenBytes = strlen((char *) &dtbAssignmentData[i]) + 1;
440 newAssignment->permissionsList = (char *) Rm_osalMalloc(permissionsLenBytes);
441 strncpy(newAssignment->permissionsList, ((char *) &dtbAssignmentData[i]), permissionsLenBytes);
442 i += permissionsLenBytes;
444 newAssignment->nextAssignment = NULL;
445 if (prevAssignment == NULL) {
446 startAssignment = newAssignment;
447 }
448 else {
449 prevAssignment->nextAssignment = newAssignment;
450 }
451 prevAssignment = newAssignment;
452 }
453 return (startAssignment);
454 }
456 void rmDtbUtilPolicyFreeAssignments(Rm_PolicyAssignment *assignmentList)
457 {
458 Rm_PolicyAssignment *nextAssignment;
459 int32_t permissionsSize;
461 while (assignmentList) {
462 nextAssignment = assignmentList->nextAssignment;
463 permissionsSize = strlen(assignmentList->permissionsList);
464 Rm_osalFree((void *)assignmentList->permissionsList, permissionsSize+1);
465 Rm_osalFree((void *)assignmentList, sizeof(Rm_PolicyAssignment));
466 assignmentList = nextAssignment;
467 }
468 }
470 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
471 Rm_ResourceValue *rmDtbUtilPolicyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
472 {
473 return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
474 }
476 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
477 void rmDtbUtilPolicyFreeAllocationSizes (Rm_ResourceValue *allocationSizeList)
478 {
479 dtbUtilCommonFreeValueList(allocationSizeList);
480 }
482 /* Construct and return a list of allocation alignments as specified in the Policy DTB */
483 Rm_ResourceValue *rmDtbUtilPolicyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
484 {
485 return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
486 }
488 /* Function to clean up the memory allocated for a linked list of extracted allocation alignments */
489 void rmDtbUtilPolicyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
490 {
491 dtbUtilCommonFreeValueList(alignmentList);
492 }
494 Rm_PolicyValidInst *rmDtbUtilPolicyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen,
495 int32_t *result)
496 {
497 uint8_t *dtbValidInstData = (uint8_t *)dtbDataPtr;
498 uint32_t instLenBytes;
499 Rm_PolicyValidInst *startInst = NULL;
500 Rm_PolicyValidInst *newInst = NULL;
501 Rm_PolicyValidInst *prevInst = NULL;
502 int32_t i = 0;
504 /* Valid RM instances are stored in the DTB as a list of null-terminated character
505 * strings. */
506 while(i < dtbDataLen) {
507 newInst = (Rm_PolicyValidInst *) Rm_osalMalloc(sizeof(Rm_PolicyValidInst));
509 instLenBytes = strlen((char *) &dtbValidInstData[i]) + 1;
510 if (instLenBytes > RM_NAME_MAX_CHARS) {
511 Rm_osalFree((void *)newInst, sizeof(Rm_PolicyValidInst));
512 while (startInst) {
513 newInst = startInst->nextValidInst;
514 Rm_osalFree((void *)startInst, sizeof(Rm_PolicyValidInst));
515 startInst = newInst;
516 }
517 *result = RM_ERROR_VALID_INST_NAME_TOO_LONG;
518 return(NULL);
519 }
520 strncpy(newInst->instName, ((char *) &dtbValidInstData[i]), instLenBytes);
522 i += instLenBytes;
524 newInst->nextValidInst = NULL;
526 if (prevInst == NULL) {
527 startInst = newInst;
528 }
529 else {
530 prevInst->nextValidInst = newInst;
531 }
532 prevInst = newInst;
533 }
534 return (startInst);
535 }
537 void rmDtbUtilPolicyFreeValidInstances (Rm_PolicyValidInst *validInstList)
538 {
539 Rm_PolicyValidInst *nextInst;
541 while (validInstList) {
542 nextInst = validInstList->nextValidInst;
543 Rm_osalFree((void *)validInstList, sizeof(Rm_PolicyValidInst));
544 validInstList = nextInst;
545 }
546 }
548 /**********************************************************************
549 ****************Linux DTB Parsing Defines and Functions***************
550 **********************************************************************/
552 Rm_LinuxValueRange *rmDtbUtilLinuxExtractValues(const void *dtbDataPtr, int32_t dtbDataLen)
553 {
554 uint32_t *dtbValueData = (uint32_t *)dtbDataPtr;
555 Rm_LinuxValueRange *startValue = NULL;
556 Rm_LinuxValueRange *newValue = NULL;
557 Rm_LinuxValueRange *prevValue = NULL;
558 uint32_t i;
560 /* Values are stored in the Linux DTB as a list of 32-bit words. The number of 32-bit
561 * words in the value field can differ. depending on the number of values specified. */
562 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
563 newValue = (Rm_LinuxValueRange *) Rm_osalMalloc(sizeof(Rm_LinuxValueRange));
564 /* Endianness of extracted value must be flipped */
565 newValue->value = fdt32_to_cpu(dtbValueData[i]);
566 newValue->nextValue = NULL;
568 if (prevValue == NULL) {
569 startValue = newValue;
570 }
571 else {
572 prevValue->nextValue = newValue;
573 }
574 prevValue = newValue;
575 }
576 return (startValue);
577 }
579 void rmDtbUtilLinuxFreeValues(Rm_LinuxValueRange *valueList)
580 {
581 Rm_LinuxValueRange *nextValue;
583 while (valueList) {
584 nextValue = valueList->nextValue;
585 Rm_osalFree((void *)valueList, sizeof(Rm_LinuxValueRange));
586 valueList = nextValue;
587 }
588 }