RTEMS: cpukit/include/libfdt.h Source File

| RTEMS 5.4-rc2

Loading...
Searching...
No Matches
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 */
111const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
112#endif
113static 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
118uint32_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
127static 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
137static 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
147static 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
161static 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
179int fdt_next_node(const void *fdt, int offset, int *depth);
180
188int fdt_first_subnode(const void *fdt, int offset);
189
201int 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 }
253fdt_set_hdr_(magic);
254fdt_set_hdr_(totalsize);
255fdt_set_hdr_(off_dt_struct);
256fdt_set_hdr_(off_dt_strings);
257fdt_set_hdr_(off_mem_rsvmap);
258fdt_set_hdr_(version);
259fdt_set_hdr_(last_comp_version);
260fdt_set_hdr_(boot_cpuid_phys);
261fdt_set_hdr_(size_dt_strings);
262fdt_set_hdr_(size_dt_struct);
263#undef fdt_set_hdr_
264
269size_t fdt_header_size(const void *fdt);
270
274size_t fdt_header_size_(uint32_t version);
275
293int fdt_check_header(const void *fdt);
294
314int fdt_move(const void *fdt, void *buf, int bufsize);
315
316/**********************************************************************/
317/* Read-only functions */
318/**********************************************************************/
319
320int fdt_check_full(const void *fdt, size_t bufsize);
321
336const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
337
350const char *fdt_string(const void *fdt, int stroffset);
351
364int fdt_find_max_phandle(const void *fdt, uint32_t *phandle);
365
381static 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
406int fdt_generate_phandle(const void *fdt, uint32_t *phandle);
407
419int fdt_num_mem_rsv(const void *fdt);
420
436int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
437
450#ifndef SWIG /* Not available in Python */
451int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
452 const char *name, int namelen);
453#endif
478int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
479
489#ifndef SWIG /* Not available in Python */
490int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
491#endif
492
516int fdt_path_offset(const void *fdt, const char *path);
517
541const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
542
561int fdt_first_property_offset(const void *fdt, int nodeoffset);
562
582int 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
638const 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 */
654const 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
688const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
689 const char *name, int *lenp);
690static 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 */
730const 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 */
746const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
747 const char *name, int namelen, int *lenp);
748static 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
785const void *fdt_getprop(const void *fdt, int nodeoffset,
786 const char *name, int *lenp);
787static 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
805uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
806
816#ifndef SWIG /* Not available in Python */
817const char *fdt_get_alias_namelen(const void *fdt,
818 const char *name, int namelen);
819#endif
820
833const char *fdt_get_alias(const void *fdt, const char *name);
834
860int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
861
892int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
893 int supernodedepth, int *nodedepth);
894
914int fdt_node_depth(const void *fdt, int nodeoffset);
915
937int fdt_parent_offset(const void *fdt, int nodeoffset);
938
977int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
978 const char *propname,
979 const void *propval, int proplen);
980
1000int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
1001
1024int fdt_node_check_compatible(const void *fdt, int nodeoffset,
1025 const char *compatible);
1026
1061int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
1062 const char *compatible);
1063
1076int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
1077
1088int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
1089
1109int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
1110 const char *string);
1111
1136const 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
1173int fdt_address_cells(const void *fdt, int nodeoffset);
1174
1194int 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 */
1218int 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 */
1253int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
1254 const void *val, int len);
1255#endif
1256
1285static 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
1320static 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
1332static 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
1362int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
1363
1386int 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
1416int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags);
1417
1429int fdt_create(void *buf, int bufsize);
1430
1431int fdt_resize(void *fdt, void *buf, int bufsize);
1432int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1433int fdt_finish_reservemap(void *fdt);
1434int fdt_begin_node(void *fdt, const char *name);
1435int fdt_property(void *fdt, const char *name, const void *val, int len);
1436static 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}
1441static 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 */
1448static 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
1467int 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)
1471int fdt_end_node(void *fdt);
1472int fdt_finish(void *fdt);
1473
1474/**********************************************************************/
1475/* Read-write functions */
1476/**********************************************************************/
1477
1478int fdt_create_empty_tree(void *buf, int bufsize);
1479int fdt_open_into(const void *fdt, void *buf, int bufsize);
1480int fdt_pack(void *fdt);
1481
1504int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1505
1528int fdt_del_mem_rsv(void *fdt, int n);
1529
1554int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1555
1584int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1585 const void *val, int len);
1586
1615int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1616 int len, void **prop_data);
1617
1646static 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
1681static 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
1693static 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
1787int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1788 const void *val, int len);
1789
1818static 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
1853static 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
1865static 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
1935int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
1936 const char *name, uint64_t addr, uint64_t size);
1937
1960int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1961
1974#ifndef SWIG /* Not available in Python */
1975int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1976 const char *name, int namelen);
1977#endif
1978
2010int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
2011
2033int fdt_del_node(void *fdt, int nodeoffset);
2034
2064int fdt_overlay_apply(void *fdt, void *fdto);
2065
2066/**********************************************************************/
2067/* Debugging / informational functions */
2068/**********************************************************************/
2069
2070const char *fdt_strerror(int errval);
2071
2072#endif /* LIBFDT_H */
fdt_property
Definition: fdt.h:41
p
unsigned p
Definition: tte.h:17