RTEMS  5.1
libfdt.h
1 /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
2 #ifndef LIBFDT_H
3 #define LIBFDT_H
4 /*
5  * libfdt - Flat Device Tree manipulation
6  * Copyright (C) 2006 David Gibson, IBM Corporation.
7  */
8 
9 #include <libfdt_env.h>
10 #include <fdt.h>
11 
12 #define FDT_FIRST_SUPPORTED_VERSION 0x02
13 #define FDT_LAST_SUPPORTED_VERSION 0x11
14 
15 /* Error codes: informative error codes */
16 #define FDT_ERR_NOTFOUND 1
17  /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
18 #define FDT_ERR_EXISTS 2
19  /* FDT_ERR_EXISTS: Attempted to create a node or property which
20  * already exists */
21 #define FDT_ERR_NOSPACE 3
22  /* FDT_ERR_NOSPACE: Operation needed to expand the device
23  * tree, but its buffer did not have sufficient space to
24  * contain the expanded tree. Use fdt_open_into() to move the
25  * device tree to a buffer with more space. */
26 
27 /* Error codes: codes for bad parameters */
28 #define FDT_ERR_BADOFFSET 4
29  /* FDT_ERR_BADOFFSET: Function was passed a structure block
30  * offset which is out-of-bounds, or which points to an
31  * unsuitable part of the structure for the operation. */
32 #define FDT_ERR_BADPATH 5
33  /* FDT_ERR_BADPATH: Function was passed a badly formatted path
34  * (e.g. missing a leading / for a function which requires an
35  * absolute path) */
36 #define FDT_ERR_BADPHANDLE 6
37  /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
38  * This can be caused either by an invalid phandle property
39  * length, or the phandle value was either 0 or -1, which are
40  * not permitted. */
41 #define FDT_ERR_BADSTATE 7
42  /* FDT_ERR_BADSTATE: Function was passed an incomplete device
43  * tree created by the sequential-write functions, which is
44  * not sufficiently complete for the requested operation. */
45 
46 /* Error codes: codes for bad device tree blobs */
47 #define FDT_ERR_TRUNCATED 8
48  /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
49  * terminated (overflows, goes outside allowed bounds, or
50  * isn't properly terminated). */
51 #define FDT_ERR_BADMAGIC 9
52  /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
53  * device tree at all - it is missing the flattened device
54  * tree magic number. */
55 #define FDT_ERR_BADVERSION 10
56  /* FDT_ERR_BADVERSION: Given device tree has a version which
57  * can't be handled by the requested operation. For
58  * read-write functions, this may mean that fdt_open_into() is
59  * required to convert the tree to the expected version. */
60 #define FDT_ERR_BADSTRUCTURE 11
61  /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
62  * structure block or other serious error (e.g. misnested
63  * nodes, or subnodes preceding properties). */
64 #define FDT_ERR_BADLAYOUT 12
65  /* FDT_ERR_BADLAYOUT: For read-write functions, the given
66  * device tree has it's sub-blocks in an order that the
67  * function can't handle (memory reserve map, then structure,
68  * then strings). Use fdt_open_into() to reorganize the tree
69  * into a form suitable for the read-write operations. */
70 
71 /* "Can't happen" error indicating a bug in libfdt */
72 #define FDT_ERR_INTERNAL 13
73  /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
74  * Should never be returned, if it is, it indicates a bug in
75  * libfdt itself. */
76 
77 /* Errors in device tree content */
78 #define FDT_ERR_BADNCELLS 14
79  /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
80  * or similar property with a bad format or value */
81 
82 #define FDT_ERR_BADVALUE 15
83  /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
84  * value. For example: a property expected to contain a string list
85  * is not NUL-terminated within the length of its value. */
86 
87 #define FDT_ERR_BADOVERLAY 16
88  /* FDT_ERR_BADOVERLAY: The device tree overlay, while
89  * correctly structured, cannot be applied due to some
90  * unexpected or missing value, property or node. */
91 
92 #define FDT_ERR_NOPHANDLES 17
93  /* FDT_ERR_NOPHANDLES: The device tree doesn't have any
94  * phandle available anymore without causing an overflow */
95 
96 #define FDT_ERR_BADFLAGS 18
97  /* FDT_ERR_BADFLAGS: The function was passed a flags field that
98  * contains invalid flags or an invalid combination of flags. */
99 
100 #define FDT_ERR_MAX 18
101 
102 /* constants */
103 #define FDT_MAX_PHANDLE 0xfffffffe
104  /* Valid values for phandles range from 1 to 2^32-2. */
105 
106 /**********************************************************************/
107 /* Low-level functions (you probably don't need these) */
108 /**********************************************************************/
109 
110 #ifndef SWIG /* This function is not useful in Python */
111 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
112 #endif
113 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
114 {
115  return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
116 }
117 
118 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
119 
120 /*
121  * Alignment helpers:
122  * These helpers access words from a device tree blob. They're
123  * built to work even with unaligned pointers on platforms (ike
124  * ARM) that don't like unaligned loads and stores
125  */
126 
127 static inline uint32_t fdt32_ld(const fdt32_t *p)
128 {
129  const uint8_t *bp = (const uint8_t *)p;
130 
131  return ((uint32_t)bp[0] << 24)
132  | ((uint32_t)bp[1] << 16)
133  | ((uint32_t)bp[2] << 8)
134  | bp[3];
135 }
136 
137 static inline void fdt32_st(void *property, uint32_t value)
138 {
139  uint8_t *bp = (uint8_t *)property;
140 
141  bp[0] = value >> 24;
142  bp[1] = (value >> 16) & 0xff;
143  bp[2] = (value >> 8) & 0xff;
144  bp[3] = value & 0xff;
145 }
146 
147 static inline uint64_t fdt64_ld(const fdt64_t *p)
148 {
149  const uint8_t *bp = (const uint8_t *)p;
150 
151  return ((uint64_t)bp[0] << 56)
152  | ((uint64_t)bp[1] << 48)
153  | ((uint64_t)bp[2] << 40)
154  | ((uint64_t)bp[3] << 32)
155  | ((uint64_t)bp[4] << 24)
156  | ((uint64_t)bp[5] << 16)
157  | ((uint64_t)bp[6] << 8)
158  | bp[7];
159 }
160 
161 static inline void fdt64_st(void *property, uint64_t value)
162 {
163  uint8_t *bp = (uint8_t *)property;
164 
165  bp[0] = value >> 56;
166  bp[1] = (value >> 48) & 0xff;
167  bp[2] = (value >> 40) & 0xff;
168  bp[3] = (value >> 32) & 0xff;
169  bp[4] = (value >> 24) & 0xff;
170  bp[5] = (value >> 16) & 0xff;
171  bp[6] = (value >> 8) & 0xff;
172  bp[7] = value & 0xff;
173 }
174 
175 /**********************************************************************/
176 /* Traversal functions */
177 /**********************************************************************/
178 
179 int fdt_next_node(const void *fdt, int offset, int *depth);
180 
188 int fdt_first_subnode(const void *fdt, int offset);
189 
201 int fdt_next_subnode(const void *fdt, int offset);
202 
226 #define fdt_for_each_subnode(node, fdt, parent) \
227  for (node = fdt_first_subnode(fdt, parent); \
228  node >= 0; \
229  node = fdt_next_subnode(fdt, node))
230 
231 /**********************************************************************/
232 /* General functions */
233 /**********************************************************************/
234 #define fdt_get_header(fdt, field) \
235  (fdt32_ld(&((const struct fdt_header *)(fdt))->field))
236 #define fdt_magic(fdt) (fdt_get_header(fdt, magic))
237 #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
238 #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
239 #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
240 #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
241 #define fdt_version(fdt) (fdt_get_header(fdt, version))
242 #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
243 #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
244 #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
245 #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
246 
247 #define fdt_set_hdr_(name) \
248  static inline void fdt_set_##name(void *fdt, uint32_t val) \
249  { \
250  struct fdt_header *fdth = (struct fdt_header *)fdt; \
251  fdth->name = cpu_to_fdt32(val); \
252  }
253 fdt_set_hdr_(magic);
254 fdt_set_hdr_(totalsize);
255 fdt_set_hdr_(off_dt_struct);
256 fdt_set_hdr_(off_dt_strings);
257 fdt_set_hdr_(off_mem_rsvmap);
258 fdt_set_hdr_(version);
259 fdt_set_hdr_(last_comp_version);
260 fdt_set_hdr_(boot_cpuid_phys);
261 fdt_set_hdr_(size_dt_strings);
262 fdt_set_hdr_(size_dt_struct);
263 #undef fdt_set_hdr_
264 
269 size_t fdt_header_size(const void *fdt);
270 
274 size_t fdt_header_size_(uint32_t version);
275 
293 int fdt_check_header(const void *fdt);
294 
314 int fdt_move(const void *fdt, void *buf, int bufsize);
315 
316 /**********************************************************************/
317 /* Read-only functions */
318 /**********************************************************************/
319 
320 int fdt_check_full(const void *fdt, size_t bufsize);
321 
336 const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
337 
350 const char *fdt_string(const void *fdt, int stroffset);
351 
364 int fdt_find_max_phandle(const void *fdt, uint32_t *phandle);
365 
381 static inline uint32_t fdt_get_max_phandle(const void *fdt)
382 {
383  uint32_t phandle;
384  int err;
385 
386  err = fdt_find_max_phandle(fdt, &phandle);
387  if (err < 0)
388  return (uint32_t)-1;
389 
390  return phandle;
391 }
392 
406 int fdt_generate_phandle(const void *fdt, uint32_t *phandle);
407 
419 int fdt_num_mem_rsv(const void *fdt);
420 
436 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
437 
450 #ifndef SWIG /* Not available in Python */
451 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
452  const char *name, int namelen);
453 #endif
454 
478 int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
479 
489 #ifndef SWIG /* Not available in Python */
490 int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
491 #endif
492 
516 int fdt_path_offset(const void *fdt, const char *path);
517 
541 const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
542 
561 int fdt_first_property_offset(const void *fdt, int nodeoffset);
562 
582 int fdt_next_property_offset(const void *fdt, int offset);
583 
606 #define fdt_for_each_property_offset(property, fdt, node) \
607  for (property = fdt_first_property_offset(fdt, node); \
608  property >= 0; \
609  property = fdt_next_property_offset(fdt, property))
610 
638 const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
639  int offset,
640  int *lenp);
641 
653 #ifndef SWIG /* Not available in Python */
654 const struct fdt_property *fdt_get_property_namelen(const void *fdt,
655  int nodeoffset,
656  const char *name,
657  int namelen, int *lenp);
658 #endif
659 
688 const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
689  const char *name, int *lenp);
690 static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
691  const char *name,
692  int *lenp)
693 {
694  return (struct fdt_property *)(uintptr_t)
695  fdt_get_property(fdt, nodeoffset, name, lenp);
696 }
697 
729 #ifndef SWIG /* This function is not useful in Python */
730 const void *fdt_getprop_by_offset(const void *fdt, int offset,
731  const char **namep, int *lenp);
732 #endif
733 
745 #ifndef SWIG /* Not available in Python */
746 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
747  const char *name, int namelen, int *lenp);
748 static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
749  const char *name, int namelen,
750  int *lenp)
751 {
752  return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
753  namelen, lenp);
754 }
755 #endif
756 
785 const void *fdt_getprop(const void *fdt, int nodeoffset,
786  const char *name, int *lenp);
787 static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
788  const char *name, int *lenp)
789 {
790  return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
791 }
792 
805 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
806 
816 #ifndef SWIG /* Not available in Python */
817 const char *fdt_get_alias_namelen(const void *fdt,
818  const char *name, int namelen);
819 #endif
820 
833 const char *fdt_get_alias(const void *fdt, const char *name);
834 
860 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
861 
892 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
893  int supernodedepth, int *nodedepth);
894 
914 int fdt_node_depth(const void *fdt, int nodeoffset);
915 
937 int fdt_parent_offset(const void *fdt, int nodeoffset);
938 
977 int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
978  const char *propname,
979  const void *propval, int proplen);
980 
1000 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
1001 
1024 int fdt_node_check_compatible(const void *fdt, int nodeoffset,
1025  const char *compatible);
1026 
1061 int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
1062  const char *compatible);
1063 
1076 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
1077 
1088 int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
1089 
1109 int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
1110  const char *string);
1111 
1136 const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
1137  const char *property, int index,
1138  int *lenp);
1139 
1140 /**********************************************************************/
1141 /* Read-only functions (addressing related) */
1142 /**********************************************************************/
1143 
1153 #define FDT_MAX_NCELLS 4
1154 
1173 int fdt_address_cells(const void *fdt, int nodeoffset);
1174 
1194 int fdt_size_cells(const void *fdt, int nodeoffset);
1195 
1196 
1197 /**********************************************************************/
1198 /* Write-in-place functions */
1199 /**********************************************************************/
1200 
1217 #ifndef SWIG /* Not available in Python */
1218 int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
1219  const char *name, int namelen,
1220  uint32_t idx, const void *val,
1221  int len);
1222 #endif
1223 
1252 #ifndef SWIG /* Not available in Python */
1253 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
1254  const void *val, int len);
1255 #endif
1256 
1285 static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
1286  const char *name, uint32_t val)
1287 {
1288  fdt32_t tmp = cpu_to_fdt32(val);
1289  return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1290 }
1291 
1320 static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
1321  const char *name, uint64_t val)
1322 {
1323  fdt64_t tmp = cpu_to_fdt64(val);
1324  return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1325 }
1326 
1332 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
1333  const char *name, uint32_t val)
1334 {
1335  return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
1336 }
1337 
1362 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
1363 
1386 int fdt_nop_node(void *fdt, int nodeoffset);
1387 
1388 /**********************************************************************/
1389 /* Sequential write functions */
1390 /**********************************************************************/
1391 
1392 /* fdt_create_with_flags flags */
1393 #define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1
1394  /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property
1395  * names in the fdt. This can result in faster creation times, but
1396  * a larger fdt. */
1397 
1398 #define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP)
1399 
1416 int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags);
1417 
1429 int fdt_create(void *buf, int bufsize);
1430 
1431 int fdt_resize(void *fdt, void *buf, int bufsize);
1432 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1433 int fdt_finish_reservemap(void *fdt);
1434 int fdt_begin_node(void *fdt, const char *name);
1435 int fdt_property(void *fdt, const char *name, const void *val, int len);
1436 static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
1437 {
1438  fdt32_t tmp = cpu_to_fdt32(val);
1439  return fdt_property(fdt, name, &tmp, sizeof(tmp));
1440 }
1441 static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1442 {
1443  fdt64_t tmp = cpu_to_fdt64(val);
1444  return fdt_property(fdt, name, &tmp, sizeof(tmp));
1445 }
1446 
1447 #ifndef SWIG /* Not available in Python */
1448 static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1449 {
1450  return fdt_property_u32(fdt, name, val);
1451 }
1452 #endif
1453 
1467 int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1468 
1469 #define fdt_property_string(fdt, name, str) \
1470  fdt_property(fdt, name, str, strlen(str)+1)
1471 int fdt_end_node(void *fdt);
1472 int fdt_finish(void *fdt);
1473 
1474 /**********************************************************************/
1475 /* Read-write functions */
1476 /**********************************************************************/
1477 
1478 int fdt_create_empty_tree(void *buf, int bufsize);
1479 int fdt_open_into(const void *fdt, void *buf, int bufsize);
1480 int fdt_pack(void *fdt);
1481 
1504 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1505 
1528 int fdt_del_mem_rsv(void *fdt, int n);
1529 
1554 int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1555 
1584 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1585  const void *val, int len);
1586 
1615 int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1616  int len, void **prop_data);
1617 
1646 static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
1647  uint32_t val)
1648 {
1649  fdt32_t tmp = cpu_to_fdt32(val);
1650  return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1651 }
1652 
1681 static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1682  uint64_t val)
1683 {
1684  fdt64_t tmp = cpu_to_fdt64(val);
1685  return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1686 }
1687 
1693 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1694  uint32_t val)
1695 {
1696  return fdt_setprop_u32(fdt, nodeoffset, name, val);
1697 }
1698 
1727 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
1728  fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1729 
1730 
1757 #define fdt_setprop_empty(fdt, nodeoffset, name) \
1758  fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
1759 
1787 int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1788  const void *val, int len);
1789 
1818 static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1819  const char *name, uint32_t val)
1820 {
1821  fdt32_t tmp = cpu_to_fdt32(val);
1822  return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1823 }
1824 
1853 static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1854  const char *name, uint64_t val)
1855 {
1856  fdt64_t tmp = cpu_to_fdt64(val);
1857  return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1858 }
1859 
1865 static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1866  const char *name, uint32_t val)
1867 {
1868  return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1869 }
1870 
1898 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1899  fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1900 
1935 int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
1936  const char *name, uint64_t addr, uint64_t size);
1937 
1960 int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1961 
1974 #ifndef SWIG /* Not available in Python */
1975 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1976  const char *name, int namelen);
1977 #endif
1978 
2010 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
2011 
2033 int fdt_del_node(void *fdt, int nodeoffset);
2034 
2064 int fdt_overlay_apply(void *fdt, void *fdto);
2065 
2066 /**********************************************************************/
2067 /* Debugging / informational functions */
2068 /**********************************************************************/
2069 
2070 const char *fdt_strerror(int errval);
2071 
2072 #endif /* LIBFDT_H */
unsigned p
Definition: tte.h:90
Definition: fdt.h:41
unsigned size
Definition: tte.h:74