source: rtems/cpukit/include/libfdt.h @ c81f432

5
Last change on this file since c81f432 was 72273b6, checked in by David Gibson <david@…>, on 11/14/17 at 11:45:56

libfdt: Safer access to strings section

fdt_string() is used to retrieve strings from a DT blob's strings section.
It's rarely used directly, but is widely used internally.

However, it doesn't do any bounds checking, which means in the case of a
corrupted blob it could access bad memory, which libfdt is supposed to
avoid.

This write a safe alternative to fdt_string, fdt_get_string(). It checks
both that the given offset is within the string section and that the string
it points to is properly \0 terminated within the section. It also returns
the string's length as a convenience (since it needs to determine to do the
checks anyway).

fdt_string() is rewritten in terms of fdt_get_string() for compatibility.

Most of the diff here is actually testing infrastructure.

Signed-off-by: David Gibson <david@…>
Tested-by: Alexey Kardashevskiy <aik@…>
Reviewed-by: Alexey Kardashevskiy <aik@…>

  • Property mode set to 100644
File size: 68.5 KB
Line 
1#ifndef LIBFDT_H
2#define LIBFDT_H
3/*
4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation.
6 *
7 * libfdt is dual licensed: you can use it either under the terms of
8 * the GPL, or the BSD license, at your option.
9 *
10 *  a) This library is free software; you can redistribute it and/or
11 *     modify it under the terms of the GNU General Public License as
12 *     published by the Free Software Foundation; either version 2 of the
13 *     License, or (at your option) any later version.
14 *
15 *     This library is distributed in the hope that it will be useful,
16 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *     GNU General Public License for more details.
19 *
20 *     You should have received a copy of the GNU General Public
21 *     License along with this library; if not, write to the Free
22 *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
23 *     MA 02110-1301 USA
24 *
25 * Alternatively,
26 *
27 *  b) Redistribution and use in source and binary forms, with or
28 *     without modification, are permitted provided that the following
29 *     conditions are met:
30 *
31 *     1. Redistributions of source code must retain the above
32 *        copyright notice, this list of conditions and the following
33 *        disclaimer.
34 *     2. Redistributions in binary form must reproduce the above
35 *        copyright notice, this list of conditions and the following
36 *        disclaimer in the documentation and/or other materials
37 *        provided with the distribution.
38 *
39 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
40 *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
41 *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42 *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44 *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
50 *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51 *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53
54#include <libfdt_env.h>
55#include <fdt.h>
56
57#define FDT_FIRST_SUPPORTED_VERSION     0x02
58#define FDT_LAST_SUPPORTED_VERSION      0x11
59
60/* Error codes: informative error codes */
61#define FDT_ERR_NOTFOUND        1
62        /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
63#define FDT_ERR_EXISTS          2
64        /* FDT_ERR_EXISTS: Attempted to create a node or property which
65         * already exists */
66#define FDT_ERR_NOSPACE         3
67        /* FDT_ERR_NOSPACE: Operation needed to expand the device
68         * tree, but its buffer did not have sufficient space to
69         * contain the expanded tree. Use fdt_open_into() to move the
70         * device tree to a buffer with more space. */
71
72/* Error codes: codes for bad parameters */
73#define FDT_ERR_BADOFFSET       4
74        /* FDT_ERR_BADOFFSET: Function was passed a structure block
75         * offset which is out-of-bounds, or which points to an
76         * unsuitable part of the structure for the operation. */
77#define FDT_ERR_BADPATH         5
78        /* FDT_ERR_BADPATH: Function was passed a badly formatted path
79         * (e.g. missing a leading / for a function which requires an
80         * absolute path) */
81#define FDT_ERR_BADPHANDLE      6
82        /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
83         * This can be caused either by an invalid phandle property
84         * length, or the phandle value was either 0 or -1, which are
85         * not permitted. */
86#define FDT_ERR_BADSTATE        7
87        /* FDT_ERR_BADSTATE: Function was passed an incomplete device
88         * tree created by the sequential-write functions, which is
89         * not sufficiently complete for the requested operation. */
90
91/* Error codes: codes for bad device tree blobs */
92#define FDT_ERR_TRUNCATED       8
93        /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
94         * terminated (overflows, goes outside allowed bounds, or
95         * isn't properly terminated).  */
96#define FDT_ERR_BADMAGIC        9
97        /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
98         * device tree at all - it is missing the flattened device
99         * tree magic number. */
100#define FDT_ERR_BADVERSION      10
101        /* FDT_ERR_BADVERSION: Given device tree has a version which
102         * can't be handled by the requested operation.  For
103         * read-write functions, this may mean that fdt_open_into() is
104         * required to convert the tree to the expected version. */
105#define FDT_ERR_BADSTRUCTURE    11
106        /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
107         * structure block or other serious error (e.g. misnested
108         * nodes, or subnodes preceding properties). */
109#define FDT_ERR_BADLAYOUT       12
110        /* FDT_ERR_BADLAYOUT: For read-write functions, the given
111         * device tree has it's sub-blocks in an order that the
112         * function can't handle (memory reserve map, then structure,
113         * then strings).  Use fdt_open_into() to reorganize the tree
114         * into a form suitable for the read-write operations. */
115
116/* "Can't happen" error indicating a bug in libfdt */
117#define FDT_ERR_INTERNAL        13
118        /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
119         * Should never be returned, if it is, it indicates a bug in
120         * libfdt itself. */
121
122/* Errors in device tree content */
123#define FDT_ERR_BADNCELLS       14
124        /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
125         * or similar property with a bad format or value */
126
127#define FDT_ERR_BADVALUE        15
128        /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
129         * value. For example: a property expected to contain a string list
130         * is not NUL-terminated within the length of its value. */
131
132#define FDT_ERR_BADOVERLAY      16
133        /* FDT_ERR_BADOVERLAY: The device tree overlay, while
134         * correctly structured, cannot be applied due to some
135         * unexpected or missing value, property or node. */
136
137#define FDT_ERR_NOPHANDLES      17
138        /* FDT_ERR_NOPHANDLES: The device tree doesn't have any
139         * phandle available anymore without causing an overflow */
140
141#define FDT_ERR_MAX             17
142
143/**********************************************************************/
144/* Low-level functions (you probably don't need these)                */
145/**********************************************************************/
146
147#ifndef SWIG /* This function is not useful in Python */
148const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
149#endif
150static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
151{
152        return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
153}
154
155uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
156
157/**********************************************************************/
158/* Traversal functions                                                */
159/**********************************************************************/
160
161int fdt_next_node(const void *fdt, int offset, int *depth);
162
163/**
164 * fdt_first_subnode() - get offset of first direct subnode
165 *
166 * @fdt:        FDT blob
167 * @offset:     Offset of node to check
168 * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
169 */
170int fdt_first_subnode(const void *fdt, int offset);
171
172/**
173 * fdt_next_subnode() - get offset of next direct subnode
174 *
175 * After first calling fdt_first_subnode(), call this function repeatedly to
176 * get direct subnodes of a parent node.
177 *
178 * @fdt:        FDT blob
179 * @offset:     Offset of previous subnode
180 * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
181 * subnodes
182 */
183int fdt_next_subnode(const void *fdt, int offset);
184
185/**
186 * fdt_for_each_subnode - iterate over all subnodes of a parent
187 *
188 * @node:       child node (int, lvalue)
189 * @fdt:        FDT blob (const void *)
190 * @parent:     parent node (int)
191 *
192 * This is actually a wrapper around a for loop and would be used like so:
193 *
194 *      fdt_for_each_subnode(node, fdt, parent) {
195 *              Use node
196 *              ...
197 *      }
198 *
199 *      if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {
200 *              Error handling
201 *      }
202 *
203 * Note that this is implemented as a macro and @node is used as
204 * iterator in the loop. The parent variable be constant or even a
205 * literal.
206 *
207 */
208#define fdt_for_each_subnode(node, fdt, parent)         \
209        for (node = fdt_first_subnode(fdt, parent);     \
210             node >= 0;                                 \
211             node = fdt_next_subnode(fdt, node))
212
213/**********************************************************************/
214/* General functions                                                  */
215/**********************************************************************/
216#define fdt_get_header(fdt, field) \
217        (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
218#define fdt_magic(fdt)                  (fdt_get_header(fdt, magic))
219#define fdt_totalsize(fdt)              (fdt_get_header(fdt, totalsize))
220#define fdt_off_dt_struct(fdt)          (fdt_get_header(fdt, off_dt_struct))
221#define fdt_off_dt_strings(fdt)         (fdt_get_header(fdt, off_dt_strings))
222#define fdt_off_mem_rsvmap(fdt)         (fdt_get_header(fdt, off_mem_rsvmap))
223#define fdt_version(fdt)                (fdt_get_header(fdt, version))
224#define fdt_last_comp_version(fdt)      (fdt_get_header(fdt, last_comp_version))
225#define fdt_boot_cpuid_phys(fdt)        (fdt_get_header(fdt, boot_cpuid_phys))
226#define fdt_size_dt_strings(fdt)        (fdt_get_header(fdt, size_dt_strings))
227#define fdt_size_dt_struct(fdt)         (fdt_get_header(fdt, size_dt_struct))
228
229#define fdt_set_hdr_(name) \
230        static inline void fdt_set_##name(void *fdt, uint32_t val) \
231        { \
232                struct fdt_header *fdth = (struct fdt_header *)fdt; \
233                fdth->name = cpu_to_fdt32(val); \
234        }
235fdt_set_hdr_(magic);
236fdt_set_hdr_(totalsize);
237fdt_set_hdr_(off_dt_struct);
238fdt_set_hdr_(off_dt_strings);
239fdt_set_hdr_(off_mem_rsvmap);
240fdt_set_hdr_(version);
241fdt_set_hdr_(last_comp_version);
242fdt_set_hdr_(boot_cpuid_phys);
243fdt_set_hdr_(size_dt_strings);
244fdt_set_hdr_(size_dt_struct);
245#undef fdt_set_hdr_
246
247/**
248 * fdt_check_header - sanity check a device tree header
249 * @fdt: pointer to data which might be a flattened device tree
250 *
251 * fdt_check_header() checks that the given buffer contains what
252 * appears to be a flattened device tree, and that the header contains
253 * valid information (to the extent that can be determined from the
254 * header alone).
255 *
256 * returns:
257 *     0, if the buffer appears to contain a valid device tree
258 *     -FDT_ERR_BADMAGIC,
259 *     -FDT_ERR_BADVERSION,
260 *     -FDT_ERR_BADSTATE,
261 *     -FDT_ERR_TRUNCATED, standard meanings, as above
262 */
263int fdt_check_header(const void *fdt);
264
265/**
266 * fdt_move - move a device tree around in memory
267 * @fdt: pointer to the device tree to move
268 * @buf: pointer to memory where the device is to be moved
269 * @bufsize: size of the memory space at buf
270 *
271 * fdt_move() relocates, if possible, the device tree blob located at
272 * fdt to the buffer at buf of size bufsize.  The buffer may overlap
273 * with the existing device tree blob at fdt.  Therefore,
274 *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
275 * should always succeed.
276 *
277 * returns:
278 *     0, on success
279 *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
280 *     -FDT_ERR_BADMAGIC,
281 *     -FDT_ERR_BADVERSION,
282 *     -FDT_ERR_BADSTATE, standard meanings
283 */
284int fdt_move(const void *fdt, void *buf, int bufsize);
285
286/**********************************************************************/
287/* Read-only functions                                                */
288/**********************************************************************/
289
290/**
291 * fdt_get_string - retrieve a string from the strings block of a device tree
292 * @fdt: pointer to the device tree blob
293 * @stroffset: offset of the string within the strings block (native endian)
294 * @lenp: optional pointer to return the string's length
295 *
296 * fdt_get_string() retrieves a pointer to a single string from the
297 * strings block of the device tree blob at fdt, and optionally also
298 * returns the string's length in *lenp.
299 *
300 * returns:
301 *     a pointer to the string, on success
302 *     NULL, if stroffset is out of bounds, or doesn't point to a valid string
303 */
304const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
305
306/**
307 * fdt_string - retrieve a string from the strings block of a device tree
308 * @fdt: pointer to the device tree blob
309 * @stroffset: offset of the string within the strings block (native endian)
310 *
311 * fdt_string() retrieves a pointer to a single string from the
312 * strings block of the device tree blob at fdt.
313 *
314 * returns:
315 *     a pointer to the string, on success
316 *     NULL, if stroffset is out of bounds, or doesn't point to a valid string
317 */
318const char *fdt_string(const void *fdt, int stroffset);
319
320/**
321 * fdt_get_max_phandle - retrieves the highest phandle in a tree
322 * @fdt: pointer to the device tree blob
323 *
324 * fdt_get_max_phandle retrieves the highest phandle in the given
325 * device tree. This will ignore badly formatted phandles, or phandles
326 * with a value of 0 or -1.
327 *
328 * returns:
329 *      the highest phandle on success
330 *      0, if no phandle was found in the device tree
331 *      -1, if an error occurred
332 */
333uint32_t fdt_get_max_phandle(const void *fdt);
334
335/**
336 * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
337 * @fdt: pointer to the device tree blob
338 *
339 * Returns the number of entries in the device tree blob's memory
340 * reservation map.  This does not include the terminating 0,0 entry
341 * or any other (0,0) entries reserved for expansion.
342 *
343 * returns:
344 *     the number of entries
345 */
346int fdt_num_mem_rsv(const void *fdt);
347
348/**
349 * fdt_get_mem_rsv - retrieve one memory reserve map entry
350 * @fdt: pointer to the device tree blob
351 * @address, @size: pointers to 64-bit variables
352 *
353 * On success, *address and *size will contain the address and size of
354 * the n-th reserve map entry from the device tree blob, in
355 * native-endian format.
356 *
357 * returns:
358 *     0, on success
359 *     -FDT_ERR_BADMAGIC,
360 *     -FDT_ERR_BADVERSION,
361 *     -FDT_ERR_BADSTATE, standard meanings
362 */
363int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
364
365/**
366 * fdt_subnode_offset_namelen - find a subnode based on substring
367 * @fdt: pointer to the device tree blob
368 * @parentoffset: structure block offset of a node
369 * @name: name of the subnode to locate
370 * @namelen: number of characters of name to consider
371 *
372 * Identical to fdt_subnode_offset(), but only examine the first
373 * namelen characters of name for matching the subnode name.  This is
374 * useful for finding subnodes based on a portion of a larger string,
375 * such as a full path.
376 */
377#ifndef SWIG /* Not available in Python */
378int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
379                               const char *name, int namelen);
380#endif
381/**
382 * fdt_subnode_offset - find a subnode of a given node
383 * @fdt: pointer to the device tree blob
384 * @parentoffset: structure block offset of a node
385 * @name: name of the subnode to locate
386 *
387 * fdt_subnode_offset() finds a subnode of the node at structure block
388 * offset parentoffset with the given name.  name may include a unit
389 * address, in which case fdt_subnode_offset() will find the subnode
390 * with that unit address, or the unit address may be omitted, in
391 * which case fdt_subnode_offset() will find an arbitrary subnode
392 * whose name excluding unit address matches the given name.
393 *
394 * returns:
395 *      structure block offset of the requested subnode (>=0), on success
396 *      -FDT_ERR_NOTFOUND, if the requested subnode does not exist
397 *      -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
398 *              tag
399 *      -FDT_ERR_BADMAGIC,
400 *      -FDT_ERR_BADVERSION,
401 *      -FDT_ERR_BADSTATE,
402 *      -FDT_ERR_BADSTRUCTURE,
403 *      -FDT_ERR_TRUNCATED, standard meanings.
404 */
405int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
406
407/**
408 * fdt_path_offset_namelen - find a tree node by its full path
409 * @fdt: pointer to the device tree blob
410 * @path: full path of the node to locate
411 * @namelen: number of characters of path to consider
412 *
413 * Identical to fdt_path_offset(), but only consider the first namelen
414 * characters of path as the path name.
415 */
416#ifndef SWIG /* Not available in Python */
417int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
418#endif
419
420/**
421 * fdt_path_offset - find a tree node by its full path
422 * @fdt: pointer to the device tree blob
423 * @path: full path of the node to locate
424 *
425 * fdt_path_offset() finds a node of a given path in the device tree.
426 * Each path component may omit the unit address portion, but the
427 * results of this are undefined if any such path component is
428 * ambiguous (that is if there are multiple nodes at the relevant
429 * level matching the given component, differentiated only by unit
430 * address).
431 *
432 * returns:
433 *      structure block offset of the node with the requested path (>=0), on
434 *              success
435 *      -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
436 *      -FDT_ERR_NOTFOUND, if the requested node does not exist
437 *      -FDT_ERR_BADMAGIC,
438 *      -FDT_ERR_BADVERSION,
439 *      -FDT_ERR_BADSTATE,
440 *      -FDT_ERR_BADSTRUCTURE,
441 *      -FDT_ERR_TRUNCATED, standard meanings.
442 */
443int fdt_path_offset(const void *fdt, const char *path);
444
445/**
446 * fdt_get_name - retrieve the name of a given node
447 * @fdt: pointer to the device tree blob
448 * @nodeoffset: structure block offset of the starting node
449 * @lenp: pointer to an integer variable (will be overwritten) or NULL
450 *
451 * fdt_get_name() retrieves the name (including unit address) of the
452 * device tree node at structure block offset nodeoffset.  If lenp is
453 * non-NULL, the length of this name is also returned, in the integer
454 * pointed to by lenp.
455 *
456 * returns:
457 *      pointer to the node's name, on success
458 *              If lenp is non-NULL, *lenp contains the length of that name
459 *                      (>=0)
460 *      NULL, on error
461 *              if lenp is non-NULL *lenp contains an error code (<0):
462 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
463 *                      tag
464 *              -FDT_ERR_BADMAGIC,
465 *              -FDT_ERR_BADVERSION,
466 *              -FDT_ERR_BADSTATE, standard meanings
467 */
468const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
469
470/**
471 * fdt_first_property_offset - find the offset of a node's first property
472 * @fdt: pointer to the device tree blob
473 * @nodeoffset: structure block offset of a node
474 *
475 * fdt_first_property_offset() finds the first property of the node at
476 * the given structure block offset.
477 *
478 * returns:
479 *      structure block offset of the property (>=0), on success
480 *      -FDT_ERR_NOTFOUND, if the requested node has no properties
481 *      -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
482 *      -FDT_ERR_BADMAGIC,
483 *      -FDT_ERR_BADVERSION,
484 *      -FDT_ERR_BADSTATE,
485 *      -FDT_ERR_BADSTRUCTURE,
486 *      -FDT_ERR_TRUNCATED, standard meanings.
487 */
488int fdt_first_property_offset(const void *fdt, int nodeoffset);
489
490/**
491 * fdt_next_property_offset - step through a node's properties
492 * @fdt: pointer to the device tree blob
493 * @offset: structure block offset of a property
494 *
495 * fdt_next_property_offset() finds the property immediately after the
496 * one at the given structure block offset.  This will be a property
497 * of the same node as the given property.
498 *
499 * returns:
500 *      structure block offset of the next property (>=0), on success
501 *      -FDT_ERR_NOTFOUND, if the given property is the last in its node
502 *      -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
503 *      -FDT_ERR_BADMAGIC,
504 *      -FDT_ERR_BADVERSION,
505 *      -FDT_ERR_BADSTATE,
506 *      -FDT_ERR_BADSTRUCTURE,
507 *      -FDT_ERR_TRUNCATED, standard meanings.
508 */
509int fdt_next_property_offset(const void *fdt, int offset);
510
511/**
512 * fdt_for_each_property_offset - iterate over all properties of a node
513 *
514 * @property_offset:    property offset (int, lvalue)
515 * @fdt:                FDT blob (const void *)
516 * @node:               node offset (int)
517 *
518 * This is actually a wrapper around a for loop and would be used like so:
519 *
520 *      fdt_for_each_property_offset(property, fdt, node) {
521 *              Use property
522 *              ...
523 *      }
524 *
525 *      if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {
526 *              Error handling
527 *      }
528 *
529 * Note that this is implemented as a macro and property is used as
530 * iterator in the loop. The node variable can be constant or even a
531 * literal.
532 */
533#define fdt_for_each_property_offset(property, fdt, node)       \
534        for (property = fdt_first_property_offset(fdt, node);   \
535             property >= 0;                                     \
536             property = fdt_next_property_offset(fdt, property))
537
538/**
539 * fdt_get_property_by_offset - retrieve the property at a given offset
540 * @fdt: pointer to the device tree blob
541 * @offset: offset of the property to retrieve
542 * @lenp: pointer to an integer variable (will be overwritten) or NULL
543 *
544 * fdt_get_property_by_offset() retrieves a pointer to the
545 * fdt_property structure within the device tree blob at the given
546 * offset.  If lenp is non-NULL, the length of the property value is
547 * also returned, in the integer pointed to by lenp.
548 *
549 * Note that this code only works on device tree versions >= 16. fdt_getprop()
550 * works on all versions.
551 *
552 * returns:
553 *      pointer to the structure representing the property
554 *              if lenp is non-NULL, *lenp contains the length of the property
555 *              value (>=0)
556 *      NULL, on error
557 *              if lenp is non-NULL, *lenp contains an error code (<0):
558 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
559 *              -FDT_ERR_BADMAGIC,
560 *              -FDT_ERR_BADVERSION,
561 *              -FDT_ERR_BADSTATE,
562 *              -FDT_ERR_BADSTRUCTURE,
563 *              -FDT_ERR_TRUNCATED, standard meanings
564 */
565const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
566                                                      int offset,
567                                                      int *lenp);
568
569/**
570 * fdt_get_property_namelen - find a property based on substring
571 * @fdt: pointer to the device tree blob
572 * @nodeoffset: offset of the node whose property to find
573 * @name: name of the property to find
574 * @namelen: number of characters of name to consider
575 * @lenp: pointer to an integer variable (will be overwritten) or NULL
576 *
577 * Identical to fdt_get_property(), but only examine the first namelen
578 * characters of name for matching the property name.
579 */
580#ifndef SWIG /* Not available in Python */
581const struct fdt_property *fdt_get_property_namelen(const void *fdt,
582                                                    int nodeoffset,
583                                                    const char *name,
584                                                    int namelen, int *lenp);
585#endif
586
587/**
588 * fdt_get_property - find a given property in a given node
589 * @fdt: pointer to the device tree blob
590 * @nodeoffset: offset of the node whose property to find
591 * @name: name of the property to find
592 * @lenp: pointer to an integer variable (will be overwritten) or NULL
593 *
594 * fdt_get_property() retrieves a pointer to the fdt_property
595 * structure within the device tree blob corresponding to the property
596 * named 'name' of the node at offset nodeoffset.  If lenp is
597 * non-NULL, the length of the property value is also returned, in the
598 * integer pointed to by lenp.
599 *
600 * returns:
601 *      pointer to the structure representing the property
602 *              if lenp is non-NULL, *lenp contains the length of the property
603 *              value (>=0)
604 *      NULL, on error
605 *              if lenp is non-NULL, *lenp contains an error code (<0):
606 *              -FDT_ERR_NOTFOUND, node does not have named property
607 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
608 *                      tag
609 *              -FDT_ERR_BADMAGIC,
610 *              -FDT_ERR_BADVERSION,
611 *              -FDT_ERR_BADSTATE,
612 *              -FDT_ERR_BADSTRUCTURE,
613 *              -FDT_ERR_TRUNCATED, standard meanings
614 */
615const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
616                                            const char *name, int *lenp);
617static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
618                                                      const char *name,
619                                                      int *lenp)
620{
621        return (struct fdt_property *)(uintptr_t)
622                fdt_get_property(fdt, nodeoffset, name, lenp);
623}
624
625/**
626 * fdt_getprop_by_offset - retrieve the value of a property at a given offset
627 * @fdt: pointer to the device tree blob
628 * @ffset: offset of the property to read
629 * @namep: pointer to a string variable (will be overwritten) or NULL
630 * @lenp: pointer to an integer variable (will be overwritten) or NULL
631 *
632 * fdt_getprop_by_offset() retrieves a pointer to the value of the
633 * property at structure block offset 'offset' (this will be a pointer
634 * to within the device blob itself, not a copy of the value).  If
635 * lenp is non-NULL, the length of the property value is also
636 * returned, in the integer pointed to by lenp.  If namep is non-NULL,
637 * the property's namne will also be returned in the char * pointed to
638 * by namep (this will be a pointer to within the device tree's string
639 * block, not a new copy of the name).
640 *
641 * returns:
642 *      pointer to the property's value
643 *              if lenp is non-NULL, *lenp contains the length of the property
644 *              value (>=0)
645 *              if namep is non-NULL *namep contiains a pointer to the property
646 *              name.
647 *      NULL, on error
648 *              if lenp is non-NULL, *lenp contains an error code (<0):
649 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
650 *              -FDT_ERR_BADMAGIC,
651 *              -FDT_ERR_BADVERSION,
652 *              -FDT_ERR_BADSTATE,
653 *              -FDT_ERR_BADSTRUCTURE,
654 *              -FDT_ERR_TRUNCATED, standard meanings
655 */
656#ifndef SWIG /* This function is not useful in Python */
657const void *fdt_getprop_by_offset(const void *fdt, int offset,
658                                  const char **namep, int *lenp);
659#endif
660
661/**
662 * fdt_getprop_namelen - get property value based on substring
663 * @fdt: pointer to the device tree blob
664 * @nodeoffset: offset of the node whose property to find
665 * @name: name of the property to find
666 * @namelen: number of characters of name to consider
667 * @lenp: pointer to an integer variable (will be overwritten) or NULL
668 *
669 * Identical to fdt_getprop(), but only examine the first namelen
670 * characters of name for matching the property name.
671 */
672#ifndef SWIG /* Not available in Python */
673const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
674                                const char *name, int namelen, int *lenp);
675static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
676                                          const char *name, int namelen,
677                                          int *lenp)
678{
679        return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
680                                                      namelen, lenp);
681}
682#endif
683
684/**
685 * fdt_getprop - retrieve the value of a given property
686 * @fdt: pointer to the device tree blob
687 * @nodeoffset: offset of the node whose property to find
688 * @name: name of the property to find
689 * @lenp: pointer to an integer variable (will be overwritten) or NULL
690 *
691 * fdt_getprop() retrieves a pointer to the value of the property
692 * named 'name' of the node at offset nodeoffset (this will be a
693 * pointer to within the device blob itself, not a copy of the value).
694 * If lenp is non-NULL, the length of the property value is also
695 * returned, in the integer pointed to by lenp.
696 *
697 * returns:
698 *      pointer to the property's value
699 *              if lenp is non-NULL, *lenp contains the length of the property
700 *              value (>=0)
701 *      NULL, on error
702 *              if lenp is non-NULL, *lenp contains an error code (<0):
703 *              -FDT_ERR_NOTFOUND, node does not have named property
704 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
705 *                      tag
706 *              -FDT_ERR_BADMAGIC,
707 *              -FDT_ERR_BADVERSION,
708 *              -FDT_ERR_BADSTATE,
709 *              -FDT_ERR_BADSTRUCTURE,
710 *              -FDT_ERR_TRUNCATED, standard meanings
711 */
712const void *fdt_getprop(const void *fdt, int nodeoffset,
713                        const char *name, int *lenp);
714static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
715                                  const char *name, int *lenp)
716{
717        return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
718}
719
720/**
721 * fdt_get_phandle - retrieve the phandle of a given node
722 * @fdt: pointer to the device tree blob
723 * @nodeoffset: structure block offset of the node
724 *
725 * fdt_get_phandle() retrieves the phandle of the device tree node at
726 * structure block offset nodeoffset.
727 *
728 * returns:
729 *      the phandle of the node at nodeoffset, on success (!= 0, != -1)
730 *      0, if the node has no phandle, or another error occurs
731 */
732uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
733
734/**
735 * fdt_get_alias_namelen - get alias based on substring
736 * @fdt: pointer to the device tree blob
737 * @name: name of the alias th look up
738 * @namelen: number of characters of name to consider
739 *
740 * Identical to fdt_get_alias(), but only examine the first namelen
741 * characters of name for matching the alias name.
742 */
743#ifndef SWIG /* Not available in Python */
744const char *fdt_get_alias_namelen(const void *fdt,
745                                  const char *name, int namelen);
746#endif
747
748/**
749 * fdt_get_alias - retrieve the path referenced by a given alias
750 * @fdt: pointer to the device tree blob
751 * @name: name of the alias th look up
752 *
753 * fdt_get_alias() retrieves the value of a given alias.  That is, the
754 * value of the property named 'name' in the node /aliases.
755 *
756 * returns:
757 *      a pointer to the expansion of the alias named 'name', if it exists
758 *      NULL, if the given alias or the /aliases node does not exist
759 */
760const char *fdt_get_alias(const void *fdt, const char *name);
761
762/**
763 * fdt_get_path - determine the full path of a node
764 * @fdt: pointer to the device tree blob
765 * @nodeoffset: offset of the node whose path to find
766 * @buf: character buffer to contain the returned path (will be overwritten)
767 * @buflen: size of the character buffer at buf
768 *
769 * fdt_get_path() computes the full path of the node at offset
770 * nodeoffset, and records that path in the buffer at buf.
771 *
772 * NOTE: This function is expensive, as it must scan the device tree
773 * structure from the start to nodeoffset.
774 *
775 * returns:
776 *      0, on success
777 *              buf contains the absolute path of the node at
778 *              nodeoffset, as a NUL-terminated string.
779 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
780 *      -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
781 *              characters and will not fit in the given buffer.
782 *      -FDT_ERR_BADMAGIC,
783 *      -FDT_ERR_BADVERSION,
784 *      -FDT_ERR_BADSTATE,
785 *      -FDT_ERR_BADSTRUCTURE, standard meanings
786 */
787int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
788
789/**
790 * fdt_supernode_atdepth_offset - find a specific ancestor of a node
791 * @fdt: pointer to the device tree blob
792 * @nodeoffset: offset of the node whose parent to find
793 * @supernodedepth: depth of the ancestor to find
794 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
795 *
796 * fdt_supernode_atdepth_offset() finds an ancestor of the given node
797 * at a specific depth from the root (where the root itself has depth
798 * 0, its immediate subnodes depth 1 and so forth).  So
799 *      fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
800 * will always return 0, the offset of the root node.  If the node at
801 * nodeoffset has depth D, then:
802 *      fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
803 * will return nodeoffset itself.
804 *
805 * NOTE: This function is expensive, as it must scan the device tree
806 * structure from the start to nodeoffset.
807 *
808 * returns:
809 *      structure block offset of the node at node offset's ancestor
810 *              of depth supernodedepth (>=0), on success
811 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
812 *      -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of
813 *              nodeoffset
814 *      -FDT_ERR_BADMAGIC,
815 *      -FDT_ERR_BADVERSION,
816 *      -FDT_ERR_BADSTATE,
817 *      -FDT_ERR_BADSTRUCTURE, standard meanings
818 */
819int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
820                                 int supernodedepth, int *nodedepth);
821
822/**
823 * fdt_node_depth - find the depth of a given node
824 * @fdt: pointer to the device tree blob
825 * @nodeoffset: offset of the node whose parent to find
826 *
827 * fdt_node_depth() finds the depth of a given node.  The root node
828 * has depth 0, its immediate subnodes depth 1 and so forth.
829 *
830 * NOTE: This function is expensive, as it must scan the device tree
831 * structure from the start to nodeoffset.
832 *
833 * returns:
834 *      depth of the node at nodeoffset (>=0), on success
835 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
836 *      -FDT_ERR_BADMAGIC,
837 *      -FDT_ERR_BADVERSION,
838 *      -FDT_ERR_BADSTATE,
839 *      -FDT_ERR_BADSTRUCTURE, standard meanings
840 */
841int fdt_node_depth(const void *fdt, int nodeoffset);
842
843/**
844 * fdt_parent_offset - find the parent of a given node
845 * @fdt: pointer to the device tree blob
846 * @nodeoffset: offset of the node whose parent to find
847 *
848 * fdt_parent_offset() locates the parent node of a given node (that
849 * is, it finds the offset of the node which contains the node at
850 * nodeoffset as a subnode).
851 *
852 * NOTE: This function is expensive, as it must scan the device tree
853 * structure from the start to nodeoffset, *twice*.
854 *
855 * returns:
856 *      structure block offset of the parent of the node at nodeoffset
857 *              (>=0), on success
858 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
859 *      -FDT_ERR_BADMAGIC,
860 *      -FDT_ERR_BADVERSION,
861 *      -FDT_ERR_BADSTATE,
862 *      -FDT_ERR_BADSTRUCTURE, standard meanings
863 */
864int fdt_parent_offset(const void *fdt, int nodeoffset);
865
866/**
867 * fdt_node_offset_by_prop_value - find nodes with a given property value
868 * @fdt: pointer to the device tree blob
869 * @startoffset: only find nodes after this offset
870 * @propname: property name to check
871 * @propval: property value to search for
872 * @proplen: length of the value in propval
873 *
874 * fdt_node_offset_by_prop_value() returns the offset of the first
875 * node after startoffset, which has a property named propname whose
876 * value is of length proplen and has value equal to propval; or if
877 * startoffset is -1, the very first such node in the tree.
878 *
879 * To iterate through all nodes matching the criterion, the following
880 * idiom can be used:
881 *      offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
882 *                                             propval, proplen);
883 *      while (offset != -FDT_ERR_NOTFOUND) {
884 *              // other code here
885 *              offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
886 *                                                     propval, proplen);
887 *      }
888 *
889 * Note the -1 in the first call to the function, if 0 is used here
890 * instead, the function will never locate the root node, even if it
891 * matches the criterion.
892 *
893 * returns:
894 *      structure block offset of the located node (>= 0, >startoffset),
895 *               on success
896 *      -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
897 *              tree after startoffset
898 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
899 *      -FDT_ERR_BADMAGIC,
900 *      -FDT_ERR_BADVERSION,
901 *      -FDT_ERR_BADSTATE,
902 *      -FDT_ERR_BADSTRUCTURE, standard meanings
903 */
904int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
905                                  const char *propname,
906                                  const void *propval, int proplen);
907
908/**
909 * fdt_node_offset_by_phandle - find the node with a given phandle
910 * @fdt: pointer to the device tree blob
911 * @phandle: phandle value
912 *
913 * fdt_node_offset_by_phandle() returns the offset of the node
914 * which has the given phandle value.  If there is more than one node
915 * in the tree with the given phandle (an invalid tree), results are
916 * undefined.
917 *
918 * returns:
919 *      structure block offset of the located node (>= 0), on success
920 *      -FDT_ERR_NOTFOUND, no node with that phandle exists
921 *      -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
922 *      -FDT_ERR_BADMAGIC,
923 *      -FDT_ERR_BADVERSION,
924 *      -FDT_ERR_BADSTATE,
925 *      -FDT_ERR_BADSTRUCTURE, standard meanings
926 */
927int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
928
929/**
930 * fdt_node_check_compatible: check a node's compatible property
931 * @fdt: pointer to the device tree blob
932 * @nodeoffset: offset of a tree node
933 * @compatible: string to match against
934 *
935 *
936 * fdt_node_check_compatible() returns 0 if the given node contains a
937 * 'compatible' property with the given string as one of its elements,
938 * it returns non-zero otherwise, or on error.
939 *
940 * returns:
941 *      0, if the node has a 'compatible' property listing the given string
942 *      1, if the node has a 'compatible' property, but it does not list
943 *              the given string
944 *      -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
945 *      -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
946 *      -FDT_ERR_BADMAGIC,
947 *      -FDT_ERR_BADVERSION,
948 *      -FDT_ERR_BADSTATE,
949 *      -FDT_ERR_BADSTRUCTURE, standard meanings
950 */
951int fdt_node_check_compatible(const void *fdt, int nodeoffset,
952                              const char *compatible);
953
954/**
955 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
956 * @fdt: pointer to the device tree blob
957 * @startoffset: only find nodes after this offset
958 * @compatible: 'compatible' string to match against
959 *
960 * fdt_node_offset_by_compatible() returns the offset of the first
961 * node after startoffset, which has a 'compatible' property which
962 * lists the given compatible string; or if startoffset is -1, the
963 * very first such node in the tree.
964 *
965 * To iterate through all nodes matching the criterion, the following
966 * idiom can be used:
967 *      offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
968 *      while (offset != -FDT_ERR_NOTFOUND) {
969 *              // other code here
970 *              offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
971 *      }
972 *
973 * Note the -1 in the first call to the function, if 0 is used here
974 * instead, the function will never locate the root node, even if it
975 * matches the criterion.
976 *
977 * returns:
978 *      structure block offset of the located node (>= 0, >startoffset),
979 *               on success
980 *      -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
981 *              tree after startoffset
982 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
983 *      -FDT_ERR_BADMAGIC,
984 *      -FDT_ERR_BADVERSION,
985 *      -FDT_ERR_BADSTATE,
986 *      -FDT_ERR_BADSTRUCTURE, standard meanings
987 */
988int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
989                                  const char *compatible);
990
991/**
992 * fdt_stringlist_contains - check a string list property for a string
993 * @strlist: Property containing a list of strings to check
994 * @listlen: Length of property
995 * @str: String to search for
996 *
997 * This is a utility function provided for convenience. The list contains
998 * one or more strings, each terminated by \0, as is found in a device tree
999 * "compatible" property.
1000 *
1001 * @return: 1 if the string is found in the list, 0 not found, or invalid list
1002 */
1003int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
1004
1005/**
1006 * fdt_stringlist_count - count the number of strings in a string list
1007 * @fdt: pointer to the device tree blob
1008 * @nodeoffset: offset of a tree node
1009 * @property: name of the property containing the string list
1010 * @return:
1011 *   the number of strings in the given property
1012 *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1013 *   -FDT_ERR_NOTFOUND if the property does not exist
1014 */
1015int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
1016
1017/**
1018 * fdt_stringlist_search - find a string in a string list and return its index
1019 * @fdt: pointer to the device tree blob
1020 * @nodeoffset: offset of a tree node
1021 * @property: name of the property containing the string list
1022 * @string: string to look up in the string list
1023 *
1024 * Note that it is possible for this function to succeed on property values
1025 * that are not NUL-terminated. That's because the function will stop after
1026 * finding the first occurrence of @string. This can for example happen with
1027 * small-valued cell properties, such as #address-cells, when searching for
1028 * the empty string.
1029 *
1030 * @return:
1031 *   the index of the string in the list of strings
1032 *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1033 *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain
1034 *                     the given string
1035 */
1036int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
1037                          const char *string);
1038
1039/**
1040 * fdt_stringlist_get() - obtain the string at a given index in a string list
1041 * @fdt: pointer to the device tree blob
1042 * @nodeoffset: offset of a tree node
1043 * @property: name of the property containing the string list
1044 * @index: index of the string to return
1045 * @lenp: return location for the string length or an error code on failure
1046 *
1047 * Note that this will successfully extract strings from properties with
1048 * non-NUL-terminated values. For example on small-valued cell properties
1049 * this function will return the empty string.
1050 *
1051 * If non-NULL, the length of the string (on success) or a negative error-code
1052 * (on failure) will be stored in the integer pointer to by lenp.
1053 *
1054 * @return:
1055 *   A pointer to the string at the given index in the string list or NULL on
1056 *   failure. On success the length of the string will be stored in the memory
1057 *   location pointed to by the lenp parameter, if non-NULL. On failure one of
1058 *   the following negative error codes will be returned in the lenp parameter
1059 *   (if non-NULL):
1060 *     -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1061 *     -FDT_ERR_NOTFOUND if the property does not exist
1062 */
1063const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
1064                               const char *property, int index,
1065                               int *lenp);
1066
1067/**********************************************************************/
1068/* Read-only functions (addressing related)                           */
1069/**********************************************************************/
1070
1071/**
1072 * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells
1073 *
1074 * This is the maximum value for #address-cells, #size-cells and
1075 * similar properties that will be processed by libfdt.  IEE1275
1076 * requires that OF implementations handle values up to 4.
1077 * Implementations may support larger values, but in practice higher
1078 * values aren't used.
1079 */
1080#define FDT_MAX_NCELLS          4
1081
1082/**
1083 * fdt_address_cells - retrieve address size for a bus represented in the tree
1084 * @fdt: pointer to the device tree blob
1085 * @nodeoffset: offset of the node to find the address size for
1086 *
1087 * When the node has a valid #address-cells property, returns its value.
1088 *
1089 * returns:
1090 *      0 <= n < FDT_MAX_NCELLS, on success
1091 *      2, if the node has no #address-cells property
1092 *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1093 *              #address-cells property
1094 *      -FDT_ERR_BADMAGIC,
1095 *      -FDT_ERR_BADVERSION,
1096 *      -FDT_ERR_BADSTATE,
1097 *      -FDT_ERR_BADSTRUCTURE,
1098 *      -FDT_ERR_TRUNCATED, standard meanings
1099 */
1100int fdt_address_cells(const void *fdt, int nodeoffset);
1101
1102/**
1103 * fdt_size_cells - retrieve address range size for a bus represented in the
1104 *                  tree
1105 * @fdt: pointer to the device tree blob
1106 * @nodeoffset: offset of the node to find the address range size for
1107 *
1108 * When the node has a valid #size-cells property, returns its value.
1109 *
1110 * returns:
1111 *      0 <= n < FDT_MAX_NCELLS, on success
1112 *      2, if the node has no #address-cells property
1113 *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1114 *              #size-cells property
1115 *      -FDT_ERR_BADMAGIC,
1116 *      -FDT_ERR_BADVERSION,
1117 *      -FDT_ERR_BADSTATE,
1118 *      -FDT_ERR_BADSTRUCTURE,
1119 *      -FDT_ERR_TRUNCATED, standard meanings
1120 */
1121int fdt_size_cells(const void *fdt, int nodeoffset);
1122
1123
1124/**********************************************************************/
1125/* Write-in-place functions                                           */
1126/**********************************************************************/
1127
1128/**
1129 * fdt_setprop_inplace_namelen_partial - change a property's value,
1130 *                                       but not its size
1131 * @fdt: pointer to the device tree blob
1132 * @nodeoffset: offset of the node whose property to change
1133 * @name: name of the property to change
1134 * @namelen: number of characters of name to consider
1135 * @idx: index of the property to change in the array
1136 * @val: pointer to data to replace the property value with
1137 * @len: length of the property value
1138 *
1139 * Identical to fdt_setprop_inplace(), but modifies the given property
1140 * starting from the given index, and using only the first characters
1141 * of the name. It is useful when you want to manipulate only one value of
1142 * an array and you have a string that doesn't end with \0.
1143 */
1144#ifndef SWIG /* Not available in Python */
1145int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
1146                                        const char *name, int namelen,
1147                                        uint32_t idx, const void *val,
1148                                        int len);
1149#endif
1150
1151/**
1152 * fdt_setprop_inplace - change a property's value, but not its size
1153 * @fdt: pointer to the device tree blob
1154 * @nodeoffset: offset of the node whose property to change
1155 * @name: name of the property to change
1156 * @val: pointer to data to replace the property value with
1157 * @len: length of the property value
1158 *
1159 * fdt_setprop_inplace() replaces the value of a given property with
1160 * the data in val, of length len.  This function cannot change the
1161 * size of a property, and so will only work if len is equal to the
1162 * current length of the property.
1163 *
1164 * This function will alter only the bytes in the blob which contain
1165 * the given property value, and will not alter or move any other part
1166 * of the tree.
1167 *
1168 * returns:
1169 *      0, on success
1170 *      -FDT_ERR_NOSPACE, if len is not equal to the property's current length
1171 *      -FDT_ERR_NOTFOUND, node does not have the named property
1172 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1173 *      -FDT_ERR_BADMAGIC,
1174 *      -FDT_ERR_BADVERSION,
1175 *      -FDT_ERR_BADSTATE,
1176 *      -FDT_ERR_BADSTRUCTURE,
1177 *      -FDT_ERR_TRUNCATED, standard meanings
1178 */
1179#ifndef SWIG /* Not available in Python */
1180int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
1181                        const void *val, int len);
1182#endif
1183
1184/**
1185 * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
1186 * @fdt: pointer to the device tree blob
1187 * @nodeoffset: offset of the node whose property to change
1188 * @name: name of the property to change
1189 * @val: 32-bit integer value to replace the property with
1190 *
1191 * fdt_setprop_inplace_u32() replaces the value of a given property
1192 * with the 32-bit integer value in val, converting val to big-endian
1193 * if necessary.  This function cannot change the size of a property,
1194 * and so will only work if the property already exists and has length
1195 * 4.
1196 *
1197 * This function will alter only the bytes in the blob which contain
1198 * the given property value, and will not alter or move any other part
1199 * of the tree.
1200 *
1201 * returns:
1202 *      0, on success
1203 *      -FDT_ERR_NOSPACE, if the property's length is not equal to 4
1204 *      -FDT_ERR_NOTFOUND, node does not have the named property
1205 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1206 *      -FDT_ERR_BADMAGIC,
1207 *      -FDT_ERR_BADVERSION,
1208 *      -FDT_ERR_BADSTATE,
1209 *      -FDT_ERR_BADSTRUCTURE,
1210 *      -FDT_ERR_TRUNCATED, standard meanings
1211 */
1212static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
1213                                          const char *name, uint32_t val)
1214{
1215        fdt32_t tmp = cpu_to_fdt32(val);
1216        return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1217}
1218
1219/**
1220 * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
1221 * @fdt: pointer to the device tree blob
1222 * @nodeoffset: offset of the node whose property to change
1223 * @name: name of the property to change
1224 * @val: 64-bit integer value to replace the property with
1225 *
1226 * fdt_setprop_inplace_u64() replaces the value of a given property
1227 * with the 64-bit integer value in val, converting val to big-endian
1228 * if necessary.  This function cannot change the size of a property,
1229 * and so will only work if the property already exists and has length
1230 * 8.
1231 *
1232 * This function will alter only the bytes in the blob which contain
1233 * the given property value, and will not alter or move any other part
1234 * of the tree.
1235 *
1236 * returns:
1237 *      0, on success
1238 *      -FDT_ERR_NOSPACE, if the property's length is not equal to 8
1239 *      -FDT_ERR_NOTFOUND, node does not have the named property
1240 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1241 *      -FDT_ERR_BADMAGIC,
1242 *      -FDT_ERR_BADVERSION,
1243 *      -FDT_ERR_BADSTATE,
1244 *      -FDT_ERR_BADSTRUCTURE,
1245 *      -FDT_ERR_TRUNCATED, standard meanings
1246 */
1247static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
1248                                          const char *name, uint64_t val)
1249{
1250        fdt64_t tmp = cpu_to_fdt64(val);
1251        return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1252}
1253
1254/**
1255 * fdt_setprop_inplace_cell - change the value of a single-cell property
1256 *
1257 * This is an alternative name for fdt_setprop_inplace_u32()
1258 */
1259static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
1260                                           const char *name, uint32_t val)
1261{
1262        return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
1263}
1264
1265/**
1266 * fdt_nop_property - replace a property with nop tags
1267 * @fdt: pointer to the device tree blob
1268 * @nodeoffset: offset of the node whose property to nop
1269 * @name: name of the property to nop
1270 *
1271 * fdt_nop_property() will replace a given property's representation
1272 * in the blob with FDT_NOP tags, effectively removing it from the
1273 * tree.
1274 *
1275 * This function will alter only the bytes in the blob which contain
1276 * the property, and will not alter or move any other part of the
1277 * tree.
1278 *
1279 * returns:
1280 *      0, on success
1281 *      -FDT_ERR_NOTFOUND, node does not have the named property
1282 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1283 *      -FDT_ERR_BADMAGIC,
1284 *      -FDT_ERR_BADVERSION,
1285 *      -FDT_ERR_BADSTATE,
1286 *      -FDT_ERR_BADSTRUCTURE,
1287 *      -FDT_ERR_TRUNCATED, standard meanings
1288 */
1289int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
1290
1291/**
1292 * fdt_nop_node - replace a node (subtree) with nop tags
1293 * @fdt: pointer to the device tree blob
1294 * @nodeoffset: offset of the node to nop
1295 *
1296 * fdt_nop_node() will replace a given node's representation in the
1297 * blob, including all its subnodes, if any, with FDT_NOP tags,
1298 * effectively removing it from the tree.
1299 *
1300 * This function will alter only the bytes in the blob which contain
1301 * the node and its properties and subnodes, and will not alter or
1302 * move any other part of the tree.
1303 *
1304 * returns:
1305 *      0, on success
1306 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1307 *      -FDT_ERR_BADMAGIC,
1308 *      -FDT_ERR_BADVERSION,
1309 *      -FDT_ERR_BADSTATE,
1310 *      -FDT_ERR_BADSTRUCTURE,
1311 *      -FDT_ERR_TRUNCATED, standard meanings
1312 */
1313int fdt_nop_node(void *fdt, int nodeoffset);
1314
1315/**********************************************************************/
1316/* Sequential write functions                                         */
1317/**********************************************************************/
1318
1319int fdt_create(void *buf, int bufsize);
1320int fdt_resize(void *fdt, void *buf, int bufsize);
1321int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1322int fdt_finish_reservemap(void *fdt);
1323int fdt_begin_node(void *fdt, const char *name);
1324int fdt_property(void *fdt, const char *name, const void *val, int len);
1325static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
1326{
1327        fdt32_t tmp = cpu_to_fdt32(val);
1328        return fdt_property(fdt, name, &tmp, sizeof(tmp));
1329}
1330static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1331{
1332        fdt64_t tmp = cpu_to_fdt64(val);
1333        return fdt_property(fdt, name, &tmp, sizeof(tmp));
1334}
1335static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1336{
1337        return fdt_property_u32(fdt, name, val);
1338}
1339
1340/**
1341 * fdt_property_placeholder - add a new property and return a ptr to its value
1342 *
1343 * @fdt: pointer to the device tree blob
1344 * @name: name of property to add
1345 * @len: length of property value in bytes
1346 * @valp: returns a pointer to where where the value should be placed
1347 *
1348 * returns:
1349 *      0, on success
1350 *      -FDT_ERR_BADMAGIC,
1351 *      -FDT_ERR_NOSPACE, standard meanings
1352 */
1353int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1354
1355#define fdt_property_string(fdt, name, str) \
1356        fdt_property(fdt, name, str, strlen(str)+1)
1357int fdt_end_node(void *fdt);
1358int fdt_finish(void *fdt);
1359
1360/**********************************************************************/
1361/* Read-write functions                                               */
1362/**********************************************************************/
1363
1364int fdt_create_empty_tree(void *buf, int bufsize);
1365int fdt_open_into(const void *fdt, void *buf, int bufsize);
1366int fdt_pack(void *fdt);
1367
1368/**
1369 * fdt_add_mem_rsv - add one memory reserve map entry
1370 * @fdt: pointer to the device tree blob
1371 * @address, @size: 64-bit values (native endian)
1372 *
1373 * Adds a reserve map entry to the given blob reserving a region at
1374 * address address of length size.
1375 *
1376 * This function will insert data into the reserve map and will
1377 * therefore change the indexes of some entries in the table.
1378 *
1379 * returns:
1380 *      0, on success
1381 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1382 *              contain the new reservation entry
1383 *      -FDT_ERR_BADMAGIC,
1384 *      -FDT_ERR_BADVERSION,
1385 *      -FDT_ERR_BADSTATE,
1386 *      -FDT_ERR_BADSTRUCTURE,
1387 *      -FDT_ERR_BADLAYOUT,
1388 *      -FDT_ERR_TRUNCATED, standard meanings
1389 */
1390int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1391
1392/**
1393 * fdt_del_mem_rsv - remove a memory reserve map entry
1394 * @fdt: pointer to the device tree blob
1395 * @n: entry to remove
1396 *
1397 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
1398 * the blob.
1399 *
1400 * This function will delete data from the reservation table and will
1401 * therefore change the indexes of some entries in the table.
1402 *
1403 * returns:
1404 *      0, on success
1405 *      -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
1406 *              are less than n+1 reserve map entries)
1407 *      -FDT_ERR_BADMAGIC,
1408 *      -FDT_ERR_BADVERSION,
1409 *      -FDT_ERR_BADSTATE,
1410 *      -FDT_ERR_BADSTRUCTURE,
1411 *      -FDT_ERR_BADLAYOUT,
1412 *      -FDT_ERR_TRUNCATED, standard meanings
1413 */
1414int fdt_del_mem_rsv(void *fdt, int n);
1415
1416/**
1417 * fdt_set_name - change the name of a given node
1418 * @fdt: pointer to the device tree blob
1419 * @nodeoffset: structure block offset of a node
1420 * @name: name to give the node
1421 *
1422 * fdt_set_name() replaces the name (including unit address, if any)
1423 * of the given node with the given string.  NOTE: this function can't
1424 * efficiently check if the new name is unique amongst the given
1425 * node's siblings; results are undefined if this function is invoked
1426 * with a name equal to one of the given node's siblings.
1427 *
1428 * This function may insert or delete data from the blob, and will
1429 * therefore change the offsets of some existing nodes.
1430 *
1431 * returns:
1432 *      0, on success
1433 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob
1434 *              to contain the new name
1435 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1436 *      -FDT_ERR_BADMAGIC,
1437 *      -FDT_ERR_BADVERSION,
1438 *      -FDT_ERR_BADSTATE, standard meanings
1439 */
1440int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1441
1442/**
1443 * fdt_setprop - create or change a property
1444 * @fdt: pointer to the device tree blob
1445 * @nodeoffset: offset of the node whose property to change
1446 * @name: name of the property to change
1447 * @val: pointer to data to set the property value to
1448 * @len: length of the property value
1449 *
1450 * fdt_setprop() sets the value of the named property in the given
1451 * node to the given value and length, creating the property if it
1452 * does not already exist.
1453 *
1454 * This function may insert or delete data from the blob, and will
1455 * therefore change the offsets of some existing nodes.
1456 *
1457 * returns:
1458 *      0, on success
1459 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1460 *              contain the new property value
1461 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1462 *      -FDT_ERR_BADLAYOUT,
1463 *      -FDT_ERR_BADMAGIC,
1464 *      -FDT_ERR_BADVERSION,
1465 *      -FDT_ERR_BADSTATE,
1466 *      -FDT_ERR_BADSTRUCTURE,
1467 *      -FDT_ERR_BADLAYOUT,
1468 *      -FDT_ERR_TRUNCATED, standard meanings
1469 */
1470int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1471                const void *val, int len);
1472
1473/**
1474 * fdt_setprop_placeholder - allocate space for a property
1475 * @fdt: pointer to the device tree blob
1476 * @nodeoffset: offset of the node whose property to change
1477 * @name: name of the property to change
1478 * @len: length of the property value
1479 * @prop_data: return pointer to property data
1480 *
1481 * fdt_setprop_placeholer() allocates the named property in the given node.
1482 * If the property exists it is resized. In either case a pointer to the
1483 * property data is returned.
1484 *
1485 * This function may insert or delete data from the blob, and will
1486 * therefore change the offsets of some existing nodes.
1487 *
1488 * returns:
1489 *      0, on success
1490 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1491 *              contain the new property value
1492 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1493 *      -FDT_ERR_BADLAYOUT,
1494 *      -FDT_ERR_BADMAGIC,
1495 *      -FDT_ERR_BADVERSION,
1496 *      -FDT_ERR_BADSTATE,
1497 *      -FDT_ERR_BADSTRUCTURE,
1498 *      -FDT_ERR_BADLAYOUT,
1499 *      -FDT_ERR_TRUNCATED, standard meanings
1500 */
1501int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1502                            int len, void **prop_data);
1503
1504/**
1505 * fdt_setprop_u32 - set a property to a 32-bit integer
1506 * @fdt: pointer to the device tree blob
1507 * @nodeoffset: offset of the node whose property to change
1508 * @name: name of the property to change
1509 * @val: 32-bit integer value for the property (native endian)
1510 *
1511 * fdt_setprop_u32() sets the value of the named property in the given
1512 * node to the given 32-bit integer value (converting to big-endian if
1513 * necessary), or creates a new property with that value if it does
1514 * not already exist.
1515 *
1516 * This function may insert or delete data from the blob, and will
1517 * therefore change the offsets of some existing nodes.
1518 *
1519 * returns:
1520 *      0, on success
1521 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1522 *              contain the new property value
1523 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1524 *      -FDT_ERR_BADLAYOUT,
1525 *      -FDT_ERR_BADMAGIC,
1526 *      -FDT_ERR_BADVERSION,
1527 *      -FDT_ERR_BADSTATE,
1528 *      -FDT_ERR_BADSTRUCTURE,
1529 *      -FDT_ERR_BADLAYOUT,
1530 *      -FDT_ERR_TRUNCATED, standard meanings
1531 */
1532static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
1533                                  uint32_t val)
1534{
1535        fdt32_t tmp = cpu_to_fdt32(val);
1536        return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1537}
1538
1539/**
1540 * fdt_setprop_u64 - set a property to a 64-bit integer
1541 * @fdt: pointer to the device tree blob
1542 * @nodeoffset: offset of the node whose property to change
1543 * @name: name of the property to change
1544 * @val: 64-bit integer value for the property (native endian)
1545 *
1546 * fdt_setprop_u64() sets the value of the named property in the given
1547 * node to the given 64-bit integer value (converting to big-endian if
1548 * necessary), or creates a new property with that value if it does
1549 * not already exist.
1550 *
1551 * This function may insert or delete data from the blob, and will
1552 * therefore change the offsets of some existing nodes.
1553 *
1554 * returns:
1555 *      0, on success
1556 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1557 *              contain the new property value
1558 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1559 *      -FDT_ERR_BADLAYOUT,
1560 *      -FDT_ERR_BADMAGIC,
1561 *      -FDT_ERR_BADVERSION,
1562 *      -FDT_ERR_BADSTATE,
1563 *      -FDT_ERR_BADSTRUCTURE,
1564 *      -FDT_ERR_BADLAYOUT,
1565 *      -FDT_ERR_TRUNCATED, standard meanings
1566 */
1567static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1568                                  uint64_t val)
1569{
1570        fdt64_t tmp = cpu_to_fdt64(val);
1571        return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1572}
1573
1574/**
1575 * fdt_setprop_cell - set a property to a single cell value
1576 *
1577 * This is an alternative name for fdt_setprop_u32()
1578 */
1579static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1580                                   uint32_t val)
1581{
1582        return fdt_setprop_u32(fdt, nodeoffset, name, val);
1583}
1584
1585/**
1586 * fdt_setprop_string - set a property to a string value
1587 * @fdt: pointer to the device tree blob
1588 * @nodeoffset: offset of the node whose property to change
1589 * @name: name of the property to change
1590 * @str: string value for the property
1591 *
1592 * fdt_setprop_string() sets the value of the named property in the
1593 * given node to the given string value (using the length of the
1594 * string to determine the new length of the property), or creates a
1595 * new property with that value if it does not already exist.
1596 *
1597 * This function may insert or delete data from the blob, and will
1598 * therefore change the offsets of some existing nodes.
1599 *
1600 * returns:
1601 *      0, on success
1602 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1603 *              contain the new property value
1604 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1605 *      -FDT_ERR_BADLAYOUT,
1606 *      -FDT_ERR_BADMAGIC,
1607 *      -FDT_ERR_BADVERSION,
1608 *      -FDT_ERR_BADSTATE,
1609 *      -FDT_ERR_BADSTRUCTURE,
1610 *      -FDT_ERR_BADLAYOUT,
1611 *      -FDT_ERR_TRUNCATED, standard meanings
1612 */
1613#define fdt_setprop_string(fdt, nodeoffset, name, str) \
1614        fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1615
1616
1617/**
1618 * fdt_setprop_empty - set a property to an empty value
1619 * @fdt: pointer to the device tree blob
1620 * @nodeoffset: offset of the node whose property to change
1621 * @name: name of the property to change
1622 *
1623 * fdt_setprop_empty() sets the value of the named property in the
1624 * given node to an empty (zero length) value, or creates a new empty
1625 * property if it does not already exist.
1626 *
1627 * This function may insert or delete data from the blob, and will
1628 * therefore change the offsets of some existing nodes.
1629 *
1630 * returns:
1631 *      0, on success
1632 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1633 *              contain the new property value
1634 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1635 *      -FDT_ERR_BADLAYOUT,
1636 *      -FDT_ERR_BADMAGIC,
1637 *      -FDT_ERR_BADVERSION,
1638 *      -FDT_ERR_BADSTATE,
1639 *      -FDT_ERR_BADSTRUCTURE,
1640 *      -FDT_ERR_BADLAYOUT,
1641 *      -FDT_ERR_TRUNCATED, standard meanings
1642 */
1643#define fdt_setprop_empty(fdt, nodeoffset, name) \
1644        fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
1645
1646/**
1647 * fdt_appendprop - append to or create a property
1648 * @fdt: pointer to the device tree blob
1649 * @nodeoffset: offset of the node whose property to change
1650 * @name: name of the property to append to
1651 * @val: pointer to data to append to the property value
1652 * @len: length of the data to append to the property value
1653 *
1654 * fdt_appendprop() appends the value to the named property in the
1655 * given node, creating the property if it does not already exist.
1656 *
1657 * This function may insert data into the blob, and will therefore
1658 * change the offsets of some existing nodes.
1659 *
1660 * returns:
1661 *      0, on success
1662 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1663 *              contain the new property value
1664 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1665 *      -FDT_ERR_BADLAYOUT,
1666 *      -FDT_ERR_BADMAGIC,
1667 *      -FDT_ERR_BADVERSION,
1668 *      -FDT_ERR_BADSTATE,
1669 *      -FDT_ERR_BADSTRUCTURE,
1670 *      -FDT_ERR_BADLAYOUT,
1671 *      -FDT_ERR_TRUNCATED, standard meanings
1672 */
1673int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1674                   const void *val, int len);
1675
1676/**
1677 * fdt_appendprop_u32 - append a 32-bit integer value to a property
1678 * @fdt: pointer to the device tree blob
1679 * @nodeoffset: offset of the node whose property to change
1680 * @name: name of the property to change
1681 * @val: 32-bit integer value to append to the property (native endian)
1682 *
1683 * fdt_appendprop_u32() appends the given 32-bit integer value
1684 * (converting to big-endian if necessary) to the value of the named
1685 * property in the given node, or creates a new property with that
1686 * value if it does not already exist.
1687 *
1688 * This function may insert data into the blob, and will therefore
1689 * change the offsets of some existing nodes.
1690 *
1691 * returns:
1692 *      0, on success
1693 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1694 *              contain the new property value
1695 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1696 *      -FDT_ERR_BADLAYOUT,
1697 *      -FDT_ERR_BADMAGIC,
1698 *      -FDT_ERR_BADVERSION,
1699 *      -FDT_ERR_BADSTATE,
1700 *      -FDT_ERR_BADSTRUCTURE,
1701 *      -FDT_ERR_BADLAYOUT,
1702 *      -FDT_ERR_TRUNCATED, standard meanings
1703 */
1704static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1705                                     const char *name, uint32_t val)
1706{
1707        fdt32_t tmp = cpu_to_fdt32(val);
1708        return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1709}
1710
1711/**
1712 * fdt_appendprop_u64 - append a 64-bit integer value to a property
1713 * @fdt: pointer to the device tree blob
1714 * @nodeoffset: offset of the node whose property to change
1715 * @name: name of the property to change
1716 * @val: 64-bit integer value to append to the property (native endian)
1717 *
1718 * fdt_appendprop_u64() appends the given 64-bit integer value
1719 * (converting to big-endian if necessary) to the value of the named
1720 * property in the given node, or creates a new property with that
1721 * value if it does not already exist.
1722 *
1723 * This function may insert data into the blob, and will therefore
1724 * change the offsets of some existing nodes.
1725 *
1726 * returns:
1727 *      0, on success
1728 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1729 *              contain the new property value
1730 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1731 *      -FDT_ERR_BADLAYOUT,
1732 *      -FDT_ERR_BADMAGIC,
1733 *      -FDT_ERR_BADVERSION,
1734 *      -FDT_ERR_BADSTATE,
1735 *      -FDT_ERR_BADSTRUCTURE,
1736 *      -FDT_ERR_BADLAYOUT,
1737 *      -FDT_ERR_TRUNCATED, standard meanings
1738 */
1739static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1740                                     const char *name, uint64_t val)
1741{
1742        fdt64_t tmp = cpu_to_fdt64(val);
1743        return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1744}
1745
1746/**
1747 * fdt_appendprop_cell - append a single cell value to a property
1748 *
1749 * This is an alternative name for fdt_appendprop_u32()
1750 */
1751static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1752                                      const char *name, uint32_t val)
1753{
1754        return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1755}
1756
1757/**
1758 * fdt_appendprop_string - append a string to a property
1759 * @fdt: pointer to the device tree blob
1760 * @nodeoffset: offset of the node whose property to change
1761 * @name: name of the property to change
1762 * @str: string value to append to the property
1763 *
1764 * fdt_appendprop_string() appends the given string to the value of
1765 * the named property in the given node, or creates a new property
1766 * with that value if it does not already exist.
1767 *
1768 * This function may insert data into the blob, and will therefore
1769 * change the offsets of some existing nodes.
1770 *
1771 * returns:
1772 *      0, on success
1773 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1774 *              contain the new property value
1775 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1776 *      -FDT_ERR_BADLAYOUT,
1777 *      -FDT_ERR_BADMAGIC,
1778 *      -FDT_ERR_BADVERSION,
1779 *      -FDT_ERR_BADSTATE,
1780 *      -FDT_ERR_BADSTRUCTURE,
1781 *      -FDT_ERR_BADLAYOUT,
1782 *      -FDT_ERR_TRUNCATED, standard meanings
1783 */
1784#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1785        fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1786
1787/**
1788 * fdt_delprop - delete a property
1789 * @fdt: pointer to the device tree blob
1790 * @nodeoffset: offset of the node whose property to nop
1791 * @name: name of the property to nop
1792 *
1793 * fdt_del_property() will delete the given property.
1794 *
1795 * This function will delete data from the blob, and will therefore
1796 * change the offsets of some existing nodes.
1797 *
1798 * returns:
1799 *      0, on success
1800 *      -FDT_ERR_NOTFOUND, node does not have the named property
1801 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1802 *      -FDT_ERR_BADLAYOUT,
1803 *      -FDT_ERR_BADMAGIC,
1804 *      -FDT_ERR_BADVERSION,
1805 *      -FDT_ERR_BADSTATE,
1806 *      -FDT_ERR_BADSTRUCTURE,
1807 *      -FDT_ERR_TRUNCATED, standard meanings
1808 */
1809int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1810
1811/**
1812 * fdt_add_subnode_namelen - creates a new node based on substring
1813 * @fdt: pointer to the device tree blob
1814 * @parentoffset: structure block offset of a node
1815 * @name: name of the subnode to locate
1816 * @namelen: number of characters of name to consider
1817 *
1818 * Identical to fdt_add_subnode(), but use only the first namelen
1819 * characters of name as the name of the new node.  This is useful for
1820 * creating subnodes based on a portion of a larger string, such as a
1821 * full path.
1822 */
1823#ifndef SWIG /* Not available in Python */
1824int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1825                            const char *name, int namelen);
1826#endif
1827
1828/**
1829 * fdt_add_subnode - creates a new node
1830 * @fdt: pointer to the device tree blob
1831 * @parentoffset: structure block offset of a node
1832 * @name: name of the subnode to locate
1833 *
1834 * fdt_add_subnode() creates a new node as a subnode of the node at
1835 * structure block offset parentoffset, with the given name (which
1836 * should include the unit address, if any).
1837 *
1838 * This function will insert data into the blob, and will therefore
1839 * change the offsets of some existing nodes.
1840
1841 * returns:
1842 *      structure block offset of the created nodeequested subnode (>=0), on
1843 *              success
1844 *      -FDT_ERR_NOTFOUND, if the requested subnode does not exist
1845 *      -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
1846 *              tag
1847 *      -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1848 *              the given name
1849 *      -FDT_ERR_NOSPACE, if there is insufficient free space in the
1850 *              blob to contain the new node
1851 *      -FDT_ERR_NOSPACE
1852 *      -FDT_ERR_BADLAYOUT
1853 *      -FDT_ERR_BADMAGIC,
1854 *      -FDT_ERR_BADVERSION,
1855 *      -FDT_ERR_BADSTATE,
1856 *      -FDT_ERR_BADSTRUCTURE,
1857 *      -FDT_ERR_TRUNCATED, standard meanings.
1858 */
1859int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1860
1861/**
1862 * fdt_del_node - delete a node (subtree)
1863 * @fdt: pointer to the device tree blob
1864 * @nodeoffset: offset of the node to nop
1865 *
1866 * fdt_del_node() will remove the given node, including all its
1867 * subnodes if any, from the blob.
1868 *
1869 * This function will delete data from the blob, and will therefore
1870 * change the offsets of some existing nodes.
1871 *
1872 * returns:
1873 *      0, on success
1874 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1875 *      -FDT_ERR_BADLAYOUT,
1876 *      -FDT_ERR_BADMAGIC,
1877 *      -FDT_ERR_BADVERSION,
1878 *      -FDT_ERR_BADSTATE,
1879 *      -FDT_ERR_BADSTRUCTURE,
1880 *      -FDT_ERR_TRUNCATED, standard meanings
1881 */
1882int fdt_del_node(void *fdt, int nodeoffset);
1883
1884/**
1885 * fdt_overlay_apply - Applies a DT overlay on a base DT
1886 * @fdt: pointer to the base device tree blob
1887 * @fdto: pointer to the device tree overlay blob
1888 *
1889 * fdt_overlay_apply() will apply the given device tree overlay on the
1890 * given base device tree.
1891 *
1892 * Expect the base device tree to be modified, even if the function
1893 * returns an error.
1894 *
1895 * returns:
1896 *      0, on success
1897 *      -FDT_ERR_NOSPACE, there's not enough space in the base device tree
1898 *      -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
1899 *              properties in the base DT
1900 *      -FDT_ERR_BADPHANDLE,
1901 *      -FDT_ERR_BADOVERLAY,
1902 *      -FDT_ERR_NOPHANDLES,
1903 *      -FDT_ERR_INTERNAL,
1904 *      -FDT_ERR_BADLAYOUT,
1905 *      -FDT_ERR_BADMAGIC,
1906 *      -FDT_ERR_BADOFFSET,
1907 *      -FDT_ERR_BADPATH,
1908 *      -FDT_ERR_BADVERSION,
1909 *      -FDT_ERR_BADSTRUCTURE,
1910 *      -FDT_ERR_BADSTATE,
1911 *      -FDT_ERR_TRUNCATED, standard meanings
1912 */
1913int fdt_overlay_apply(void *fdt, void *fdto);
1914
1915/**********************************************************************/
1916/* Debugging / informational functions                                */
1917/**********************************************************************/
1918
1919const char *fdt_strerror(int errval);
1920
1921#endif /* LIBFDT_H */
Note: See TracBrowser for help on using the repository browser.