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, see <http://www.gnu.org/licenses/>.
22  *
23  * Alternatively,
24  *
25  *  b) Redistribution and use in source and binary forms, with or
26  *     without modification, are permitted provided that the following
27  *     conditions are met:
28  *
29  *     1. Redistributions of source code must retain the above
30  *        copyright notice, this list of conditions and the following
31  *        disclaimer.
32  *     2. Redistributions in binary form must reproduce the above
33  *        copyright notice, this list of conditions and the following
34  *        disclaimer in the documentation and/or other materials
35  *        provided with the distribution.
36  *
37  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50  */
51 
52 #include <xen/libfdt/libfdt_env.h>
53 #include <xen/libfdt/fdt.h>
54 
55 #define FDT_FIRST_SUPPORTED_VERSION	0x10
56 #define FDT_LAST_SUPPORTED_VERSION	0x11
57 
58 /* Error codes: informative error codes */
59 #define FDT_ERR_NOTFOUND	1
60 	/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
61 #define FDT_ERR_EXISTS		2
62 	/* FDT_ERR_EXISTS: Attemped to create a node or property which
63 	 * already exists */
64 #define FDT_ERR_NOSPACE		3
65 	/* FDT_ERR_NOSPACE: Operation needed to expand the device
66 	 * tree, but its buffer did not have sufficient space to
67 	 * contain the expanded tree. Use fdt_open_into() to move the
68 	 * device tree to a buffer with more space. */
69 
70 /* Error codes: codes for bad parameters */
71 #define FDT_ERR_BADOFFSET	4
72 	/* FDT_ERR_BADOFFSET: Function was passed a structure block
73 	 * offset which is out-of-bounds, or which points to an
74 	 * unsuitable part of the structure for the operation. */
75 #define FDT_ERR_BADPATH		5
76 	/* FDT_ERR_BADPATH: Function was passed a badly formatted path
77 	 * (e.g. missing a leading / for a function which requires an
78 	 * absolute path) */
79 #define FDT_ERR_BADPHANDLE	6
80 	/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
81 	 * value.  phandle values of 0 and -1 are not permitted. */
82 #define FDT_ERR_BADSTATE	7
83 	/* FDT_ERR_BADSTATE: Function was passed an incomplete device
84 	 * tree created by the sequential-write functions, which is
85 	 * not sufficiently complete for the requested operation. */
86 
87 /* Error codes: codes for bad device tree blobs */
88 #define FDT_ERR_TRUNCATED	8
89 	/* FDT_ERR_TRUNCATED: Structure block of the given device tree
90 	 * ends without an FDT_END tag. */
91 #define FDT_ERR_BADMAGIC	9
92 	/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
93 	 * device tree at all - it is missing the flattened device
94 	 * tree magic number. */
95 #define FDT_ERR_BADVERSION	10
96 	/* FDT_ERR_BADVERSION: Given device tree has a version which
97 	 * can't be handled by the requested operation.  For
98 	 * read-write functions, this may mean that fdt_open_into() is
99 	 * required to convert the tree to the expected version. */
100 #define FDT_ERR_BADSTRUCTURE	11
101 	/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
102 	 * structure block or other serious error (e.g. misnested
103 	 * nodes, or subnodes preceding properties). */
104 #define FDT_ERR_BADLAYOUT	12
105 	/* FDT_ERR_BADLAYOUT: For read-write functions, the given
106 	 * device tree has it's sub-blocks in an order that the
107 	 * function can't handle (memory reserve map, then structure,
108 	 * then strings).  Use fdt_open_into() to reorganize the tree
109 	 * into a form suitable for the read-write operations. */
110 
111 /* "Can't happen" error indicating a bug in libfdt */
112 #define FDT_ERR_INTERNAL	13
113 	/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
114 	 * Should never be returned, if it is, it indicates a bug in
115 	 * libfdt itself. */
116 
117 #define FDT_ERR_MAX		13
118 
119 /**********************************************************************/
120 /* Low-level functions (you probably don't need these)                */
121 /**********************************************************************/
122 
123 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
fdt_offset_ptr_w(void * fdt,int offset,int checklen)124 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
125 {
126 	return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
127 }
128 
129 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
130 
131 /**********************************************************************/
132 /* Traversal functions                                                */
133 /**********************************************************************/
134 
135 int fdt_next_node(const void *fdt, int offset, int *depth);
136 
137 /**
138  * fdt_first_subnode() - get offset of first direct subnode
139  *
140  * @fdt:	FDT blob
141  * @offset:	Offset of node to check
142  * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
143  */
144 int fdt_first_subnode(const void *fdt, int offset);
145 
146 /**
147  * fdt_next_subnode() - get offset of next direct subnode
148  *
149  * After first calling fdt_first_subnode(), call this function repeatedly to
150  * get direct subnodes of a parent node.
151  *
152  * @fdt:	FDT blob
153  * @offset:	Offset of previous subnode
154  * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
155  * subnodes
156  */
157 int fdt_next_subnode(const void *fdt, int offset);
158 
159 /**********************************************************************/
160 /* General functions                                                  */
161 /**********************************************************************/
162 
163 #define fdt_get_header(fdt, field) \
164 	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
165 #define fdt_magic(fdt) 			(fdt_get_header(fdt, magic))
166 #define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
167 #define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
168 #define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
169 #define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
170 #define fdt_version(fdt)		(fdt_get_header(fdt, version))
171 #define fdt_last_comp_version(fdt) 	(fdt_get_header(fdt, last_comp_version))
172 #define fdt_boot_cpuid_phys(fdt) 	(fdt_get_header(fdt, boot_cpuid_phys))
173 #define fdt_size_dt_strings(fdt) 	(fdt_get_header(fdt, size_dt_strings))
174 #define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
175 
176 #define __fdt_set_hdr(name) \
177 	static inline void fdt_set_##name(void *fdt, uint32_t val) \
178 	{ \
179 		struct fdt_header *fdth = (struct fdt_header*)fdt; \
180 		fdth->name = cpu_to_fdt32(val); \
181 	}
182 __fdt_set_hdr(magic);
183 __fdt_set_hdr(totalsize);
184 __fdt_set_hdr(off_dt_struct);
185 __fdt_set_hdr(off_dt_strings);
186 __fdt_set_hdr(off_mem_rsvmap);
187 __fdt_set_hdr(version);
188 __fdt_set_hdr(last_comp_version);
189 __fdt_set_hdr(boot_cpuid_phys);
190 __fdt_set_hdr(size_dt_strings);
191 __fdt_set_hdr(size_dt_struct);
192 #undef __fdt_set_hdr
193 
194 /**
195  * fdt_check_header - sanity check a device tree or possible device tree
196  * @fdt: pointer to data which might be a flattened device tree
197  *
198  * fdt_check_header() checks that the given buffer contains what
199  * appears to be a flattened device tree with sane information in its
200  * header.
201  *
202  * returns:
203  *     0, if the buffer appears to contain a valid device tree
204  *     -FDT_ERR_BADMAGIC,
205  *     -FDT_ERR_BADVERSION,
206  *     -FDT_ERR_BADSTATE, standard meanings, as above
207  */
208 int fdt_check_header(const void *fdt);
209 
210 /**
211  * fdt_move - move a device tree around in memory
212  * @fdt: pointer to the device tree to move
213  * @buf: pointer to memory where the device is to be moved
214  * @bufsize: size of the memory space at buf
215  *
216  * fdt_move() relocates, if possible, the device tree blob located at
217  * fdt to the buffer at buf of size bufsize.  The buffer may overlap
218  * with the existing device tree blob at fdt.  Therefore,
219  *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
220  * should always succeed.
221  *
222  * returns:
223  *     0, on success
224  *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
225  *     -FDT_ERR_BADMAGIC,
226  *     -FDT_ERR_BADVERSION,
227  *     -FDT_ERR_BADSTATE, standard meanings
228  */
229 int fdt_move(const void *fdt, void *buf, int bufsize);
230 
231 /**********************************************************************/
232 /* Read-only functions                                                */
233 /**********************************************************************/
234 
235 /**
236  * fdt_string - retrieve a string from the strings block of a device tree
237  * @fdt: pointer to the device tree blob
238  * @stroffset: offset of the string within the strings block (native endian)
239  *
240  * fdt_string() retrieves a pointer to a single string from the
241  * strings block of the device tree blob at fdt.
242  *
243  * returns:
244  *     a pointer to the string, on success
245  *     NULL, if stroffset is out of bounds
246  */
247 const char *fdt_string(const void *fdt, int stroffset);
248 
249 /**
250  * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
251  * @fdt: pointer to the device tree blob
252  *
253  * Returns the number of entries in the device tree blob's memory
254  * reservation map.  This does not include the terminating 0,0 entry
255  * or any other (0,0) entries reserved for expansion.
256  *
257  * returns:
258  *     the number of entries
259  */
260 int fdt_num_mem_rsv(const void *fdt);
261 
262 /**
263  * fdt_get_mem_rsv - retrieve one memory reserve map entry
264  * @fdt: pointer to the device tree blob
265  * @address, @size: pointers to 64-bit variables
266  *
267  * On success, *address and *size will contain the address and size of
268  * the n-th reserve map entry from the device tree blob, in
269  * native-endian format.
270  *
271  * returns:
272  *     0, on success
273  *     -FDT_ERR_BADMAGIC,
274  *     -FDT_ERR_BADVERSION,
275  *     -FDT_ERR_BADSTATE, standard meanings
276  */
277 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
278 
279 /**
280  * fdt_subnode_offset_namelen - find a subnode based on substring
281  * @fdt: pointer to the device tree blob
282  * @parentoffset: structure block offset of a node
283  * @name: name of the subnode to locate
284  * @namelen: number of characters of name to consider
285  *
286  * Identical to fdt_subnode_offset(), but only examine the first
287  * namelen characters of name for matching the subnode name.  This is
288  * useful for finding subnodes based on a portion of a larger string,
289  * such as a full path.
290  */
291 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
292 			       const char *name, int namelen);
293 /**
294  * fdt_subnode_offset - find a subnode of a given node
295  * @fdt: pointer to the device tree blob
296  * @parentoffset: structure block offset of a node
297  * @name: name of the subnode to locate
298  *
299  * fdt_subnode_offset() finds a subnode of the node at structure block
300  * offset parentoffset with the given name.  name may include a unit
301  * address, in which case fdt_subnode_offset() will find the subnode
302  * with that unit address, or the unit address may be omitted, in
303  * which case fdt_subnode_offset() will find an arbitrary subnode
304  * whose name excluding unit address matches the given name.
305  *
306  * returns:
307  *	structure block offset of the requested subnode (>=0), on success
308  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
309  *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
310  *      -FDT_ERR_BADMAGIC,
311  *	-FDT_ERR_BADVERSION,
312  *	-FDT_ERR_BADSTATE,
313  *	-FDT_ERR_BADSTRUCTURE,
314  *	-FDT_ERR_TRUNCATED, standard meanings.
315  */
316 int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
317 
318 /**
319  * fdt_path_offset - find a tree node by its full path
320  * @fdt: pointer to the device tree blob
321  * @path: full path of the node to locate
322  *
323  * fdt_path_offset() finds a node of a given path in the device tree.
324  * Each path component may omit the unit address portion, but the
325  * results of this are undefined if any such path component is
326  * ambiguous (that is if there are multiple nodes at the relevant
327  * level matching the given component, differentiated only by unit
328  * address).
329  *
330  * returns:
331  *	structure block offset of the node with the requested path (>=0), on success
332  *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
333  *	-FDT_ERR_NOTFOUND, if the requested node does not exist
334  *      -FDT_ERR_BADMAGIC,
335  *	-FDT_ERR_BADVERSION,
336  *	-FDT_ERR_BADSTATE,
337  *	-FDT_ERR_BADSTRUCTURE,
338  *	-FDT_ERR_TRUNCATED, standard meanings.
339  */
340 int fdt_path_offset(const void *fdt, const char *path);
341 
342 /**
343  * fdt_get_name - retrieve the name of a given node
344  * @fdt: pointer to the device tree blob
345  * @nodeoffset: structure block offset of the starting node
346  * @lenp: pointer to an integer variable (will be overwritten) or NULL
347  *
348  * fdt_get_name() retrieves the name (including unit address) of the
349  * device tree node at structure block offset nodeoffset.  If lenp is
350  * non-NULL, the length of this name is also returned, in the integer
351  * pointed to by lenp.
352  *
353  * returns:
354  *	pointer to the node's name, on success
355  *		If lenp is non-NULL, *lenp contains the length of that name (>=0)
356  *	NULL, on error
357  *		if lenp is non-NULL *lenp contains an error code (<0):
358  *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
359  *		-FDT_ERR_BADMAGIC,
360  *		-FDT_ERR_BADVERSION,
361  *		-FDT_ERR_BADSTATE, standard meanings
362  */
363 const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
364 
365 /**
366  * fdt_first_property_offset - find the offset of a node's first property
367  * @fdt: pointer to the device tree blob
368  * @nodeoffset: structure block offset of a node
369  *
370  * fdt_first_property_offset() finds the first property of the node at
371  * the given structure block offset.
372  *
373  * returns:
374  *	structure block offset of the property (>=0), on success
375  *	-FDT_ERR_NOTFOUND, if the requested node has no properties
376  *	-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
377  *      -FDT_ERR_BADMAGIC,
378  *	-FDT_ERR_BADVERSION,
379  *	-FDT_ERR_BADSTATE,
380  *	-FDT_ERR_BADSTRUCTURE,
381  *	-FDT_ERR_TRUNCATED, standard meanings.
382  */
383 int fdt_first_property_offset(const void *fdt, int nodeoffset);
384 
385 /**
386  * fdt_next_property_offset - step through a node's properties
387  * @fdt: pointer to the device tree blob
388  * @offset: structure block offset of a property
389  *
390  * fdt_next_property_offset() finds the property immediately after the
391  * one at the given structure block offset.  This will be a property
392  * of the same node as the given property.
393  *
394  * returns:
395  *	structure block offset of the next property (>=0), on success
396  *	-FDT_ERR_NOTFOUND, if the given property is the last in its node
397  *	-FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
398  *      -FDT_ERR_BADMAGIC,
399  *	-FDT_ERR_BADVERSION,
400  *	-FDT_ERR_BADSTATE,
401  *	-FDT_ERR_BADSTRUCTURE,
402  *	-FDT_ERR_TRUNCATED, standard meanings.
403  */
404 int fdt_next_property_offset(const void *fdt, int offset);
405 
406 /**
407  * fdt_get_property_by_offset - retrieve the property at a given offset
408  * @fdt: pointer to the device tree blob
409  * @offset: offset of the property to retrieve
410  * @lenp: pointer to an integer variable (will be overwritten) or NULL
411  *
412  * fdt_get_property_by_offset() retrieves a pointer to the
413  * fdt_property structure within the device tree blob at the given
414  * offset.  If lenp is non-NULL, the length of the property value is
415  * also returned, in the integer pointed to by lenp.
416  *
417  * returns:
418  *	pointer to the structure representing the property
419  *		if lenp is non-NULL, *lenp contains the length of the property
420  *		value (>=0)
421  *	NULL, on error
422  *		if lenp is non-NULL, *lenp contains an error code (<0):
423  *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
424  *		-FDT_ERR_BADMAGIC,
425  *		-FDT_ERR_BADVERSION,
426  *		-FDT_ERR_BADSTATE,
427  *		-FDT_ERR_BADSTRUCTURE,
428  *		-FDT_ERR_TRUNCATED, standard meanings
429  */
430 const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
431 						      int offset,
432 						      int *lenp);
433 
434 /**
435  * fdt_get_property_namelen - find a property based on substring
436  * @fdt: pointer to the device tree blob
437  * @nodeoffset: offset of the node whose property to find
438  * @name: name of the property to find
439  * @namelen: number of characters of name to consider
440  * @lenp: pointer to an integer variable (will be overwritten) or NULL
441  *
442  * Identical to fdt_get_property_namelen(), but only examine the first
443  * namelen characters of name for matching the property name.
444  */
445 const struct fdt_property *fdt_get_property_namelen(const void *fdt,
446 						    int nodeoffset,
447 						    const char *name,
448 						    int namelen, int *lenp);
449 
450 /**
451  * fdt_get_property - find a given property in a given node
452  * @fdt: pointer to the device tree blob
453  * @nodeoffset: offset of the node whose property to find
454  * @name: name of the property to find
455  * @lenp: pointer to an integer variable (will be overwritten) or NULL
456  *
457  * fdt_get_property() retrieves a pointer to the fdt_property
458  * structure within the device tree blob corresponding to the property
459  * named 'name' of the node at offset nodeoffset.  If lenp is
460  * non-NULL, the length of the property value is also returned, in the
461  * integer pointed to by lenp.
462  *
463  * returns:
464  *	pointer to the structure representing the property
465  *		if lenp is non-NULL, *lenp contains the length of the property
466  *		value (>=0)
467  *	NULL, on error
468  *		if lenp is non-NULL, *lenp contains an error code (<0):
469  *		-FDT_ERR_NOTFOUND, node does not have named property
470  *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
471  *		-FDT_ERR_BADMAGIC,
472  *		-FDT_ERR_BADVERSION,
473  *		-FDT_ERR_BADSTATE,
474  *		-FDT_ERR_BADSTRUCTURE,
475  *		-FDT_ERR_TRUNCATED, standard meanings
476  */
477 const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
478 					    const char *name, int *lenp);
fdt_get_property_w(void * fdt,int nodeoffset,const char * name,int * lenp)479 static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
480 						      const char *name,
481 						      int *lenp)
482 {
483 	return (struct fdt_property *)(uintptr_t)
484 		fdt_get_property(fdt, nodeoffset, name, lenp);
485 }
486 
487 /**
488  * fdt_getprop_by_offset - retrieve the value of a property at a given offset
489  * @fdt: pointer to the device tree blob
490  * @ffset: offset of the property to read
491  * @namep: pointer to a string variable (will be overwritten) or NULL
492  * @lenp: pointer to an integer variable (will be overwritten) or NULL
493  *
494  * fdt_getprop_by_offset() retrieves a pointer to the value of the
495  * property at structure block offset 'offset' (this will be a pointer
496  * to within the device blob itself, not a copy of the value).  If
497  * lenp is non-NULL, the length of the property value is also
498  * returned, in the integer pointed to by lenp.  If namep is non-NULL,
499  * the property's namne will also be returned in the char * pointed to
500  * by namep (this will be a pointer to within the device tree's string
501  * block, not a new copy of the name).
502  *
503  * returns:
504  *	pointer to the property's value
505  *		if lenp is non-NULL, *lenp contains the length of the property
506  *		value (>=0)
507  *		if namep is non-NULL *namep contiains a pointer to the property
508  *		name.
509  *	NULL, on error
510  *		if lenp is non-NULL, *lenp contains an error code (<0):
511  *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
512  *		-FDT_ERR_BADMAGIC,
513  *		-FDT_ERR_BADVERSION,
514  *		-FDT_ERR_BADSTATE,
515  *		-FDT_ERR_BADSTRUCTURE,
516  *		-FDT_ERR_TRUNCATED, standard meanings
517  */
518 const void *fdt_getprop_by_offset(const void *fdt, int offset,
519 				  const char **namep, int *lenp);
520 
521 /**
522  * fdt_getprop_namelen - get property value based on substring
523  * @fdt: pointer to the device tree blob
524  * @nodeoffset: offset of the node whose property to find
525  * @name: name of the property to find
526  * @namelen: number of characters of name to consider
527  * @lenp: pointer to an integer variable (will be overwritten) or NULL
528  *
529  * Identical to fdt_getprop(), but only examine the first namelen
530  * characters of name for matching the property name.
531  */
532 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
533 				const char *name, int namelen, int *lenp);
534 
535 /**
536  * fdt_getprop - retrieve the value of a given property
537  * @fdt: pointer to the device tree blob
538  * @nodeoffset: offset of the node whose property to find
539  * @name: name of the property to find
540  * @lenp: pointer to an integer variable (will be overwritten) or NULL
541  *
542  * fdt_getprop() retrieves a pointer to the value of the property
543  * named 'name' of the node at offset nodeoffset (this will be a
544  * pointer to within the device blob itself, not a copy of the value).
545  * If lenp is non-NULL, the length of the property value is also
546  * returned, in the integer pointed to by lenp.
547  *
548  * returns:
549  *	pointer to the property's value
550  *		if lenp is non-NULL, *lenp contains the length of the property
551  *		value (>=0)
552  *	NULL, on error
553  *		if lenp is non-NULL, *lenp contains an error code (<0):
554  *		-FDT_ERR_NOTFOUND, node does not have named property
555  *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
556  *		-FDT_ERR_BADMAGIC,
557  *		-FDT_ERR_BADVERSION,
558  *		-FDT_ERR_BADSTATE,
559  *		-FDT_ERR_BADSTRUCTURE,
560  *		-FDT_ERR_TRUNCATED, standard meanings
561  */
562 const void *fdt_getprop(const void *fdt, int nodeoffset,
563 			const char *name, int *lenp);
fdt_getprop_w(void * fdt,int nodeoffset,const char * name,int * lenp)564 static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
565 				  const char *name, int *lenp)
566 {
567 	return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
568 }
569 
570 /**
571  * fdt_get_phandle - retrieve the phandle of a given node
572  * @fdt: pointer to the device tree blob
573  * @nodeoffset: structure block offset of the node
574  *
575  * fdt_get_phandle() retrieves the phandle of the device tree node at
576  * structure block offset nodeoffset.
577  *
578  * returns:
579  *	the phandle of the node at nodeoffset, on success (!= 0, != -1)
580  *	0, if the node has no phandle, or another error occurs
581  */
582 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
583 
584 /**
585  * fdt_get_alias_namelen - get alias based on substring
586  * @fdt: pointer to the device tree blob
587  * @name: name of the alias th look up
588  * @namelen: number of characters of name to consider
589  *
590  * Identical to fdt_get_alias(), but only examine the first namelen
591  * characters of name for matching the alias name.
592  */
593 const char *fdt_get_alias_namelen(const void *fdt,
594 				  const char *name, int namelen);
595 
596 /**
597  * fdt_get_alias - retrieve the path referenced by a given alias
598  * @fdt: pointer to the device tree blob
599  * @name: name of the alias th look up
600  *
601  * fdt_get_alias() retrieves the value of a given alias.  That is, the
602  * value of the property named 'name' in the node /aliases.
603  *
604  * returns:
605  *	a pointer to the expansion of the alias named 'name', if it exists
606  *	NULL, if the given alias or the /aliases node does not exist
607  */
608 const char *fdt_get_alias(const void *fdt, const char *name);
609 
610 /**
611  * fdt_get_path - determine the full path of a node
612  * @fdt: pointer to the device tree blob
613  * @nodeoffset: offset of the node whose path to find
614  * @buf: character buffer to contain the returned path (will be overwritten)
615  * @buflen: size of the character buffer at buf
616  *
617  * fdt_get_path() computes the full path of the node at offset
618  * nodeoffset, and records that path in the buffer at buf.
619  *
620  * NOTE: This function is expensive, as it must scan the device tree
621  * structure from the start to nodeoffset.
622  *
623  * returns:
624  *	0, on success
625  *		buf contains the absolute path of the node at
626  *		nodeoffset, as a NUL-terminated string.
627  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
628  *	-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
629  *		characters and will not fit in the given buffer.
630  *	-FDT_ERR_BADMAGIC,
631  *	-FDT_ERR_BADVERSION,
632  *	-FDT_ERR_BADSTATE,
633  *	-FDT_ERR_BADSTRUCTURE, standard meanings
634  */
635 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
636 
637 /**
638  * fdt_supernode_atdepth_offset - find a specific ancestor of a node
639  * @fdt: pointer to the device tree blob
640  * @nodeoffset: offset of the node whose parent to find
641  * @supernodedepth: depth of the ancestor to find
642  * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
643  *
644  * fdt_supernode_atdepth_offset() finds an ancestor of the given node
645  * at a specific depth from the root (where the root itself has depth
646  * 0, its immediate subnodes depth 1 and so forth).  So
647  *	fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
648  * will always return 0, the offset of the root node.  If the node at
649  * nodeoffset has depth D, then:
650  *	fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
651  * will return nodeoffset itself.
652  *
653  * NOTE: This function is expensive, as it must scan the device tree
654  * structure from the start to nodeoffset.
655  *
656  * returns:
657 
658  *	structure block offset of the node at node offset's ancestor
659  *		of depth supernodedepth (>=0), on success
660  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
661 *	-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
662  *	-FDT_ERR_BADMAGIC,
663  *	-FDT_ERR_BADVERSION,
664  *	-FDT_ERR_BADSTATE,
665  *	-FDT_ERR_BADSTRUCTURE, standard meanings
666  */
667 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
668 				 int supernodedepth, int *nodedepth);
669 
670 /**
671  * fdt_node_depth - find the depth of a given node
672  * @fdt: pointer to the device tree blob
673  * @nodeoffset: offset of the node whose parent to find
674  *
675  * fdt_node_depth() finds the depth of a given node.  The root node
676  * has depth 0, its immediate subnodes depth 1 and so forth.
677  *
678  * NOTE: This function is expensive, as it must scan the device tree
679  * structure from the start to nodeoffset.
680  *
681  * returns:
682  *	depth of the node at nodeoffset (>=0), on success
683  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
684  *	-FDT_ERR_BADMAGIC,
685  *	-FDT_ERR_BADVERSION,
686  *	-FDT_ERR_BADSTATE,
687  *	-FDT_ERR_BADSTRUCTURE, standard meanings
688  */
689 int fdt_node_depth(const void *fdt, int nodeoffset);
690 
691 /**
692  * fdt_parent_offset - find the parent of a given node
693  * @fdt: pointer to the device tree blob
694  * @nodeoffset: offset of the node whose parent to find
695  *
696  * fdt_parent_offset() locates the parent node of a given node (that
697  * is, it finds the offset of the node which contains the node at
698  * nodeoffset as a subnode).
699  *
700  * NOTE: This function is expensive, as it must scan the device tree
701  * structure from the start to nodeoffset, *twice*.
702  *
703  * returns:
704  *	structure block offset of the parent of the node at nodeoffset
705  *		(>=0), on success
706  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
707  *	-FDT_ERR_BADMAGIC,
708  *	-FDT_ERR_BADVERSION,
709  *	-FDT_ERR_BADSTATE,
710  *	-FDT_ERR_BADSTRUCTURE, standard meanings
711  */
712 int fdt_parent_offset(const void *fdt, int nodeoffset);
713 
714 /**
715  * fdt_node_offset_by_prop_value - find nodes with a given property value
716  * @fdt: pointer to the device tree blob
717  * @startoffset: only find nodes after this offset
718  * @propname: property name to check
719  * @propval: property value to search for
720  * @proplen: length of the value in propval
721  *
722  * fdt_node_offset_by_prop_value() returns the offset of the first
723  * node after startoffset, which has a property named propname whose
724  * value is of length proplen and has value equal to propval; or if
725  * startoffset is -1, the very first such node in the tree.
726  *
727  * To iterate through all nodes matching the criterion, the following
728  * idiom can be used:
729  *	offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
730  *					       propval, proplen);
731  *	while (offset != -FDT_ERR_NOTFOUND) {
732  *		// other code here
733  *		offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
734  *						       propval, proplen);
735  *	}
736  *
737  * Note the -1 in the first call to the function, if 0 is used here
738  * instead, the function will never locate the root node, even if it
739  * matches the criterion.
740  *
741  * returns:
742  *	structure block offset of the located node (>= 0, >startoffset),
743  *		 on success
744  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
745  *		tree after startoffset
746  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
747  *	-FDT_ERR_BADMAGIC,
748  *	-FDT_ERR_BADVERSION,
749  *	-FDT_ERR_BADSTATE,
750  *	-FDT_ERR_BADSTRUCTURE, standard meanings
751  */
752 int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
753 				  const char *propname,
754 				  const void *propval, int proplen);
755 
756 /**
757  * fdt_node_offset_by_phandle - find the node with a given phandle
758  * @fdt: pointer to the device tree blob
759  * @phandle: phandle value
760  *
761  * fdt_node_offset_by_phandle() returns the offset of the node
762  * which has the given phandle value.  If there is more than one node
763  * in the tree with the given phandle (an invalid tree), results are
764  * undefined.
765  *
766  * returns:
767  *	structure block offset of the located node (>= 0), on success
768  *	-FDT_ERR_NOTFOUND, no node with that phandle exists
769  *	-FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
770  *	-FDT_ERR_BADMAGIC,
771  *	-FDT_ERR_BADVERSION,
772  *	-FDT_ERR_BADSTATE,
773  *	-FDT_ERR_BADSTRUCTURE, standard meanings
774  */
775 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
776 
777 /**
778  * fdt_node_check_compatible: check a node's compatible property
779  * @fdt: pointer to the device tree blob
780  * @nodeoffset: offset of a tree node
781  * @compatible: string to match against
782  *
783  *
784  * fdt_node_check_compatible() returns 0 if the given node contains a
785  * 'compatible' property with the given string as one of its elements,
786  * it returns non-zero otherwise, or on error.
787  *
788  * returns:
789  *	0, if the node has a 'compatible' property listing the given string
790  *	1, if the node has a 'compatible' property, but it does not list
791  *		the given string
792  *	-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
793  * 	-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
794  *	-FDT_ERR_BADMAGIC,
795  *	-FDT_ERR_BADVERSION,
796  *	-FDT_ERR_BADSTATE,
797  *	-FDT_ERR_BADSTRUCTURE, standard meanings
798  */
799 int fdt_node_check_compatible(const void *fdt, int nodeoffset,
800 			      const char *compatible);
801 
802 /**
803  * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
804  * @fdt: pointer to the device tree blob
805  * @startoffset: only find nodes after this offset
806  * @compatible: 'compatible' string to match against
807  *
808  * fdt_node_offset_by_compatible() returns the offset of the first
809  * node after startoffset, which has a 'compatible' property which
810  * lists the given compatible string; or if startoffset is -1, the
811  * very first such node in the tree.
812  *
813  * To iterate through all nodes matching the criterion, the following
814  * idiom can be used:
815  *	offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
816  *	while (offset != -FDT_ERR_NOTFOUND) {
817  *		// other code here
818  *		offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
819  *	}
820  *
821  * Note the -1 in the first call to the function, if 0 is used here
822  * instead, the function will never locate the root node, even if it
823  * matches the criterion.
824  *
825  * returns:
826  *	structure block offset of the located node (>= 0, >startoffset),
827  *		 on success
828  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
829  *		tree after startoffset
830  * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
831  *	-FDT_ERR_BADMAGIC,
832  *	-FDT_ERR_BADVERSION,
833  *	-FDT_ERR_BADSTATE,
834  *	-FDT_ERR_BADSTRUCTURE, standard meanings
835  */
836 int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
837 				  const char *compatible);
838 
839 /**
840  * fdt_stringlist_contains - check a string list property for a string
841  * @strlist: Property containing a list of strings to check
842  * @listlen: Length of property
843  * @str: String to search for
844  *
845  * This is a utility function provided for convenience. The list contains
846  * one or more strings, each terminated by \0, as is found in a device tree
847  * "compatible" property.
848  *
849  * @return: 1 if the string is found in the list, 0 not found, or invalid list
850  */
851 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
852 
853 /**********************************************************************/
854 /* Write-in-place functions                                           */
855 /**********************************************************************/
856 
857 /**
858  * fdt_setprop_inplace - change a property's value, but not its size
859  * @fdt: pointer to the device tree blob
860  * @nodeoffset: offset of the node whose property to change
861  * @name: name of the property to change
862  * @val: pointer to data to replace the property value with
863  * @len: length of the property value
864  *
865  * fdt_setprop_inplace() replaces the value of a given property with
866  * the data in val, of length len.  This function cannot change the
867  * size of a property, and so will only work if len is equal to the
868  * current length of the property.
869  *
870  * This function will alter only the bytes in the blob which contain
871  * the given property value, and will not alter or move any other part
872  * of the tree.
873  *
874  * returns:
875  *	0, on success
876  *	-FDT_ERR_NOSPACE, if len is not equal to the property's current length
877  *	-FDT_ERR_NOTFOUND, node does not have the named property
878  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
879  *	-FDT_ERR_BADMAGIC,
880  *	-FDT_ERR_BADVERSION,
881  *	-FDT_ERR_BADSTATE,
882  *	-FDT_ERR_BADSTRUCTURE,
883  *	-FDT_ERR_TRUNCATED, standard meanings
884  */
885 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
886 			const void *val, int len);
887 
888 /**
889  * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
890  * @fdt: pointer to the device tree blob
891  * @nodeoffset: offset of the node whose property to change
892  * @name: name of the property to change
893  * @val: 32-bit integer value to replace the property with
894  *
895  * fdt_setprop_inplace_u32() replaces the value of a given property
896  * with the 32-bit integer value in val, converting val to big-endian
897  * if necessary.  This function cannot change the size of a property,
898  * and so will only work if the property already exists and has length
899  * 4.
900  *
901  * This function will alter only the bytes in the blob which contain
902  * the given property value, and will not alter or move any other part
903  * of the tree.
904  *
905  * returns:
906  *	0, on success
907  *	-FDT_ERR_NOSPACE, if the property's length is not equal to 4
908  *	-FDT_ERR_NOTFOUND, node does not have the named property
909  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
910  *	-FDT_ERR_BADMAGIC,
911  *	-FDT_ERR_BADVERSION,
912  *	-FDT_ERR_BADSTATE,
913  *	-FDT_ERR_BADSTRUCTURE,
914  *	-FDT_ERR_TRUNCATED, standard meanings
915  */
fdt_setprop_inplace_u32(void * fdt,int nodeoffset,const char * name,uint32_t val)916 static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
917 					  const char *name, uint32_t val)
918 {
919 	fdt32_t tmp = cpu_to_fdt32(val);
920 	return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
921 }
922 
923 /**
924  * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
925  * @fdt: pointer to the device tree blob
926  * @nodeoffset: offset of the node whose property to change
927  * @name: name of the property to change
928  * @val: 64-bit integer value to replace the property with
929  *
930  * fdt_setprop_inplace_u64() replaces the value of a given property
931  * with the 64-bit integer value in val, converting val to big-endian
932  * if necessary.  This function cannot change the size of a property,
933  * and so will only work if the property already exists and has length
934  * 8.
935  *
936  * This function will alter only the bytes in the blob which contain
937  * the given property value, and will not alter or move any other part
938  * of the tree.
939  *
940  * returns:
941  *	0, on success
942  *	-FDT_ERR_NOSPACE, if the property's length is not equal to 8
943  *	-FDT_ERR_NOTFOUND, node does not have the named property
944  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
945  *	-FDT_ERR_BADMAGIC,
946  *	-FDT_ERR_BADVERSION,
947  *	-FDT_ERR_BADSTATE,
948  *	-FDT_ERR_BADSTRUCTURE,
949  *	-FDT_ERR_TRUNCATED, standard meanings
950  */
fdt_setprop_inplace_u64(void * fdt,int nodeoffset,const char * name,uint64_t val)951 static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
952 					  const char *name, uint64_t val)
953 {
954 	fdt64_t tmp = cpu_to_fdt64(val);
955 	return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
956 }
957 
958 /**
959  * fdt_setprop_inplace_cell - change the value of a single-cell property
960  *
961  * This is an alternative name for fdt_setprop_inplace_u32()
962  */
fdt_setprop_inplace_cell(void * fdt,int nodeoffset,const char * name,uint32_t val)963 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
964 					   const char *name, uint32_t val)
965 {
966 	return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
967 }
968 
969 /**
970  * fdt_nop_property - replace a property with nop tags
971  * @fdt: pointer to the device tree blob
972  * @nodeoffset: offset of the node whose property to nop
973  * @name: name of the property to nop
974  *
975  * fdt_nop_property() will replace a given property's representation
976  * in the blob with FDT_NOP tags, effectively removing it from the
977  * tree.
978  *
979  * This function will alter only the bytes in the blob which contain
980  * the property, and will not alter or move any other part of the
981  * tree.
982  *
983  * returns:
984  *	0, on success
985  *	-FDT_ERR_NOTFOUND, node does not have the named property
986  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
987  *	-FDT_ERR_BADMAGIC,
988  *	-FDT_ERR_BADVERSION,
989  *	-FDT_ERR_BADSTATE,
990  *	-FDT_ERR_BADSTRUCTURE,
991  *	-FDT_ERR_TRUNCATED, standard meanings
992  */
993 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
994 
995 /**
996  * fdt_nop_node - replace a node (subtree) with nop tags
997  * @fdt: pointer to the device tree blob
998  * @nodeoffset: offset of the node to nop
999  *
1000  * fdt_nop_node() will replace a given node's representation in the
1001  * blob, including all its subnodes, if any, with FDT_NOP tags,
1002  * effectively removing it from the tree.
1003  *
1004  * This function will alter only the bytes in the blob which contain
1005  * the node and its properties and subnodes, and will not alter or
1006  * move any other part of the tree.
1007  *
1008  * returns:
1009  *	0, on success
1010  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1011  *	-FDT_ERR_BADMAGIC,
1012  *	-FDT_ERR_BADVERSION,
1013  *	-FDT_ERR_BADSTATE,
1014  *	-FDT_ERR_BADSTRUCTURE,
1015  *	-FDT_ERR_TRUNCATED, standard meanings
1016  */
1017 int fdt_nop_node(void *fdt, int nodeoffset);
1018 
1019 /**********************************************************************/
1020 /* Sequential write functions                                         */
1021 /**********************************************************************/
1022 
1023 int fdt_create(void *buf, int bufsize);
1024 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1025 int fdt_finish_reservemap(void *fdt);
1026 int fdt_begin_node(void *fdt, const char *name);
1027 int fdt_property(void *fdt, const char *name, const void *val, int len);
fdt_property_u32(void * fdt,const char * name,uint32_t val)1028 static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
1029 {
1030 	fdt32_t tmp = cpu_to_fdt32(val);
1031 	return fdt_property(fdt, name, &tmp, sizeof(tmp));
1032 }
fdt_property_u64(void * fdt,const char * name,uint64_t val)1033 static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1034 {
1035 	fdt64_t tmp = cpu_to_fdt64(val);
1036 	return fdt_property(fdt, name, &tmp, sizeof(tmp));
1037 }
fdt_property_cell(void * fdt,const char * name,uint32_t val)1038 static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1039 {
1040 	return fdt_property_u32(fdt, name, val);
1041 }
1042 #define fdt_property_string(fdt, name, str) \
1043 	fdt_property(fdt, name, str, strlen(str)+1)
1044 int fdt_end_node(void *fdt);
1045 int fdt_finish(void *fdt);
1046 
1047 /**********************************************************************/
1048 /* Read-write functions                                               */
1049 /**********************************************************************/
1050 
1051 int fdt_create_empty_tree(void *buf, int bufsize);
1052 int fdt_open_into(const void *fdt, void *buf, int bufsize);
1053 int fdt_pack(void *fdt);
1054 
1055 /**
1056  * fdt_add_mem_rsv - add one memory reserve map entry
1057  * @fdt: pointer to the device tree blob
1058  * @address, @size: 64-bit values (native endian)
1059  *
1060  * Adds a reserve map entry to the given blob reserving a region at
1061  * address address of length size.
1062  *
1063  * This function will insert data into the reserve map and will
1064  * therefore change the indexes of some entries in the table.
1065  *
1066  * returns:
1067  *	0, on success
1068  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1069  *		contain the new reservation entry
1070  *	-FDT_ERR_BADMAGIC,
1071  *	-FDT_ERR_BADVERSION,
1072  *	-FDT_ERR_BADSTATE,
1073  *	-FDT_ERR_BADSTRUCTURE,
1074  *	-FDT_ERR_BADLAYOUT,
1075  *	-FDT_ERR_TRUNCATED, standard meanings
1076  */
1077 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1078 
1079 /**
1080  * fdt_del_mem_rsv - remove a memory reserve map entry
1081  * @fdt: pointer to the device tree blob
1082  * @n: entry to remove
1083  *
1084  * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
1085  * the blob.
1086  *
1087  * This function will delete data from the reservation table and will
1088  * therefore change the indexes of some entries in the table.
1089  *
1090  * returns:
1091  *	0, on success
1092  *	-FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
1093  *		are less than n+1 reserve map entries)
1094  *	-FDT_ERR_BADMAGIC,
1095  *	-FDT_ERR_BADVERSION,
1096  *	-FDT_ERR_BADSTATE,
1097  *	-FDT_ERR_BADSTRUCTURE,
1098  *	-FDT_ERR_BADLAYOUT,
1099  *	-FDT_ERR_TRUNCATED, standard meanings
1100  */
1101 int fdt_del_mem_rsv(void *fdt, int n);
1102 
1103 /**
1104  * fdt_set_name - change the name of a given node
1105  * @fdt: pointer to the device tree blob
1106  * @nodeoffset: structure block offset of a node
1107  * @name: name to give the node
1108  *
1109  * fdt_set_name() replaces the name (including unit address, if any)
1110  * of the given node with the given string.  NOTE: this function can't
1111  * efficiently check if the new name is unique amongst the given
1112  * node's siblings; results are undefined if this function is invoked
1113  * with a name equal to one of the given node's siblings.
1114  *
1115  * This function may insert or delete data from the blob, and will
1116  * therefore change the offsets of some existing nodes.
1117  *
1118  * returns:
1119  *	0, on success
1120  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob
1121  *		to contain the new name
1122  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1123  *	-FDT_ERR_BADMAGIC,
1124  *	-FDT_ERR_BADVERSION,
1125  *	-FDT_ERR_BADSTATE, standard meanings
1126  */
1127 int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1128 
1129 /**
1130  * fdt_setprop - create or change a property
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  * @val: pointer to data to set the property value to
1135  * @len: length of the property value
1136  *
1137  * fdt_setprop() sets the value of the named property in the given
1138  * node to the given value and length, creating the property if it
1139  * does not already exist.
1140  *
1141  * This function may insert or delete data from the blob, and will
1142  * therefore change the offsets of some existing nodes.
1143  *
1144  * returns:
1145  *	0, on success
1146  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1147  *		contain the new property value
1148  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1149  *	-FDT_ERR_BADLAYOUT,
1150  *	-FDT_ERR_BADMAGIC,
1151  *	-FDT_ERR_BADVERSION,
1152  *	-FDT_ERR_BADSTATE,
1153  *	-FDT_ERR_BADSTRUCTURE,
1154  *	-FDT_ERR_BADLAYOUT,
1155  *	-FDT_ERR_TRUNCATED, standard meanings
1156  */
1157 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1158 		const void *val, int len);
1159 
1160 /**
1161  * fdt_setprop_u32 - set a property to a 32-bit integer
1162  * @fdt: pointer to the device tree blob
1163  * @nodeoffset: offset of the node whose property to change
1164  * @name: name of the property to change
1165  * @val: 32-bit integer value for the property (native endian)
1166  *
1167  * fdt_setprop_u32() sets the value of the named property in the given
1168  * node to the given 32-bit integer value (converting to big-endian if
1169  * necessary), or creates a new property with that value if it does
1170  * not already exist.
1171  *
1172  * This function may insert or delete data from the blob, and will
1173  * therefore change the offsets of some existing nodes.
1174  *
1175  * returns:
1176  *	0, on success
1177  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1178  *		contain the new property value
1179  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1180  *	-FDT_ERR_BADLAYOUT,
1181  *	-FDT_ERR_BADMAGIC,
1182  *	-FDT_ERR_BADVERSION,
1183  *	-FDT_ERR_BADSTATE,
1184  *	-FDT_ERR_BADSTRUCTURE,
1185  *	-FDT_ERR_BADLAYOUT,
1186  *	-FDT_ERR_TRUNCATED, standard meanings
1187  */
fdt_setprop_u32(void * fdt,int nodeoffset,const char * name,uint32_t val)1188 static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
1189 				  uint32_t val)
1190 {
1191 	fdt32_t tmp = cpu_to_fdt32(val);
1192 	return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1193 }
1194 
1195 /**
1196  * fdt_setprop_u64 - set a property to a 64-bit integer
1197  * @fdt: pointer to the device tree blob
1198  * @nodeoffset: offset of the node whose property to change
1199  * @name: name of the property to change
1200  * @val: 64-bit integer value for the property (native endian)
1201  *
1202  * fdt_setprop_u64() sets the value of the named property in the given
1203  * node to the given 64-bit integer value (converting to big-endian if
1204  * necessary), or creates a new property with that value if it does
1205  * not already exist.
1206  *
1207  * This function may insert or delete data from the blob, and will
1208  * therefore change the offsets of some existing nodes.
1209  *
1210  * returns:
1211  *	0, on success
1212  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1213  *		contain the new property value
1214  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1215  *	-FDT_ERR_BADLAYOUT,
1216  *	-FDT_ERR_BADMAGIC,
1217  *	-FDT_ERR_BADVERSION,
1218  *	-FDT_ERR_BADSTATE,
1219  *	-FDT_ERR_BADSTRUCTURE,
1220  *	-FDT_ERR_BADLAYOUT,
1221  *	-FDT_ERR_TRUNCATED, standard meanings
1222  */
fdt_setprop_u64(void * fdt,int nodeoffset,const char * name,uint64_t val)1223 static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1224 				  uint64_t val)
1225 {
1226 	fdt64_t tmp = cpu_to_fdt64(val);
1227 	return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1228 }
1229 
1230 /**
1231  * fdt_setprop_cell - set a property to a single cell value
1232  *
1233  * This is an alternative name for fdt_setprop_u32()
1234  */
fdt_setprop_cell(void * fdt,int nodeoffset,const char * name,uint32_t val)1235 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1236 				   uint32_t val)
1237 {
1238 	return fdt_setprop_u32(fdt, nodeoffset, name, val);
1239 }
1240 
1241 /**
1242  * fdt_setprop_string - set a property to a string value
1243  * @fdt: pointer to the device tree blob
1244  * @nodeoffset: offset of the node whose property to change
1245  * @name: name of the property to change
1246  * @str: string value for the property
1247  *
1248  * fdt_setprop_string() sets the value of the named property in the
1249  * given node to the given string value (using the length of the
1250  * string to determine the new length of the property), or creates a
1251  * new property with that value if it does not already exist.
1252  *
1253  * This function may insert or delete data from the blob, and will
1254  * therefore change the offsets of some existing nodes.
1255  *
1256  * returns:
1257  *	0, on success
1258  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1259  *		contain the new property value
1260  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1261  *	-FDT_ERR_BADLAYOUT,
1262  *	-FDT_ERR_BADMAGIC,
1263  *	-FDT_ERR_BADVERSION,
1264  *	-FDT_ERR_BADSTATE,
1265  *	-FDT_ERR_BADSTRUCTURE,
1266  *	-FDT_ERR_BADLAYOUT,
1267  *	-FDT_ERR_TRUNCATED, standard meanings
1268  */
1269 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
1270 	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1271 
1272 /**
1273  * fdt_appendprop - append to or create a property
1274  * @fdt: pointer to the device tree blob
1275  * @nodeoffset: offset of the node whose property to change
1276  * @name: name of the property to append to
1277  * @val: pointer to data to append to the property value
1278  * @len: length of the data to append to the property value
1279  *
1280  * fdt_appendprop() appends the value to the named property in the
1281  * given node, creating the property if it does not already exist.
1282  *
1283  * This function may insert data into the blob, and will therefore
1284  * change the offsets of some existing nodes.
1285  *
1286  * returns:
1287  *	0, on success
1288  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1289  *		contain the new property value
1290  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1291  *	-FDT_ERR_BADLAYOUT,
1292  *	-FDT_ERR_BADMAGIC,
1293  *	-FDT_ERR_BADVERSION,
1294  *	-FDT_ERR_BADSTATE,
1295  *	-FDT_ERR_BADSTRUCTURE,
1296  *	-FDT_ERR_BADLAYOUT,
1297  *	-FDT_ERR_TRUNCATED, standard meanings
1298  */
1299 int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1300 		   const void *val, int len);
1301 
1302 /**
1303  * fdt_appendprop_u32 - append a 32-bit integer value to a property
1304  * @fdt: pointer to the device tree blob
1305  * @nodeoffset: offset of the node whose property to change
1306  * @name: name of the property to change
1307  * @val: 32-bit integer value to append to the property (native endian)
1308  *
1309  * fdt_appendprop_u32() appends the given 32-bit integer value
1310  * (converting to big-endian if necessary) to the value of the named
1311  * property in the given node, or creates a new property with that
1312  * value if it does not already exist.
1313  *
1314  * This function may insert data into the blob, and will therefore
1315  * change the offsets of some existing nodes.
1316  *
1317  * returns:
1318  *	0, on success
1319  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1320  *		contain the new property value
1321  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1322  *	-FDT_ERR_BADLAYOUT,
1323  *	-FDT_ERR_BADMAGIC,
1324  *	-FDT_ERR_BADVERSION,
1325  *	-FDT_ERR_BADSTATE,
1326  *	-FDT_ERR_BADSTRUCTURE,
1327  *	-FDT_ERR_BADLAYOUT,
1328  *	-FDT_ERR_TRUNCATED, standard meanings
1329  */
fdt_appendprop_u32(void * fdt,int nodeoffset,const char * name,uint32_t val)1330 static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1331 				     const char *name, uint32_t val)
1332 {
1333 	fdt32_t tmp = cpu_to_fdt32(val);
1334 	return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1335 }
1336 
1337 /**
1338  * fdt_appendprop_u64 - append a 64-bit integer value to a property
1339  * @fdt: pointer to the device tree blob
1340  * @nodeoffset: offset of the node whose property to change
1341  * @name: name of the property to change
1342  * @val: 64-bit integer value to append to the property (native endian)
1343  *
1344  * fdt_appendprop_u64() appends the given 64-bit integer value
1345  * (converting to big-endian if necessary) to the value of the named
1346  * property in the given node, or creates a new property with that
1347  * value if it does not already exist.
1348  *
1349  * This function may insert data into the blob, and will therefore
1350  * change the offsets of some existing nodes.
1351  *
1352  * returns:
1353  *	0, on success
1354  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1355  *		contain the new property value
1356  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1357  *	-FDT_ERR_BADLAYOUT,
1358  *	-FDT_ERR_BADMAGIC,
1359  *	-FDT_ERR_BADVERSION,
1360  *	-FDT_ERR_BADSTATE,
1361  *	-FDT_ERR_BADSTRUCTURE,
1362  *	-FDT_ERR_BADLAYOUT,
1363  *	-FDT_ERR_TRUNCATED, standard meanings
1364  */
fdt_appendprop_u64(void * fdt,int nodeoffset,const char * name,uint64_t val)1365 static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1366 				     const char *name, uint64_t val)
1367 {
1368 	fdt64_t tmp = cpu_to_fdt64(val);
1369 	return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1370 }
1371 
1372 /**
1373  * fdt_appendprop_cell - append a single cell value to a property
1374  *
1375  * This is an alternative name for fdt_appendprop_u32()
1376  */
fdt_appendprop_cell(void * fdt,int nodeoffset,const char * name,uint32_t val)1377 static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1378 				      const char *name, uint32_t val)
1379 {
1380 	return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1381 }
1382 
1383 /**
1384  * fdt_appendprop_string - append a string to a property
1385  * @fdt: pointer to the device tree blob
1386  * @nodeoffset: offset of the node whose property to change
1387  * @name: name of the property to change
1388  * @str: string value to append to the property
1389  *
1390  * fdt_appendprop_string() appends the given string to the value of
1391  * the named property in the given node, or creates a new property
1392  * with that value if it does not already exist.
1393  *
1394  * This function may insert data into the blob, and will therefore
1395  * change the offsets of some existing nodes.
1396  *
1397  * returns:
1398  *	0, on success
1399  *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1400  *		contain the new property value
1401  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1402  *	-FDT_ERR_BADLAYOUT,
1403  *	-FDT_ERR_BADMAGIC,
1404  *	-FDT_ERR_BADVERSION,
1405  *	-FDT_ERR_BADSTATE,
1406  *	-FDT_ERR_BADSTRUCTURE,
1407  *	-FDT_ERR_BADLAYOUT,
1408  *	-FDT_ERR_TRUNCATED, standard meanings
1409  */
1410 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1411 	fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1412 
1413 /**
1414  * fdt_delprop - delete a property
1415  * @fdt: pointer to the device tree blob
1416  * @nodeoffset: offset of the node whose property to nop
1417  * @name: name of the property to nop
1418  *
1419  * fdt_del_property() will delete the given property.
1420  *
1421  * This function will delete data from the blob, and will therefore
1422  * change the offsets of some existing nodes.
1423  *
1424  * returns:
1425  *	0, on success
1426  *	-FDT_ERR_NOTFOUND, node does not have the named property
1427  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1428  *	-FDT_ERR_BADLAYOUT,
1429  *	-FDT_ERR_BADMAGIC,
1430  *	-FDT_ERR_BADVERSION,
1431  *	-FDT_ERR_BADSTATE,
1432  *	-FDT_ERR_BADSTRUCTURE,
1433  *	-FDT_ERR_TRUNCATED, standard meanings
1434  */
1435 int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1436 
1437 /**
1438  * fdt_add_subnode_namelen - creates a new node based on substring
1439  * @fdt: pointer to the device tree blob
1440  * @parentoffset: structure block offset of a node
1441  * @name: name of the subnode to locate
1442  * @namelen: number of characters of name to consider
1443  *
1444  * Identical to fdt_add_subnode(), but use only the first namelen
1445  * characters of name as the name of the new node.  This is useful for
1446  * creating subnodes based on a portion of a larger string, such as a
1447  * full path.
1448  */
1449 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1450 			    const char *name, int namelen);
1451 
1452 /**
1453  * fdt_add_subnode - creates a new node
1454  * @fdt: pointer to the device tree blob
1455  * @parentoffset: structure block offset of a node
1456  * @name: name of the subnode to locate
1457  *
1458  * fdt_add_subnode() creates a new node as a subnode of the node at
1459  * structure block offset parentoffset, with the given name (which
1460  * should include the unit address, if any).
1461  *
1462  * This function will insert data into the blob, and will therefore
1463  * change the offsets of some existing nodes.
1464 
1465  * returns:
1466  *	structure block offset of the created nodeequested subnode (>=0), on success
1467  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
1468  *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
1469  *	-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1470  *		the given name
1471  *	-FDT_ERR_NOSPACE, if there is insufficient free space in the
1472  *		blob to contain the new node
1473  *	-FDT_ERR_NOSPACE
1474  *	-FDT_ERR_BADLAYOUT
1475  *      -FDT_ERR_BADMAGIC,
1476  *	-FDT_ERR_BADVERSION,
1477  *	-FDT_ERR_BADSTATE,
1478  *	-FDT_ERR_BADSTRUCTURE,
1479  *	-FDT_ERR_TRUNCATED, standard meanings.
1480  */
1481 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1482 
1483 /**
1484  * fdt_del_node - delete a node (subtree)
1485  * @fdt: pointer to the device tree blob
1486  * @nodeoffset: offset of the node to nop
1487  *
1488  * fdt_del_node() will remove the given node, including all its
1489  * subnodes if any, from the blob.
1490  *
1491  * This function will delete data from the blob, and will therefore
1492  * change the offsets of some existing nodes.
1493  *
1494  * returns:
1495  *	0, on success
1496  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1497  *	-FDT_ERR_BADLAYOUT,
1498  *	-FDT_ERR_BADMAGIC,
1499  *	-FDT_ERR_BADVERSION,
1500  *	-FDT_ERR_BADSTATE,
1501  *	-FDT_ERR_BADSTRUCTURE,
1502  *	-FDT_ERR_TRUNCATED, standard meanings
1503  */
1504 int fdt_del_node(void *fdt, int nodeoffset);
1505 
1506 /**********************************************************************/
1507 /* Debugging / informational functions                                */
1508 /**********************************************************************/
1509 
1510 const char *fdt_strerror(int errval);
1511 
1512 #endif /* _LIBFDT_H */
1513