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 external API includes */
47 #include <ti/drv/rm/rm.h>
48 #include <ti/drv/rm/rm_services.h>
50 /* RM internal API includes */
51 #include <ti/drv/rm/include/rm_dtb_utilloc.h>
53 /* RM OSAL layer */
54 #include <rm_osal.h>
56 /* LIBFDT includes */
57 #include <ti/drv/rm/src/libfdt/libfdt.h>
58 #include <ti/drv/rm/src/libfdt/libfdt_env.h>
60 /**********************************************************************
61 ********************Common DTB Parsing Functions**********************
62 **********************************************************************/
64 char rmDtbStartingNode[] = "\0";
66 /* Construct and return a list of ranges as specified in either the Resource
67 * DTB or a Policy DTB */
68 Rm_ResourceRange *dtbUtilCommonExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
69 {
70 uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
71 Rm_ResourceRange *startRange = NULL;
72 Rm_ResourceRange *newRange = NULL;
73 Rm_ResourceRange *prevRange = NULL;
74 uint32_t i;
76 /* Ranges are stored in the DTB as a list of 32-bit words. The number of 32-bit
77 * words in the DTB ranges field should be even since ranges are specified in a
78 * base, lenth format. The DTB gives properties lengths in bytes so the length
79 * returned from the DTB should be a multiple of the number of bytes in two
80 * uint32_ts. */
81 if (dtbDataLen % (2 * sizeof(uint32_t))) {
82 return (NULL);
83 }
85 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i+=2) {
86 newRange = (Rm_ResourceRange *) Rm_osalMalloc(sizeof(Rm_ResourceRange));
87 newRange->base = fdt32_to_cpu(dtbRangeData[i]);
88 newRange->length = fdt32_to_cpu(dtbRangeData[i+1]);
89 newRange->nextRange = NULL;
91 if (prevRange == NULL) {
92 startRange = newRange;
93 }
94 else {
95 prevRange->nextRange = newRange;
96 }
97 prevRange = newRange;
98 }
99 return (startRange);
100 }
102 /* Function to clean up the memory allocated for a linked list of extracted ranges */
103 void dtbUtilCommonFreeRangeList(Rm_ResourceRange *rangeList)
104 {
105 Rm_ResourceRange *nextRange;
107 while (rangeList) {
108 nextRange = rangeList->nextRange;
109 Rm_osalFree((void *)rangeList, sizeof(Rm_ResourceRange));
110 rangeList = nextRange;
111 }
112 }
114 /* Construct and return a list of values as specified in the Policy DTB */
115 Rm_ResourceValue *dtbUtilCommonExtractValueList(const void *dtbDataPtr, int32_t dtbDataLen)
116 {
117 uint32_t *dtbRangeData = (uint32_t *)dtbDataPtr;
118 Rm_ResourceValue *startValue = NULL;
119 Rm_ResourceValue *newValue = NULL;
120 Rm_ResourceValue *prevValue = NULL;
121 uint32_t i;
123 /* Values are stored in the DTB as a list of 32-bit words. The DTB
124 * gives properties lengths in bytes so the length returned from the DTB
125 * should be a multiple of the number of bytes a uint32_t. */
126 if (dtbDataLen % sizeof(uint32_t)) {
127 return (NULL);
128 }
130 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
131 newValue = (Rm_ResourceValue *) Rm_osalMalloc(sizeof(Rm_ResourceValue));
132 newValue->value = fdt32_to_cpu(dtbRangeData[i]);
133 newValue->nextValue = NULL;
135 if (prevValue == NULL) {
136 startValue = newValue;
137 }
138 else {
139 prevValue->nextValue = newValue;
140 }
141 prevValue = newValue;
142 }
143 return (startValue);
144 }
146 /* Function to clean up the memory allocated for a linked list of extracted values */
147 void dtbUtilCommonFreeValueList (Rm_ResourceValue *valueList)
148 {
149 Rm_ResourceValue *nextValue;
151 while (valueList) {
152 nextValue = valueList->nextValue;
153 Rm_osalFree((void *)valueList, sizeof(Rm_ResourceValue));
154 valueList = nextValue;
155 }
156 }
158 /**********************************************************************
159 *******Global Resource List DTB Parsing Defines and Functions*********
160 **********************************************************************/
162 /* Resource List Properties - These are the property values used
163 * by an application integrator to define the properties of resources
164 * listed in the Device Global Resource List */
165 char dtbUtilResRangeProp[] = "resource-range";
166 char dtbUtilResLinuxAliasProp[] = "linux-dtb-alias";
167 char dtbUtilResNsAssignmentProp[] = "ns-assignment";
169 Rm_ResourcePropType rmDtbUtilResGetPropertyType(const char * propertyName)
170 {
171 Rm_ResourcePropType propertyType = Rm_resourcePropType_UNKNOWN;
173 if(strcmp(dtbUtilResRangeProp, propertyName) == 0) {
174 propertyType = Rm_resourcePropType_RESOURCE_RANGE;
175 }
176 else if(strcmp(dtbUtilResLinuxAliasProp, propertyName) == 0) {
177 propertyType = Rm_resourcePropType_RESOURCE_LINUX_ALIAS;
178 }
179 else if(strcmp(dtbUtilResNsAssignmentProp, propertyName) == 0) {
180 propertyType = Rm_resourcePropType_NSASSIGNMENT;
181 }
182 return (propertyType);
183 }
185 Rm_ResourceRange *rmDtbUtilResExtractRange(const void *dtbDataPtr, int32_t dtbDataLen)
186 {
187 return(dtbUtilCommonExtractRange(dtbDataPtr, dtbDataLen));
188 }
190 void rmDtbUtilResFreeRange(Rm_ResourceRange *rangeList)
191 {
192 dtbUtilCommonFreeRangeList(rangeList);
193 }
195 Rm_LinuxAlias *rmDtbUtilResExtractLinuxAlias(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
196 {
197 uint8_t *dtbAliasData = (uint8_t *)dtbDataPtr;
198 uint32_t pathLenBytes;
199 uint32_t extractedValue;
200 uint8_t *extractedValueBytePtr;
201 Rm_LinuxAlias *startAlias = NULL;
202 Rm_LinuxAlias *newAlias = NULL;
203 Rm_LinuxAlias *prevAlias = NULL;
204 uint32_t numOffsets;
205 int32_t i = 0;
206 uint16_t j;
208 /* Linux aliases are stored in the DTB as a list space-separated path node names within
209 * null terminated string. Following the path string
210 * will be two or three values specifying the fields in the linux DTB property
211 * that contain the relevant data. The first value specifies the number of offsets
212 * that follow. If two field offsets are specified the
213 * Linux DTB contains a base + length. If one field offset is specified the
214 * Linux DTB contains a single value for reservation. There is no padding between
215 * the path string and the 32-bit offsets. Therefore the 32-bit offsets may not be on
216 * a 4-byte boundary and must be constructed upon extraction */
217 while(i < dtbDataLen) {
218 newAlias = (Rm_LinuxAlias *) Rm_osalMalloc(sizeof(Rm_LinuxAlias));
220 pathLenBytes = strlen((char *) &dtbAliasData[i]) + 1;
221 newAlias->path = (char *) Rm_osalMalloc(pathLenBytes);
222 strncpy(newAlias->path, ((char *) &dtbAliasData[i]), pathLenBytes);
224 /* Extract 32-bit value specifying number of offsets that follow */
225 i += pathLenBytes;
226 extractedValueBytePtr = (uint8_t *)&extractedValue;
227 for (j = 0; j < sizeof(uint32_t); j++, i++) {
228 extractedValueBytePtr[j] = dtbAliasData[i];
229 }
230 numOffsets = fdt32_to_cpu(extractedValue);
232 if ((numOffsets == 1) || (numOffsets == 2)) {
233 /* Always extract the base value */
234 extractedValueBytePtr = (uint8_t *)&extractedValue;
235 for (j = 0; j < sizeof(uint32_t); j++, i++) {
236 extractedValueBytePtr[j] = dtbAliasData[i];
237 }
238 newAlias->baseOffset = fdt32_to_cpu(extractedValue);
240 if (numOffsets == 2) {
241 for (j = 0; j < sizeof(uint32_t); j++, i++) {
242 extractedValueBytePtr[j] = dtbAliasData[i];
243 }
244 newAlias->lengthOffset = fdt32_to_cpu(extractedValue);
245 }
246 else {
247 newAlias->lengthOffset = RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET;
248 }
250 newAlias->nextLinuxAlias = NULL;
251 if (prevAlias == NULL) {
252 startAlias = newAlias;
253 }
254 else {
255 prevAlias->nextLinuxAlias = newAlias;
256 }
257 prevAlias = newAlias;
258 }
259 else {
260 Rm_osalFree((void *)newAlias->path, pathLenBytes);
261 Rm_osalFree((void *)newAlias, sizeof(Rm_LinuxAlias));
262 while (startAlias) {
263 newAlias = startAlias->nextLinuxAlias;
264 pathLenBytes = strlen(startAlias->path);
265 Rm_osalFree((void *)startAlias->path, pathLenBytes + 1);
266 Rm_osalFree((void *)startAlias, sizeof(Rm_LinuxAlias));
267 startAlias = newAlias;
268 }
269 *result = RM_INIT_ERROR_GRL_INVALID_LINUX_ALIAS_FORMAT;
270 return(NULL);
271 }
272 }
273 return (startAlias);
274 }
276 /* Function to clean up the memory allocated for a linked list of extracted Linux
277 * aliases. */
278 void rmDtbUtilResFreeLinuxAlias(Rm_LinuxAlias *aliasList)
279 {
280 Rm_LinuxAlias *nextAlias;
281 int32_t pathSize;
283 while (aliasList) {
284 nextAlias = aliasList->nextLinuxAlias;
285 pathSize = strlen(aliasList->path);
286 Rm_osalFree((void *)aliasList->path, pathSize + 1);
287 Rm_osalFree((void *)aliasList, sizeof(Rm_LinuxAlias));
288 aliasList = nextAlias;
289 }
290 }
292 /* Construct and return a list of NameServer assignments as specified in the Resource DTB */
293 Rm_NsAssignment *rmDtbUtilResExtractNsAssignment(const void *dtbDataPtr, int32_t dtbDataLen, int32_t *result)
294 {
295 uint8_t *dtbNsAssignmentData = (uint8_t *)dtbDataPtr;
296 uint32_t nameLenBytes;
297 uint32_t extractedValue;
298 uint8_t *extractedValueBytePtr;
299 Rm_NsAssignment *startAssignment = NULL;
300 Rm_NsAssignment *newAssignment = NULL;
301 Rm_NsAssignment *prevAssignment = NULL;
302 int32_t i = 0;
303 uint16_t j;
305 /* NameServer assignments are stored in the DTB as a null-terminated character
306 * string followed by a 32-bit word containing the value to be assigned to the
307 * name in the string. There is no padding between the string and the 32-bit
308 * word. Therefore the 32-bit word may not be on a 4-byte boundary and must
309 * be constructed upon extraction */
310 while(i < dtbDataLen) {
311 newAssignment = (Rm_NsAssignment *) Rm_osalMalloc(sizeof(Rm_NsAssignment));
313 nameLenBytes = strlen((char *) &dtbNsAssignmentData[i]) + 1;
314 if (nameLenBytes > RM_RESOURCE_NAME_MAX_CHARS) {
315 Rm_osalFree((void *)newAssignment, sizeof(Rm_NsAssignment));
316 while (startAssignment) {
317 newAssignment = startAssignment->nextNsAssignment;
318 Rm_osalFree((void *)startAssignment, sizeof(Rm_NsAssignment));
319 startAssignment = newAssignment;
320 }
321 *result = RM_INIT_ERROR_NS_ASSIGNMENT_NAME_TOO_LONG;
322 return(NULL);
323 }
324 strncpy(newAssignment->nsName, ((char *) &dtbNsAssignmentData[i]), RM_RESOURCE_NAME_MAX_CHARS);
326 /* Extract 32-bit base value and flip endian */
327 i += nameLenBytes;
328 extractedValueBytePtr = (uint8_t *)&extractedValue;
329 for (j = 0; j < sizeof(uint32_t); j++, i++) {
330 extractedValueBytePtr[j] = dtbNsAssignmentData[i];
331 }
332 newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
334 /* Extract 32-bit length value and flip endian */
335 for (j = 0; j < sizeof(uint32_t); j++, i++) {
336 extractedValueBytePtr[j] = dtbNsAssignmentData[i];
337 }
338 newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
340 newAssignment->nextNsAssignment = NULL;
341 if (prevAssignment == NULL) {
342 startAssignment = newAssignment;
343 }
344 else {
345 prevAssignment->nextNsAssignment = newAssignment;
346 }
347 prevAssignment = newAssignment;
348 }
350 return (startAssignment);
351 }
353 /* Function to clean up the memory allocated for a linked list of extracted NameServer
354 * assignments. */
355 void rmDtbUtilResFreeNsAssignmentList (Rm_NsAssignment *nsAssignmentList)
356 {
357 Rm_NsAssignment *nextAssignment;
359 while (nsAssignmentList) {
360 nextAssignment = nsAssignmentList->nextNsAssignment;
361 Rm_osalFree((void *)nsAssignmentList, sizeof(Rm_NsAssignment));
362 nsAssignmentList = nextAssignment;
363 }
364 }
366 /**********************************************************************
367 ***************Policy DTB Parsing Defines and Functions***************
368 **********************************************************************/
370 /* Policy Properties - These are the property values used
371 * by an application integrator to define the properties of resources
372 * listed in a Resource Manager Policy */
373 char dtbUtilPolicyValidInstances[] = "valid-instances";
374 char dtbUtilPolicyAssignments[] = "assignments";
375 char dtbUtilPolicyAllocationSize[] = "allocation-size";
376 char dtbUtilPolicyAllocationAlignment[] = "allocation-alignment";
378 Rm_PolicyPropType rmDtbUtilPolicyGetPropertyType(const char * propertyName)
379 {
380 Rm_PolicyPropType propertyType = Rm_policyPropType_UNKNOWN;
382 if(strcmp(dtbUtilPolicyAssignments, propertyName) == 0) {
383 propertyType = Rm_policyPropType_ASSIGNMENTS;
384 }
385 else if(strcmp(dtbUtilPolicyAllocationSize, propertyName) == 0) {
386 propertyType = Rm_policyPropType_ALLOCATION_SIZE;
387 }
388 else if(strcmp(dtbUtilPolicyAllocationAlignment, propertyName) == 0) {
389 propertyType = Rm_policyPropType_ALLOCATION_ALIGNMENT;
390 }
391 else if(strcmp(dtbUtilPolicyValidInstances, propertyName) == 0) {
392 propertyType = Rm_policyPropType_VALID_INSTANCES;
393 }
394 return (propertyType);
395 }
397 Rm_PolicyAssignment *rmDtbUtilPolicyExtractAssignments(const void *dtbDataPtr, int32_t dtbDataLen)
398 {
399 uint8_t *dtbAssignmentData = (uint8_t *)dtbDataPtr;
400 uint32_t permissionsLenBytes;
401 uint32_t extractedValue;
402 uint8_t *extractedValueBytePtr;
403 Rm_PolicyAssignment *startAssignment = NULL;
404 Rm_PolicyAssignment *newAssignment = NULL;
405 Rm_PolicyAssignment *prevAssignment = NULL;
406 int32_t i = 0;
407 uint16_t j;
409 /* Policy assignments are stored in the DTB as two 32-bit words containing a
410 * resource base and length to be assigned the permissions in the defined in
411 * the string that follows. There is no padding between the 32-bit words and the
412 * string. Therefore the 32-bit word may not be on a 4-byte boundary and must
413 * be constructed upon extraction */
414 while(i < dtbDataLen) {
415 newAssignment = (Rm_PolicyAssignment *) Rm_osalMalloc(sizeof(Rm_PolicyAssignment));
417 /* Extract 32-bit resource base value and flip endianness */
418 extractedValueBytePtr = (uint8_t *)&extractedValue;
419 for (j = 0; j < sizeof(uint32_t); j++, i++) {
420 extractedValueBytePtr[j] = dtbAssignmentData[i];
421 }
422 newAssignment->resourceBase = fdt32_to_cpu(extractedValue);
424 /* Extract 32-bit resource length value and flip endianness */
425 for (j = 0; j < sizeof(uint32_t); j++, i++) {
426 extractedValueBytePtr[j] = dtbAssignmentData[i];
427 }
428 newAssignment->resourceLength = fdt32_to_cpu(extractedValue);
430 permissionsLenBytes = strlen((char *) &dtbAssignmentData[i]) + 1;
431 newAssignment->permissionsList = (char *) Rm_osalMalloc(permissionsLenBytes);
432 strncpy(newAssignment->permissionsList, ((char *) &dtbAssignmentData[i]), permissionsLenBytes);
433 i += permissionsLenBytes;
435 newAssignment->nextAssignment = NULL;
436 if (prevAssignment == NULL) {
437 startAssignment = newAssignment;
438 }
439 else {
440 prevAssignment->nextAssignment = newAssignment;
441 }
442 prevAssignment = newAssignment;
443 }
444 return (startAssignment);
445 }
447 void rmDtbUtilPolicyFreeAssignments(Rm_PolicyAssignment *assignmentList)
448 {
449 Rm_PolicyAssignment *nextAssignment;
450 int32_t permissionsSize;
452 while (assignmentList) {
453 nextAssignment = assignmentList->nextAssignment;
454 permissionsSize = strlen(assignmentList->permissionsList);
455 Rm_osalFree((void *)assignmentList->permissionsList, permissionsSize+1);
456 Rm_osalFree((void *)assignmentList, sizeof(Rm_PolicyAssignment));
457 assignmentList = nextAssignment;
458 }
459 }
461 /* Construct and return a list of allocation sizes as specified in the Policy DTB */
462 Rm_ResourceValue *rmDtbUtilPolicyExtractAllocationSizes(const void *dtbDataPtr, int32_t dtbDataLen)
463 {
464 return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
465 }
467 /* Function to clean up the memory allocated for a linked list of extracted allocation sizes */
468 void rmDtbUtilPolicyFreeAllocationSizes (Rm_ResourceValue *allocationSizeList)
469 {
470 dtbUtilCommonFreeValueList(allocationSizeList);
471 }
473 /* Construct and return a list of allocation alignments as specified in the Policy DTB */
474 Rm_ResourceValue *rmDtbUtilPolicyExtractResourceAlignments(const void *dtbDataPtr, int32_t dtbDataLen)
475 {
476 return(dtbUtilCommonExtractValueList(dtbDataPtr, dtbDataLen));
477 }
479 /* Function to clean up the memory allocated for a linked list of extracted allocation alignments */
480 void rmDtbUtilPolicyFreeResourceAlignments (Rm_ResourceValue *alignmentList)
481 {
482 dtbUtilCommonFreeValueList(alignmentList);
483 }
485 Rm_PolicyValidInst *rmDtbUtilPolicyExtractValidInstances(const void *dtbDataPtr, int32_t dtbDataLen,
486 int32_t *result)
487 {
488 uint8_t *dtbValidInstData = (uint8_t *)dtbDataPtr;
489 uint32_t instLenBytes;
490 Rm_PolicyValidInst *startInst = NULL;
491 Rm_PolicyValidInst *newInst = NULL;
492 Rm_PolicyValidInst *prevInst = NULL;
493 int32_t i = 0;
495 /* Valid RM instances are stored in the DTB as a list of null-terminated character
496 * strings. */
497 while(i < dtbDataLen) {
498 newInst = (Rm_PolicyValidInst *) Rm_osalMalloc(sizeof(Rm_PolicyValidInst));
500 instLenBytes = strlen((char *) &dtbValidInstData[i]) + 1;
501 if (instLenBytes > RM_INSTANCE_NAME_MAX_CHARS) {
502 Rm_osalFree((void *)newInst, sizeof(Rm_PolicyValidInst));
503 while (startInst) {
504 newInst = startInst->nextValidInst;
505 Rm_osalFree((void *)startInst, sizeof(Rm_PolicyValidInst));
506 startInst = newInst;
507 }
508 *result = RM_INIT_ERROR_POLICY_VALID_INSTANCE_NAME_TOO_LONG;
509 return(NULL);
510 }
511 strncpy(newInst->instName, ((char *) &dtbValidInstData[i]), instLenBytes);
513 i += instLenBytes;
515 newInst->nextValidInst = NULL;
517 if (prevInst == NULL) {
518 startInst = newInst;
519 }
520 else {
521 prevInst->nextValidInst = newInst;
522 }
523 prevInst = newInst;
524 }
525 return (startInst);
526 }
528 void rmDtbUtilPolicyFreeValidInstances (Rm_PolicyValidInst *validInstList)
529 {
530 Rm_PolicyValidInst *nextInst;
532 while (validInstList) {
533 nextInst = validInstList->nextValidInst;
534 Rm_osalFree((void *)validInstList, sizeof(Rm_PolicyValidInst));
535 validInstList = nextInst;
536 }
537 }
539 /**********************************************************************
540 ****************Linux DTB Parsing Defines and Functions***************
541 **********************************************************************/
543 Rm_LinuxValueRange *rmDtbUtilLinuxExtractValues(const void *dtbDataPtr, int32_t dtbDataLen)
544 {
545 uint32_t *dtbValueData = (uint32_t *)dtbDataPtr;
546 Rm_LinuxValueRange *startValue = NULL;
547 Rm_LinuxValueRange *newValue = NULL;
548 Rm_LinuxValueRange *prevValue = NULL;
549 uint32_t i;
551 /* Values are stored in the Linux DTB as a list of 32-bit words. The number of 32-bit
552 * words in the value field can differ. depending on the number of values specified. */
553 for (i = 0; i < (dtbDataLen / sizeof(uint32_t)); i++) {
554 newValue = (Rm_LinuxValueRange *) Rm_osalMalloc(sizeof(Rm_LinuxValueRange));
555 /* Endianness of extracted value must be flipped */
556 newValue->value = fdt32_to_cpu(dtbValueData[i]);
557 newValue->nextValue = NULL;
559 if (prevValue == NULL) {
560 startValue = newValue;
561 }
562 else {
563 prevValue->nextValue = newValue;
564 }
565 prevValue = newValue;
566 }
567 return (startValue);
568 }
570 void rmDtbUtilLinuxFreeValues(Rm_LinuxValueRange *valueList)
571 {
572 Rm_LinuxValueRange *nextValue;
574 while (valueList) {
575 nextValue = valueList->nextValue;
576 Rm_osalFree((void *)valueList, sizeof(Rm_LinuxValueRange));
577 valueList = nextValue;
578 }
579 }
581 /**
582 @}
583 */