Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/scripts/dtc/libfdt/libfdt.h
10818 views
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 0x10
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
* value. phandle values of 0 and -1 are not permitted. */
84
#define FDT_ERR_BADSTATE 7
85
/* FDT_ERR_BADSTATE: Function was passed an incomplete device
86
* tree created by the sequential-write functions, which is
87
* not sufficiently complete for the requested operation. */
88
89
/* Error codes: codes for bad device tree blobs */
90
#define FDT_ERR_TRUNCATED 8
91
/* FDT_ERR_TRUNCATED: Structure block of the given device tree
92
* ends without an FDT_END tag. */
93
#define FDT_ERR_BADMAGIC 9
94
/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
95
* device tree at all - it is missing the flattened device
96
* tree magic number. */
97
#define FDT_ERR_BADVERSION 10
98
/* FDT_ERR_BADVERSION: Given device tree has a version which
99
* can't be handled by the requested operation. For
100
* read-write functions, this may mean that fdt_open_into() is
101
* required to convert the tree to the expected version. */
102
#define FDT_ERR_BADSTRUCTURE 11
103
/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
104
* structure block or other serious error (e.g. misnested
105
* nodes, or subnodes preceding properties). */
106
#define FDT_ERR_BADLAYOUT 12
107
/* FDT_ERR_BADLAYOUT: For read-write functions, the given
108
* device tree has it's sub-blocks in an order that the
109
* function can't handle (memory reserve map, then structure,
110
* then strings). Use fdt_open_into() to reorganize the tree
111
* into a form suitable for the read-write operations. */
112
113
/* "Can't happen" error indicating a bug in libfdt */
114
#define FDT_ERR_INTERNAL 13
115
/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
116
* Should never be returned, if it is, it indicates a bug in
117
* libfdt itself. */
118
119
#define FDT_ERR_MAX 13
120
121
/**********************************************************************/
122
/* Low-level functions (you probably don't need these) */
123
/**********************************************************************/
124
125
const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
126
static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
127
{
128
return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
129
}
130
131
uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
132
133
/**********************************************************************/
134
/* Traversal functions */
135
/**********************************************************************/
136
137
int fdt_next_node(const void *fdt, int offset, int *depth);
138
139
/**********************************************************************/
140
/* General functions */
141
/**********************************************************************/
142
143
#define fdt_get_header(fdt, field) \
144
(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
145
#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
146
#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
147
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
148
#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
149
#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
150
#define fdt_version(fdt) (fdt_get_header(fdt, version))
151
#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
152
#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
153
#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
154
#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
155
156
#define __fdt_set_hdr(name) \
157
static inline void fdt_set_##name(void *fdt, uint32_t val) \
158
{ \
159
struct fdt_header *fdth = fdt; \
160
fdth->name = cpu_to_fdt32(val); \
161
}
162
__fdt_set_hdr(magic);
163
__fdt_set_hdr(totalsize);
164
__fdt_set_hdr(off_dt_struct);
165
__fdt_set_hdr(off_dt_strings);
166
__fdt_set_hdr(off_mem_rsvmap);
167
__fdt_set_hdr(version);
168
__fdt_set_hdr(last_comp_version);
169
__fdt_set_hdr(boot_cpuid_phys);
170
__fdt_set_hdr(size_dt_strings);
171
__fdt_set_hdr(size_dt_struct);
172
#undef __fdt_set_hdr
173
174
/**
175
* fdt_check_header - sanity check a device tree or possible device tree
176
* @fdt: pointer to data which might be a flattened device tree
177
*
178
* fdt_check_header() checks that the given buffer contains what
179
* appears to be a flattened device tree with sane information in its
180
* header.
181
*
182
* returns:
183
* 0, if the buffer appears to contain a valid device tree
184
* -FDT_ERR_BADMAGIC,
185
* -FDT_ERR_BADVERSION,
186
* -FDT_ERR_BADSTATE, standard meanings, as above
187
*/
188
int fdt_check_header(const void *fdt);
189
190
/**
191
* fdt_move - move a device tree around in memory
192
* @fdt: pointer to the device tree to move
193
* @buf: pointer to memory where the device is to be moved
194
* @bufsize: size of the memory space at buf
195
*
196
* fdt_move() relocates, if possible, the device tree blob located at
197
* fdt to the buffer at buf of size bufsize. The buffer may overlap
198
* with the existing device tree blob at fdt. Therefore,
199
* fdt_move(fdt, fdt, fdt_totalsize(fdt))
200
* should always succeed.
201
*
202
* returns:
203
* 0, on success
204
* -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
205
* -FDT_ERR_BADMAGIC,
206
* -FDT_ERR_BADVERSION,
207
* -FDT_ERR_BADSTATE, standard meanings
208
*/
209
int fdt_move(const void *fdt, void *buf, int bufsize);
210
211
/**********************************************************************/
212
/* Read-only functions */
213
/**********************************************************************/
214
215
/**
216
* fdt_string - retrieve a string from the strings block of a device tree
217
* @fdt: pointer to the device tree blob
218
* @stroffset: offset of the string within the strings block (native endian)
219
*
220
* fdt_string() retrieves a pointer to a single string from the
221
* strings block of the device tree blob at fdt.
222
*
223
* returns:
224
* a pointer to the string, on success
225
* NULL, if stroffset is out of bounds
226
*/
227
const char *fdt_string(const void *fdt, int stroffset);
228
229
/**
230
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
231
* @fdt: pointer to the device tree blob
232
*
233
* Returns the number of entries in the device tree blob's memory
234
* reservation map. This does not include the terminating 0,0 entry
235
* or any other (0,0) entries reserved for expansion.
236
*
237
* returns:
238
* the number of entries
239
*/
240
int fdt_num_mem_rsv(const void *fdt);
241
242
/**
243
* fdt_get_mem_rsv - retrieve one memory reserve map entry
244
* @fdt: pointer to the device tree blob
245
* @address, @size: pointers to 64-bit variables
246
*
247
* On success, *address and *size will contain the address and size of
248
* the n-th reserve map entry from the device tree blob, in
249
* native-endian format.
250
*
251
* returns:
252
* 0, on success
253
* -FDT_ERR_BADMAGIC,
254
* -FDT_ERR_BADVERSION,
255
* -FDT_ERR_BADSTATE, standard meanings
256
*/
257
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
258
259
/**
260
* fdt_subnode_offset_namelen - find a subnode based on substring
261
* @fdt: pointer to the device tree blob
262
* @parentoffset: structure block offset of a node
263
* @name: name of the subnode to locate
264
* @namelen: number of characters of name to consider
265
*
266
* Identical to fdt_subnode_offset(), but only examine the first
267
* namelen characters of name for matching the subnode name. This is
268
* useful for finding subnodes based on a portion of a larger string,
269
* such as a full path.
270
*/
271
int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
272
const char *name, int namelen);
273
/**
274
* fdt_subnode_offset - find a subnode of a given node
275
* @fdt: pointer to the device tree blob
276
* @parentoffset: structure block offset of a node
277
* @name: name of the subnode to locate
278
*
279
* fdt_subnode_offset() finds a subnode of the node at structure block
280
* offset parentoffset with the given name. name may include a unit
281
* address, in which case fdt_subnode_offset() will find the subnode
282
* with that unit address, or the unit address may be omitted, in
283
* which case fdt_subnode_offset() will find an arbitrary subnode
284
* whose name excluding unit address matches the given name.
285
*
286
* returns:
287
* structure block offset of the requested subnode (>=0), on success
288
* -FDT_ERR_NOTFOUND, if the requested subnode does not exist
289
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
290
* -FDT_ERR_BADMAGIC,
291
* -FDT_ERR_BADVERSION,
292
* -FDT_ERR_BADSTATE,
293
* -FDT_ERR_BADSTRUCTURE,
294
* -FDT_ERR_TRUNCATED, standard meanings.
295
*/
296
int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
297
298
/**
299
* fdt_path_offset - find a tree node by its full path
300
* @fdt: pointer to the device tree blob
301
* @path: full path of the node to locate
302
*
303
* fdt_path_offset() finds a node of a given path in the device tree.
304
* Each path component may omit the unit address portion, but the
305
* results of this are undefined if any such path component is
306
* ambiguous (that is if there are multiple nodes at the relevant
307
* level matching the given component, differentiated only by unit
308
* address).
309
*
310
* returns:
311
* structure block offset of the node with the requested path (>=0), on success
312
* -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
313
* -FDT_ERR_NOTFOUND, if the requested node does not exist
314
* -FDT_ERR_BADMAGIC,
315
* -FDT_ERR_BADVERSION,
316
* -FDT_ERR_BADSTATE,
317
* -FDT_ERR_BADSTRUCTURE,
318
* -FDT_ERR_TRUNCATED, standard meanings.
319
*/
320
int fdt_path_offset(const void *fdt, const char *path);
321
322
/**
323
* fdt_get_name - retrieve the name of a given node
324
* @fdt: pointer to the device tree blob
325
* @nodeoffset: structure block offset of the starting node
326
* @lenp: pointer to an integer variable (will be overwritten) or NULL
327
*
328
* fdt_get_name() retrieves the name (including unit address) of the
329
* device tree node at structure block offset nodeoffset. If lenp is
330
* non-NULL, the length of this name is also returned, in the integer
331
* pointed to by lenp.
332
*
333
* returns:
334
* pointer to the node's name, on success
335
* If lenp is non-NULL, *lenp contains the length of that name (>=0)
336
* NULL, on error
337
* if lenp is non-NULL *lenp contains an error code (<0):
338
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
339
* -FDT_ERR_BADMAGIC,
340
* -FDT_ERR_BADVERSION,
341
* -FDT_ERR_BADSTATE, standard meanings
342
*/
343
const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
344
345
/**
346
* fdt_get_property - find a given property in a given node
347
* @fdt: pointer to the device tree blob
348
* @nodeoffset: offset of the node whose property to find
349
* @name: name of the property to find
350
* @lenp: pointer to an integer variable (will be overwritten) or NULL
351
*
352
* fdt_get_property() retrieves a pointer to the fdt_property
353
* structure within the device tree blob corresponding to the property
354
* named 'name' of the node at offset nodeoffset. If lenp is
355
* non-NULL, the length of the property value is also returned, in the
356
* integer pointed to by lenp.
357
*
358
* returns:
359
* pointer to the structure representing the property
360
* if lenp is non-NULL, *lenp contains the length of the property
361
* value (>=0)
362
* NULL, on error
363
* if lenp is non-NULL, *lenp contains an error code (<0):
364
* -FDT_ERR_NOTFOUND, node does not have named property
365
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
366
* -FDT_ERR_BADMAGIC,
367
* -FDT_ERR_BADVERSION,
368
* -FDT_ERR_BADSTATE,
369
* -FDT_ERR_BADSTRUCTURE,
370
* -FDT_ERR_TRUNCATED, standard meanings
371
*/
372
const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
373
const char *name, int *lenp);
374
static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
375
const char *name,
376
int *lenp)
377
{
378
return (struct fdt_property *)(uintptr_t)
379
fdt_get_property(fdt, nodeoffset, name, lenp);
380
}
381
382
/**
383
* fdt_getprop - retrieve the value of a given property
384
* @fdt: pointer to the device tree blob
385
* @nodeoffset: offset of the node whose property to find
386
* @name: name of the property to find
387
* @lenp: pointer to an integer variable (will be overwritten) or NULL
388
*
389
* fdt_getprop() retrieves a pointer to the value of the property
390
* named 'name' of the node at offset nodeoffset (this will be a
391
* pointer to within the device blob itself, not a copy of the value).
392
* If lenp is non-NULL, the length of the property value is also
393
* returned, in the integer pointed to by lenp.
394
*
395
* returns:
396
* pointer to the property's value
397
* if lenp is non-NULL, *lenp contains the length of the property
398
* value (>=0)
399
* NULL, on error
400
* if lenp is non-NULL, *lenp contains an error code (<0):
401
* -FDT_ERR_NOTFOUND, node does not have named property
402
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
403
* -FDT_ERR_BADMAGIC,
404
* -FDT_ERR_BADVERSION,
405
* -FDT_ERR_BADSTATE,
406
* -FDT_ERR_BADSTRUCTURE,
407
* -FDT_ERR_TRUNCATED, standard meanings
408
*/
409
const void *fdt_getprop(const void *fdt, int nodeoffset,
410
const char *name, int *lenp);
411
static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
412
const char *name, int *lenp)
413
{
414
return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
415
}
416
417
/**
418
* fdt_get_phandle - retrieve the phandle of a given node
419
* @fdt: pointer to the device tree blob
420
* @nodeoffset: structure block offset of the node
421
*
422
* fdt_get_phandle() retrieves the phandle of the device tree node at
423
* structure block offset nodeoffset.
424
*
425
* returns:
426
* the phandle of the node at nodeoffset, on success (!= 0, != -1)
427
* 0, if the node has no phandle, or another error occurs
428
*/
429
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
430
431
/**
432
* fdt_get_path - determine the full path of a node
433
* @fdt: pointer to the device tree blob
434
* @nodeoffset: offset of the node whose path to find
435
* @buf: character buffer to contain the returned path (will be overwritten)
436
* @buflen: size of the character buffer at buf
437
*
438
* fdt_get_path() computes the full path of the node at offset
439
* nodeoffset, and records that path in the buffer at buf.
440
*
441
* NOTE: This function is expensive, as it must scan the device tree
442
* structure from the start to nodeoffset.
443
*
444
* returns:
445
* 0, on success
446
* buf contains the absolute path of the node at
447
* nodeoffset, as a NUL-terminated string.
448
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
449
* -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
450
* characters and will not fit in the given buffer.
451
* -FDT_ERR_BADMAGIC,
452
* -FDT_ERR_BADVERSION,
453
* -FDT_ERR_BADSTATE,
454
* -FDT_ERR_BADSTRUCTURE, standard meanings
455
*/
456
int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
457
458
/**
459
* fdt_supernode_atdepth_offset - find a specific ancestor of a node
460
* @fdt: pointer to the device tree blob
461
* @nodeoffset: offset of the node whose parent to find
462
* @supernodedepth: depth of the ancestor to find
463
* @nodedepth: pointer to an integer variable (will be overwritten) or NULL
464
*
465
* fdt_supernode_atdepth_offset() finds an ancestor of the given node
466
* at a specific depth from the root (where the root itself has depth
467
* 0, its immediate subnodes depth 1 and so forth). So
468
* fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
469
* will always return 0, the offset of the root node. If the node at
470
* nodeoffset has depth D, then:
471
* fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
472
* will return nodeoffset itself.
473
*
474
* NOTE: This function is expensive, as it must scan the device tree
475
* structure from the start to nodeoffset.
476
*
477
* returns:
478
479
* structure block offset of the node at node offset's ancestor
480
* of depth supernodedepth (>=0), on success
481
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
482
* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
483
* -FDT_ERR_BADMAGIC,
484
* -FDT_ERR_BADVERSION,
485
* -FDT_ERR_BADSTATE,
486
* -FDT_ERR_BADSTRUCTURE, standard meanings
487
*/
488
int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
489
int supernodedepth, int *nodedepth);
490
491
/**
492
* fdt_node_depth - find the depth of a given node
493
* @fdt: pointer to the device tree blob
494
* @nodeoffset: offset of the node whose parent to find
495
*
496
* fdt_node_depth() finds the depth of a given node. The root node
497
* has depth 0, its immediate subnodes depth 1 and so forth.
498
*
499
* NOTE: This function is expensive, as it must scan the device tree
500
* structure from the start to nodeoffset.
501
*
502
* returns:
503
* depth of the node at nodeoffset (>=0), on success
504
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
505
* -FDT_ERR_BADMAGIC,
506
* -FDT_ERR_BADVERSION,
507
* -FDT_ERR_BADSTATE,
508
* -FDT_ERR_BADSTRUCTURE, standard meanings
509
*/
510
int fdt_node_depth(const void *fdt, int nodeoffset);
511
512
/**
513
* fdt_parent_offset - find the parent of a given node
514
* @fdt: pointer to the device tree blob
515
* @nodeoffset: offset of the node whose parent to find
516
*
517
* fdt_parent_offset() locates the parent node of a given node (that
518
* is, it finds the offset of the node which contains the node at
519
* nodeoffset as a subnode).
520
*
521
* NOTE: This function is expensive, as it must scan the device tree
522
* structure from the start to nodeoffset, *twice*.
523
*
524
* returns:
525
* structure block offset of the parent of the node at nodeoffset
526
* (>=0), on success
527
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
528
* -FDT_ERR_BADMAGIC,
529
* -FDT_ERR_BADVERSION,
530
* -FDT_ERR_BADSTATE,
531
* -FDT_ERR_BADSTRUCTURE, standard meanings
532
*/
533
int fdt_parent_offset(const void *fdt, int nodeoffset);
534
535
/**
536
* fdt_node_offset_by_prop_value - find nodes with a given property value
537
* @fdt: pointer to the device tree blob
538
* @startoffset: only find nodes after this offset
539
* @propname: property name to check
540
* @propval: property value to search for
541
* @proplen: length of the value in propval
542
*
543
* fdt_node_offset_by_prop_value() returns the offset of the first
544
* node after startoffset, which has a property named propname whose
545
* value is of length proplen and has value equal to propval; or if
546
* startoffset is -1, the very first such node in the tree.
547
*
548
* To iterate through all nodes matching the criterion, the following
549
* idiom can be used:
550
* offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
551
* propval, proplen);
552
* while (offset != -FDT_ERR_NOTFOUND) {
553
* // other code here
554
* offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
555
* propval, proplen);
556
* }
557
*
558
* Note the -1 in the first call to the function, if 0 is used here
559
* instead, the function will never locate the root node, even if it
560
* matches the criterion.
561
*
562
* returns:
563
* structure block offset of the located node (>= 0, >startoffset),
564
* on success
565
* -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
566
* tree after startoffset
567
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
568
* -FDT_ERR_BADMAGIC,
569
* -FDT_ERR_BADVERSION,
570
* -FDT_ERR_BADSTATE,
571
* -FDT_ERR_BADSTRUCTURE, standard meanings
572
*/
573
int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
574
const char *propname,
575
const void *propval, int proplen);
576
577
/**
578
* fdt_node_offset_by_phandle - find the node with a given phandle
579
* @fdt: pointer to the device tree blob
580
* @phandle: phandle value
581
*
582
* fdt_node_offset_by_phandle() returns the offset of the node
583
* which has the given phandle value. If there is more than one node
584
* in the tree with the given phandle (an invalid tree), results are
585
* undefined.
586
*
587
* returns:
588
* structure block offset of the located node (>= 0), on success
589
* -FDT_ERR_NOTFOUND, no node with that phandle exists
590
* -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
591
* -FDT_ERR_BADMAGIC,
592
* -FDT_ERR_BADVERSION,
593
* -FDT_ERR_BADSTATE,
594
* -FDT_ERR_BADSTRUCTURE, standard meanings
595
*/
596
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
597
598
/**
599
* fdt_node_check_compatible: check a node's compatible property
600
* @fdt: pointer to the device tree blob
601
* @nodeoffset: offset of a tree node
602
* @compatible: string to match against
603
*
604
*
605
* fdt_node_check_compatible() returns 0 if the given node contains a
606
* 'compatible' property with the given string as one of its elements,
607
* it returns non-zero otherwise, or on error.
608
*
609
* returns:
610
* 0, if the node has a 'compatible' property listing the given string
611
* 1, if the node has a 'compatible' property, but it does not list
612
* the given string
613
* -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
614
* -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
615
* -FDT_ERR_BADMAGIC,
616
* -FDT_ERR_BADVERSION,
617
* -FDT_ERR_BADSTATE,
618
* -FDT_ERR_BADSTRUCTURE, standard meanings
619
*/
620
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
621
const char *compatible);
622
623
/**
624
* fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
625
* @fdt: pointer to the device tree blob
626
* @startoffset: only find nodes after this offset
627
* @compatible: 'compatible' string to match against
628
*
629
* fdt_node_offset_by_compatible() returns the offset of the first
630
* node after startoffset, which has a 'compatible' property which
631
* lists the given compatible string; or if startoffset is -1, the
632
* very first such node in the tree.
633
*
634
* To iterate through all nodes matching the criterion, the following
635
* idiom can be used:
636
* offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
637
* while (offset != -FDT_ERR_NOTFOUND) {
638
* // other code here
639
* offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
640
* }
641
*
642
* Note the -1 in the first call to the function, if 0 is used here
643
* instead, the function will never locate the root node, even if it
644
* matches the criterion.
645
*
646
* returns:
647
* structure block offset of the located node (>= 0, >startoffset),
648
* on success
649
* -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
650
* tree after startoffset
651
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
652
* -FDT_ERR_BADMAGIC,
653
* -FDT_ERR_BADVERSION,
654
* -FDT_ERR_BADSTATE,
655
* -FDT_ERR_BADSTRUCTURE, standard meanings
656
*/
657
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
658
const char *compatible);
659
660
/**********************************************************************/
661
/* Write-in-place functions */
662
/**********************************************************************/
663
664
/**
665
* fdt_setprop_inplace - change a property's value, but not its size
666
* @fdt: pointer to the device tree blob
667
* @nodeoffset: offset of the node whose property to change
668
* @name: name of the property to change
669
* @val: pointer to data to replace the property value with
670
* @len: length of the property value
671
*
672
* fdt_setprop_inplace() replaces the value of a given property with
673
* the data in val, of length len. This function cannot change the
674
* size of a property, and so will only work if len is equal to the
675
* current length of the property.
676
*
677
* This function will alter only the bytes in the blob which contain
678
* the given property value, and will not alter or move any other part
679
* of the tree.
680
*
681
* returns:
682
* 0, on success
683
* -FDT_ERR_NOSPACE, if len is not equal to the property's current length
684
* -FDT_ERR_NOTFOUND, node does not have the named property
685
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
686
* -FDT_ERR_BADMAGIC,
687
* -FDT_ERR_BADVERSION,
688
* -FDT_ERR_BADSTATE,
689
* -FDT_ERR_BADSTRUCTURE,
690
* -FDT_ERR_TRUNCATED, standard meanings
691
*/
692
int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
693
const void *val, int len);
694
695
/**
696
* fdt_setprop_inplace_cell - change the value of a single-cell property
697
* @fdt: pointer to the device tree blob
698
* @nodeoffset: offset of the node whose property to change
699
* @name: name of the property to change
700
* @val: cell (32-bit integer) value to replace the property with
701
*
702
* fdt_setprop_inplace_cell() replaces the value of a given property
703
* with the 32-bit integer cell value in val, converting val to
704
* big-endian if necessary. This function cannot change the size of a
705
* property, and so will only work if the property already exists and
706
* has length 4.
707
*
708
* This function will alter only the bytes in the blob which contain
709
* the given property value, and will not alter or move any other part
710
* of the tree.
711
*
712
* returns:
713
* 0, on success
714
* -FDT_ERR_NOSPACE, if the property's length is not equal to 4
715
* -FDT_ERR_NOTFOUND, node does not have the named property
716
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
717
* -FDT_ERR_BADMAGIC,
718
* -FDT_ERR_BADVERSION,
719
* -FDT_ERR_BADSTATE,
720
* -FDT_ERR_BADSTRUCTURE,
721
* -FDT_ERR_TRUNCATED, standard meanings
722
*/
723
static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
724
const char *name, uint32_t val)
725
{
726
val = cpu_to_fdt32(val);
727
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
728
}
729
730
/**
731
* fdt_nop_property - replace a property with nop tags
732
* @fdt: pointer to the device tree blob
733
* @nodeoffset: offset of the node whose property to nop
734
* @name: name of the property to nop
735
*
736
* fdt_nop_property() will replace a given property's representation
737
* in the blob with FDT_NOP tags, effectively removing it from the
738
* tree.
739
*
740
* This function will alter only the bytes in the blob which contain
741
* the property, and will not alter or move any other part of the
742
* tree.
743
*
744
* returns:
745
* 0, on success
746
* -FDT_ERR_NOTFOUND, node does not have the named property
747
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
748
* -FDT_ERR_BADMAGIC,
749
* -FDT_ERR_BADVERSION,
750
* -FDT_ERR_BADSTATE,
751
* -FDT_ERR_BADSTRUCTURE,
752
* -FDT_ERR_TRUNCATED, standard meanings
753
*/
754
int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
755
756
/**
757
* fdt_nop_node - replace a node (subtree) with nop tags
758
* @fdt: pointer to the device tree blob
759
* @nodeoffset: offset of the node to nop
760
*
761
* fdt_nop_node() will replace a given node's representation in the
762
* blob, including all its subnodes, if any, with FDT_NOP tags,
763
* effectively removing it from the tree.
764
*
765
* This function will alter only the bytes in the blob which contain
766
* the node and its properties and subnodes, and will not alter or
767
* move any other part of the tree.
768
*
769
* returns:
770
* 0, on success
771
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
772
* -FDT_ERR_BADMAGIC,
773
* -FDT_ERR_BADVERSION,
774
* -FDT_ERR_BADSTATE,
775
* -FDT_ERR_BADSTRUCTURE,
776
* -FDT_ERR_TRUNCATED, standard meanings
777
*/
778
int fdt_nop_node(void *fdt, int nodeoffset);
779
780
/**********************************************************************/
781
/* Sequential write functions */
782
/**********************************************************************/
783
784
int fdt_create(void *buf, int bufsize);
785
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
786
int fdt_finish_reservemap(void *fdt);
787
int fdt_begin_node(void *fdt, const char *name);
788
int fdt_property(void *fdt, const char *name, const void *val, int len);
789
static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
790
{
791
val = cpu_to_fdt32(val);
792
return fdt_property(fdt, name, &val, sizeof(val));
793
}
794
#define fdt_property_string(fdt, name, str) \
795
fdt_property(fdt, name, str, strlen(str)+1)
796
int fdt_end_node(void *fdt);
797
int fdt_finish(void *fdt);
798
799
/**********************************************************************/
800
/* Read-write functions */
801
/**********************************************************************/
802
803
int fdt_open_into(const void *fdt, void *buf, int bufsize);
804
int fdt_pack(void *fdt);
805
806
/**
807
* fdt_add_mem_rsv - add one memory reserve map entry
808
* @fdt: pointer to the device tree blob
809
* @address, @size: 64-bit values (native endian)
810
*
811
* Adds a reserve map entry to the given blob reserving a region at
812
* address address of length size.
813
*
814
* This function will insert data into the reserve map and will
815
* therefore change the indexes of some entries in the table.
816
*
817
* returns:
818
* 0, on success
819
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
820
* contain the new reservation entry
821
* -FDT_ERR_BADMAGIC,
822
* -FDT_ERR_BADVERSION,
823
* -FDT_ERR_BADSTATE,
824
* -FDT_ERR_BADSTRUCTURE,
825
* -FDT_ERR_BADLAYOUT,
826
* -FDT_ERR_TRUNCATED, standard meanings
827
*/
828
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
829
830
/**
831
* fdt_del_mem_rsv - remove a memory reserve map entry
832
* @fdt: pointer to the device tree blob
833
* @n: entry to remove
834
*
835
* fdt_del_mem_rsv() removes the n-th memory reserve map entry from
836
* the blob.
837
*
838
* This function will delete data from the reservation table and will
839
* therefore change the indexes of some entries in the table.
840
*
841
* returns:
842
* 0, on success
843
* -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
844
* are less than n+1 reserve map entries)
845
* -FDT_ERR_BADMAGIC,
846
* -FDT_ERR_BADVERSION,
847
* -FDT_ERR_BADSTATE,
848
* -FDT_ERR_BADSTRUCTURE,
849
* -FDT_ERR_BADLAYOUT,
850
* -FDT_ERR_TRUNCATED, standard meanings
851
*/
852
int fdt_del_mem_rsv(void *fdt, int n);
853
854
/**
855
* fdt_set_name - change the name of a given node
856
* @fdt: pointer to the device tree blob
857
* @nodeoffset: structure block offset of a node
858
* @name: name to give the node
859
*
860
* fdt_set_name() replaces the name (including unit address, if any)
861
* of the given node with the given string. NOTE: this function can't
862
* efficiently check if the new name is unique amongst the given
863
* node's siblings; results are undefined if this function is invoked
864
* with a name equal to one of the given node's siblings.
865
*
866
* This function may insert or delete data from the blob, and will
867
* therefore change the offsets of some existing nodes.
868
*
869
* returns:
870
* 0, on success
871
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob
872
* to contain the new name
873
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
874
* -FDT_ERR_BADMAGIC,
875
* -FDT_ERR_BADVERSION,
876
* -FDT_ERR_BADSTATE, standard meanings
877
*/
878
int fdt_set_name(void *fdt, int nodeoffset, const char *name);
879
880
/**
881
* fdt_setprop - create or change a property
882
* @fdt: pointer to the device tree blob
883
* @nodeoffset: offset of the node whose property to change
884
* @name: name of the property to change
885
* @val: pointer to data to set the property value to
886
* @len: length of the property value
887
*
888
* fdt_setprop() sets the value of the named property in the given
889
* node to the given value and length, creating the property if it
890
* does not already exist.
891
*
892
* This function may insert or delete data from the blob, and will
893
* therefore change the offsets of some existing nodes.
894
*
895
* returns:
896
* 0, on success
897
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
898
* contain the new property value
899
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
900
* -FDT_ERR_BADLAYOUT,
901
* -FDT_ERR_BADMAGIC,
902
* -FDT_ERR_BADVERSION,
903
* -FDT_ERR_BADSTATE,
904
* -FDT_ERR_BADSTRUCTURE,
905
* -FDT_ERR_BADLAYOUT,
906
* -FDT_ERR_TRUNCATED, standard meanings
907
*/
908
int fdt_setprop(void *fdt, int nodeoffset, const char *name,
909
const void *val, int len);
910
911
/**
912
* fdt_setprop_cell - set a property to a single cell value
913
* @fdt: pointer to the device tree blob
914
* @nodeoffset: offset of the node whose property to change
915
* @name: name of the property to change
916
* @val: 32-bit integer value for the property (native endian)
917
*
918
* fdt_setprop_cell() sets the value of the named property in the
919
* given node to the given cell value (converting to big-endian if
920
* necessary), or creates a new property with that value if it does
921
* not already exist.
922
*
923
* This function may insert or delete data from the blob, and will
924
* therefore change the offsets of some existing nodes.
925
*
926
* returns:
927
* 0, on success
928
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
929
* contain the new property value
930
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
931
* -FDT_ERR_BADLAYOUT,
932
* -FDT_ERR_BADMAGIC,
933
* -FDT_ERR_BADVERSION,
934
* -FDT_ERR_BADSTATE,
935
* -FDT_ERR_BADSTRUCTURE,
936
* -FDT_ERR_BADLAYOUT,
937
* -FDT_ERR_TRUNCATED, standard meanings
938
*/
939
static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
940
uint32_t val)
941
{
942
val = cpu_to_fdt32(val);
943
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
944
}
945
946
/**
947
* fdt_setprop_string - set a property to a string value
948
* @fdt: pointer to the device tree blob
949
* @nodeoffset: offset of the node whose property to change
950
* @name: name of the property to change
951
* @str: string value for the property
952
*
953
* fdt_setprop_string() sets the value of the named property in the
954
* given node to the given string value (using the length of the
955
* string to determine the new length of the property), or creates a
956
* new property with that value if it does not already exist.
957
*
958
* This function may insert or delete data from the blob, and will
959
* therefore change the offsets of some existing nodes.
960
*
961
* returns:
962
* 0, on success
963
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
964
* contain the new property value
965
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
966
* -FDT_ERR_BADLAYOUT,
967
* -FDT_ERR_BADMAGIC,
968
* -FDT_ERR_BADVERSION,
969
* -FDT_ERR_BADSTATE,
970
* -FDT_ERR_BADSTRUCTURE,
971
* -FDT_ERR_BADLAYOUT,
972
* -FDT_ERR_TRUNCATED, standard meanings
973
*/
974
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
975
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
976
977
/**
978
* fdt_delprop - delete a property
979
* @fdt: pointer to the device tree blob
980
* @nodeoffset: offset of the node whose property to nop
981
* @name: name of the property to nop
982
*
983
* fdt_del_property() will delete the given property.
984
*
985
* This function will delete data from the blob, and will therefore
986
* change the offsets of some existing nodes.
987
*
988
* returns:
989
* 0, on success
990
* -FDT_ERR_NOTFOUND, node does not have the named property
991
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
992
* -FDT_ERR_BADLAYOUT,
993
* -FDT_ERR_BADMAGIC,
994
* -FDT_ERR_BADVERSION,
995
* -FDT_ERR_BADSTATE,
996
* -FDT_ERR_BADSTRUCTURE,
997
* -FDT_ERR_TRUNCATED, standard meanings
998
*/
999
int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1000
1001
/**
1002
* fdt_add_subnode_namelen - creates a new node based on substring
1003
* @fdt: pointer to the device tree blob
1004
* @parentoffset: structure block offset of a node
1005
* @name: name of the subnode to locate
1006
* @namelen: number of characters of name to consider
1007
*
1008
* Identical to fdt_add_subnode(), but use only the first namelen
1009
* characters of name as the name of the new node. This is useful for
1010
* creating subnodes based on a portion of a larger string, such as a
1011
* full path.
1012
*/
1013
int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1014
const char *name, int namelen);
1015
1016
/**
1017
* fdt_add_subnode - creates a new node
1018
* @fdt: pointer to the device tree blob
1019
* @parentoffset: structure block offset of a node
1020
* @name: name of the subnode to locate
1021
*
1022
* fdt_add_subnode() creates a new node as a subnode of the node at
1023
* structure block offset parentoffset, with the given name (which
1024
* should include the unit address, if any).
1025
*
1026
* This function will insert data into the blob, and will therefore
1027
* change the offsets of some existing nodes.
1028
1029
* returns:
1030
* structure block offset of the created nodeequested subnode (>=0), on success
1031
* -FDT_ERR_NOTFOUND, if the requested subnode does not exist
1032
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
1033
* -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1034
* the given name
1035
* -FDT_ERR_NOSPACE, if there is insufficient free space in the
1036
* blob to contain the new node
1037
* -FDT_ERR_NOSPACE
1038
* -FDT_ERR_BADLAYOUT
1039
* -FDT_ERR_BADMAGIC,
1040
* -FDT_ERR_BADVERSION,
1041
* -FDT_ERR_BADSTATE,
1042
* -FDT_ERR_BADSTRUCTURE,
1043
* -FDT_ERR_TRUNCATED, standard meanings.
1044
*/
1045
int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1046
1047
/**
1048
* fdt_del_node - delete a node (subtree)
1049
* @fdt: pointer to the device tree blob
1050
* @nodeoffset: offset of the node to nop
1051
*
1052
* fdt_del_node() will remove the given node, including all its
1053
* subnodes if any, from the blob.
1054
*
1055
* This function will delete data from the blob, and will therefore
1056
* change the offsets of some existing nodes.
1057
*
1058
* returns:
1059
* 0, on success
1060
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1061
* -FDT_ERR_BADLAYOUT,
1062
* -FDT_ERR_BADMAGIC,
1063
* -FDT_ERR_BADVERSION,
1064
* -FDT_ERR_BADSTATE,
1065
* -FDT_ERR_BADSTRUCTURE,
1066
* -FDT_ERR_TRUNCATED, standard meanings
1067
*/
1068
int fdt_del_node(void *fdt, int nodeoffset);
1069
1070
/**********************************************************************/
1071
/* Debugging / informational functions */
1072
/**********************************************************************/
1073
1074
const char *fdt_strerror(int errval);
1075
1076
#endif /* _LIBFDT_H */
1077
1078