RTEMS  5.0.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
libfdt.h
1 #ifndef LIBFDT_H
2 #define LIBFDT_H
3 /*
4  * libfdt - Flat Device Tree manipulation
5  * Copyright (C) 2006 David Gibson, IBM Corporation.
6  *
7  * libfdt is dual licensed: you can use it either under the terms of
8  * the GPL, or the BSD license, at your option.
9  *
10  * a) This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of the
13  * License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
23  * MA 02110-1301 USA
24  *
25  * Alternatively,
26  *
27  * b) Redistribution and use in source and binary forms, with or
28  * without modification, are permitted provided that the following
29  * conditions are met:
30  *
31  * 1. Redistributions of source code must retain the above
32  * copyright notice, this list of conditions and the following
33  * disclaimer.
34  * 2. Redistributions in binary form must reproduce the above
35  * copyright notice, this list of conditions and the following
36  * disclaimer in the documentation and/or other materials
37  * provided with the distribution.
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
40  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
41  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
50  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52  */
53 
54 #include <libfdt_env.h>
55 #include <fdt.h>
56 
57 #define FDT_FIRST_SUPPORTED_VERSION 0x02
58 #define FDT_LAST_SUPPORTED_VERSION 0x11
59 
60 /* Error codes: informative error codes */
61 #define FDT_ERR_NOTFOUND 1
62  /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
63 #define FDT_ERR_EXISTS 2
64  /* FDT_ERR_EXISTS: Attempted to create a node or property which
65  * already exists */
66 #define FDT_ERR_NOSPACE 3
67  /* FDT_ERR_NOSPACE: Operation needed to expand the device
68  * tree, but its buffer did not have sufficient space to
69  * contain the expanded tree. Use fdt_open_into() to move the
70  * device tree to a buffer with more space. */
71 
72 /* Error codes: codes for bad parameters */
73 #define FDT_ERR_BADOFFSET 4
74  /* FDT_ERR_BADOFFSET: Function was passed a structure block
75  * offset which is out-of-bounds, or which points to an
76  * unsuitable part of the structure for the operation. */
77 #define FDT_ERR_BADPATH 5
78  /* FDT_ERR_BADPATH: Function was passed a badly formatted path
79  * (e.g. missing a leading / for a function which requires an
80  * absolute path) */
81 #define FDT_ERR_BADPHANDLE 6
82  /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
83  * This can be caused either by an invalid phandle property
84  * length, or the phandle value was either 0 or -1, which are
85  * not permitted. */
86 #define FDT_ERR_BADSTATE 7
87  /* FDT_ERR_BADSTATE: Function was passed an incomplete device
88  * tree created by the sequential-write functions, which is
89  * not sufficiently complete for the requested operation. */
90 
91 /* Error codes: codes for bad device tree blobs */
92 #define FDT_ERR_TRUNCATED 8
93  /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
94  * terminated (overflows, goes outside allowed bounds, or
95  * isn't properly terminated). */
96 #define FDT_ERR_BADMAGIC 9
97  /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
98  * device tree at all - it is missing the flattened device
99  * tree magic number. */
100 #define FDT_ERR_BADVERSION 10
101  /* FDT_ERR_BADVERSION: Given device tree has a version which
102  * can't be handled by the requested operation. For
103  * read-write functions, this may mean that fdt_open_into() is
104  * required to convert the tree to the expected version. */
105 #define FDT_ERR_BADSTRUCTURE 11
106  /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
107  * structure block or other serious error (e.g. misnested
108  * nodes, or subnodes preceding properties). */
109 #define FDT_ERR_BADLAYOUT 12
110  /* FDT_ERR_BADLAYOUT: For read-write functions, the given
111  * device tree has it's sub-blocks in an order that the
112  * function can't handle (memory reserve map, then structure,
113  * then strings). Use fdt_open_into() to reorganize the tree
114  * into a form suitable for the read-write operations. */
115 
116 /* "Can't happen" error indicating a bug in libfdt */
117 #define FDT_ERR_INTERNAL 13
118  /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
119  * Should never be returned, if it is, it indicates a bug in
120  * libfdt itself. */
121 
122 /* Errors in device tree content */
123 #define FDT_ERR_BADNCELLS 14
124  /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
125  * or similar property with a bad format or value */
126 
127 #define FDT_ERR_BADVALUE 15
128  /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
129  * value. For example: a property expected to contain a string list
130  * is not NUL-terminated within the length of its value. */
131 
132 #define FDT_ERR_BADOVERLAY 16
133  /* FDT_ERR_BADOVERLAY: The device tree overlay, while
134  * correctly structured, cannot be applied due to some
135  * unexpected or missing value, property or node. */
136 
137 #define FDT_ERR_NOPHANDLES 17
138  /* FDT_ERR_NOPHANDLES: The device tree doesn't have any
139  * phandle available anymore without causing an overflow */
140 
141 #define FDT_ERR_MAX 17
142 
143 /**********************************************************************/
144 /* Low-level functions (you probably don't need these) */
145 /**********************************************************************/
146 
147 #ifndef SWIG /* This function is not useful in Python */
148 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
149 #endif
150 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
151 {
152  return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
153 }
154 
155 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
156 
157 /*
158  * Alignment helpers:
159  * These helpers access words from a device tree blob. They're
160  * built to work even with unaligned pointers on platforms (ike
161  * ARM) that don't like unaligned loads and stores
162  */
163 
164 static inline uint32_t fdt32_ld(const fdt32_t *p)
165 {
166  fdt32_t v;
167 
168  memcpy(&v, p, sizeof(v));
169  return fdt32_to_cpu(v);
170 }
171 
172 static inline uint64_t fdt64_ld(const fdt64_t *p)
173 {
174  fdt64_t v;
175 
176  memcpy(&v, p, sizeof(v));
177  return fdt64_to_cpu(v);
178 }
179 
180 /**********************************************************************/
181 /* Traversal functions */
182 /**********************************************************************/
183 
184 int fdt_next_node(const void *fdt, int offset, int *depth);
185 
193 int fdt_first_subnode(const void *fdt, int offset);
194 
206 int fdt_next_subnode(const void *fdt, int offset);
207 
231 #define fdt_for_each_subnode(node, fdt, parent) \
232  for (node = fdt_first_subnode(fdt, parent); \
233  node >= 0; \
234  node = fdt_next_subnode(fdt, node))
235 
236 /**********************************************************************/
237 /* General functions */
238 /**********************************************************************/
239 #define fdt_get_header(fdt, field) \
240  (fdt32_ld(&((const struct fdt_header *)(fdt))->field))
241 #define fdt_magic(fdt) (fdt_get_header(fdt, magic))
242 #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
243 #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
244 #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
245 #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
246 #define fdt_version(fdt) (fdt_get_header(fdt, version))
247 #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
248 #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
249 #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
250 #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
251 
252 #define fdt_set_hdr_(name) \
253  static inline void fdt_set_##name(void *fdt, uint32_t val) \
254  { \
255  struct fdt_header *fdth = (struct fdt_header *)fdt; \
256  fdth->name = cpu_to_fdt32(val); \
257  }
258 fdt_set_hdr_(magic);
259 fdt_set_hdr_(totalsize);
260 fdt_set_hdr_(off_dt_struct);
261 fdt_set_hdr_(off_dt_strings);
262 fdt_set_hdr_(off_mem_rsvmap);
263 fdt_set_hdr_(version);
264 fdt_set_hdr_(last_comp_version);
265 fdt_set_hdr_(boot_cpuid_phys);
266 fdt_set_hdr_(size_dt_strings);
267 fdt_set_hdr_(size_dt_struct);
268 #undef fdt_set_hdr_
269 
274 size_t fdt_header_size_(uint32_t version);
275 static inline size_t fdt_header_size(const void *fdt)
276 {
277  return fdt_header_size_(fdt_version(fdt));
278 }
279 
297 int fdt_check_header(const void *fdt);
298 
318 int fdt_move(const void *fdt, void *buf, int bufsize);
319 
320 /**********************************************************************/
321 /* Read-only functions */
322 /**********************************************************************/
323 
324 int fdt_check_full(const void *fdt, size_t bufsize);
325 
340 const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
341 
354 const char *fdt_string(const void *fdt, int stroffset);
355 
369 uint32_t fdt_get_max_phandle(const void *fdt);
370 
382 int fdt_num_mem_rsv(const void *fdt);
383 
399 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
400 
413 #ifndef SWIG /* Not available in Python */
414 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
415  const char *name, int namelen);
416 #endif
417 
441 int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
442 
452 #ifndef SWIG /* Not available in Python */
453 int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
454 #endif
455 
479 int fdt_path_offset(const void *fdt, const char *path);
480 
504 const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
505 
524 int fdt_first_property_offset(const void *fdt, int nodeoffset);
525 
545 int fdt_next_property_offset(const void *fdt, int offset);
546 
569 #define fdt_for_each_property_offset(property, fdt, node) \
570  for (property = fdt_first_property_offset(fdt, node); \
571  property >= 0; \
572  property = fdt_next_property_offset(fdt, property))
573 
601 const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
602  int offset,
603  int *lenp);
604 
616 #ifndef SWIG /* Not available in Python */
617 const struct fdt_property *fdt_get_property_namelen(const void *fdt,
618  int nodeoffset,
619  const char *name,
620  int namelen, int *lenp);
621 #endif
622 
651 const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
652  const char *name, int *lenp);
653 static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
654  const char *name,
655  int *lenp)
656 {
657  return (struct fdt_property *)(uintptr_t)
658  fdt_get_property(fdt, nodeoffset, name, lenp);
659 }
660 
692 #ifndef SWIG /* This function is not useful in Python */
693 const void *fdt_getprop_by_offset(const void *fdt, int offset,
694  const char **namep, int *lenp);
695 #endif
696 
708 #ifndef SWIG /* Not available in Python */
709 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
710  const char *name, int namelen, int *lenp);
711 static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
712  const char *name, int namelen,
713  int *lenp)
714 {
715  return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
716  namelen, lenp);
717 }
718 #endif
719 
748 const void *fdt_getprop(const void *fdt, int nodeoffset,
749  const char *name, int *lenp);
750 static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
751  const char *name, int *lenp)
752 {
753  return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
754 }
755 
768 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
769 
779 #ifndef SWIG /* Not available in Python */
780 const char *fdt_get_alias_namelen(const void *fdt,
781  const char *name, int namelen);
782 #endif
783 
796 const char *fdt_get_alias(const void *fdt, const char *name);
797 
823 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
824 
855 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
856  int supernodedepth, int *nodedepth);
857 
877 int fdt_node_depth(const void *fdt, int nodeoffset);
878 
900 int fdt_parent_offset(const void *fdt, int nodeoffset);
901 
940 int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
941  const char *propname,
942  const void *propval, int proplen);
943 
963 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
964 
987 int fdt_node_check_compatible(const void *fdt, int nodeoffset,
988  const char *compatible);
989 
1024 int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
1025  const char *compatible);
1026 
1039 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
1040 
1051 int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
1052 
1072 int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
1073  const char *string);
1074 
1099 const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
1100  const char *property, int index,
1101  int *lenp);
1102 
1103 /**********************************************************************/
1104 /* Read-only functions (addressing related) */
1105 /**********************************************************************/
1106 
1116 #define FDT_MAX_NCELLS 4
1117 
1136 int fdt_address_cells(const void *fdt, int nodeoffset);
1137 
1157 int fdt_size_cells(const void *fdt, int nodeoffset);
1158 
1159 
1160 /**********************************************************************/
1161 /* Write-in-place functions */
1162 /**********************************************************************/
1163 
1180 #ifndef SWIG /* Not available in Python */
1181 int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
1182  const char *name, int namelen,
1183  uint32_t idx, const void *val,
1184  int len);
1185 #endif
1186 
1215 #ifndef SWIG /* Not available in Python */
1216 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
1217  const void *val, int len);
1218 #endif
1219 
1248 static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
1249  const char *name, uint32_t val)
1250 {
1251  fdt32_t tmp = cpu_to_fdt32(val);
1252  return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1253 }
1254 
1283 static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
1284  const char *name, uint64_t val)
1285 {
1286  fdt64_t tmp = cpu_to_fdt64(val);
1287  return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1288 }
1289 
1295 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
1296  const char *name, uint32_t val)
1297 {
1298  return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
1299 }
1300 
1325 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
1326 
1349 int fdt_nop_node(void *fdt, int nodeoffset);
1350 
1351 /**********************************************************************/
1352 /* Sequential write functions */
1353 /**********************************************************************/
1354 
1355 int fdt_create(void *buf, int bufsize);
1356 int fdt_resize(void *fdt, void *buf, int bufsize);
1357 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1358 int fdt_finish_reservemap(void *fdt);
1359 int fdt_begin_node(void *fdt, const char *name);
1360 int fdt_property(void *fdt, const char *name, const void *val, int len);
1361 static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
1362 {
1363  fdt32_t tmp = cpu_to_fdt32(val);
1364  return fdt_property(fdt, name, &tmp, sizeof(tmp));
1365 }
1366 static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1367 {
1368  fdt64_t tmp = cpu_to_fdt64(val);
1369  return fdt_property(fdt, name, &tmp, sizeof(tmp));
1370 }
1371 
1372 #ifndef SWIG /* Not available in Python */
1373 static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1374 {
1375  return fdt_property_u32(fdt, name, val);
1376 }
1377 #endif
1378 
1392 int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1393 
1394 #define fdt_property_string(fdt, name, str) \
1395  fdt_property(fdt, name, str, strlen(str)+1)
1396 int fdt_end_node(void *fdt);
1397 int fdt_finish(void *fdt);
1398 
1399 /**********************************************************************/
1400 /* Read-write functions */
1401 /**********************************************************************/
1402 
1403 int fdt_create_empty_tree(void *buf, int bufsize);
1404 int fdt_open_into(const void *fdt, void *buf, int bufsize);
1405 int fdt_pack(void *fdt);
1406 
1429 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1430 
1453 int fdt_del_mem_rsv(void *fdt, int n);
1454 
1479 int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1480 
1509 int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1510  const void *val, int len);
1511 
1540 int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1541  int len, void **prop_data);
1542 
1571 static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
1572  uint32_t val)
1573 {
1574  fdt32_t tmp = cpu_to_fdt32(val);
1575  return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1576 }
1577 
1606 static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1607  uint64_t val)
1608 {
1609  fdt64_t tmp = cpu_to_fdt64(val);
1610  return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1611 }
1612 
1618 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1619  uint32_t val)
1620 {
1621  return fdt_setprop_u32(fdt, nodeoffset, name, val);
1622 }
1623 
1652 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
1653  fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1654 
1655 
1682 #define fdt_setprop_empty(fdt, nodeoffset, name) \
1683  fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
1684 
1712 int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1713  const void *val, int len);
1714 
1743 static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1744  const char *name, uint32_t val)
1745 {
1746  fdt32_t tmp = cpu_to_fdt32(val);
1747  return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1748 }
1749 
1778 static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1779  const char *name, uint64_t val)
1780 {
1781  fdt64_t tmp = cpu_to_fdt64(val);
1782  return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1783 }
1784 
1790 static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1791  const char *name, uint32_t val)
1792 {
1793  return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1794 }
1795 
1823 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1824  fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1825 
1848 int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1849 
1862 #ifndef SWIG /* Not available in Python */
1863 int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1864  const char *name, int namelen);
1865 #endif
1866 
1898 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1899 
1921 int fdt_del_node(void *fdt, int nodeoffset);
1922 
1952 int fdt_overlay_apply(void *fdt, void *fdto);
1953 
1954 /**********************************************************************/
1955 /* Debugging / informational functions */
1956 /**********************************************************************/
1957 
1958 const char *fdt_strerror(int errval);
1959 
1960 #endif /* LIBFDT_H */
unsigned p
Definition: tte.h:90
Definition: fdt.h:86
unsigned size
Definition: tte.h:74
unsigned v
Definition: tte.h:73