blob: db113bd22039b8f0707c04aac708680323305eb2 [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001#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#define FDT_ERR_NOTFOUND 1
61
62#define FDT_ERR_EXISTS 2
63#define FDT_ERR_NOSPACE 3
64
65#define FDT_ERR_BADOFFSET 4
66#define FDT_ERR_BADPATH 5
67#define FDT_ERR_BADPHANDLE 6
68#define FDT_ERR_BADSTATE 7
69
70#define FDT_ERR_TRUNCATED 8
71#define FDT_ERR_BADMAGIC 9
72#define FDT_ERR_BADVERSION 10
73#define FDT_ERR_BADSTRUCTURE 11
74#define FDT_ERR_BADLAYOUT 12
75
76#define FDT_ERR_INTERNAL 13
77
78#define FDT_ERR_MAX 13
79
80
81const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
82static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
83{
84 return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
85}
86
87uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
88
89
90int fdt_next_node(const void *fdt, int offset, int *depth);
91
92
93#define fdt_get_header(fdt, field) \
94 (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
95#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
96#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
97#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
98#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
99#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
100#define fdt_version(fdt) (fdt_get_header(fdt, version))
101#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
102#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
103#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
104#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
105
106#define __fdt_set_hdr(name) \
107 static inline void fdt_set_##name(void *fdt, uint32_t val) \
108 { \
109 struct fdt_header *fdth = fdt; \
110 fdth->name = cpu_to_fdt32(val); \
111 }
112__fdt_set_hdr(magic);
113__fdt_set_hdr(totalsize);
114__fdt_set_hdr(off_dt_struct);
115__fdt_set_hdr(off_dt_strings);
116__fdt_set_hdr(off_mem_rsvmap);
117__fdt_set_hdr(version);
118__fdt_set_hdr(last_comp_version);
119__fdt_set_hdr(boot_cpuid_phys);
120__fdt_set_hdr(size_dt_strings);
121__fdt_set_hdr(size_dt_struct);
122#undef __fdt_set_hdr
123
124int fdt_check_header(const void *fdt);
125
126int fdt_move(const void *fdt, void *buf, int bufsize);
127
128
129const char *fdt_string(const void *fdt, int stroffset);
130
131int fdt_num_mem_rsv(const void *fdt);
132
133int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
134
135int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
136 const char *name, int namelen);
137int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
138
139int fdt_path_offset(const void *fdt, const char *path);
140
141/**
142 * fdt_get_name - retrieve the name of a given node
143 * @fdt: pointer to the device tree blob
144 * @nodeoffset: structure block offset of the starting node
145 * @lenp: pointer to an integer variable (will be overwritten) or NULL
146 *
147 * fdt_get_name() retrieves the name (including unit address) of the
148 * device tree node at structure block offset nodeoffset. If lenp is
149 * non-NULL, the length of this name is also returned, in the integer
150 * pointed to by lenp.
151 *
152 * returns:
153 * pointer to the node's name, on success
154 * If lenp is non-NULL, *lenp contains the length of that name (>=0)
155 * NULL, on error
156 * if lenp is non-NULL *lenp contains an error code (<0):
157 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
158 * -FDT_ERR_BADMAGIC,
159 * -FDT_ERR_BADVERSION,
160 * -FDT_ERR_BADSTATE, standard meanings
161 */
162const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
163
164/**
165 * fdt_get_property - find a given property in a given node
166 * @fdt: pointer to the device tree blob
167 * @nodeoffset: offset of the node whose property to find
168 * @name: name of the property to find
169 * @lenp: pointer to an integer variable (will be overwritten) or NULL
170 *
171 * fdt_get_property() retrieves a pointer to the fdt_property
172 * structure within the device tree blob corresponding to the property
173 * named 'name' of the node at offset nodeoffset. If lenp is
174 * non-NULL, the length of the property value is also returned, in the
175 * integer pointed to by lenp.
176 *
177 * returns:
178 * pointer to the structure representing the property
179 * if lenp is non-NULL, *lenp contains the length of the property
180 * value (>=0)
181 * NULL, on error
182 * if lenp is non-NULL, *lenp contains an error code (<0):
183 * -FDT_ERR_NOTFOUND, node does not have named property
184 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
185 * -FDT_ERR_BADMAGIC,
186 * -FDT_ERR_BADVERSION,
187 * -FDT_ERR_BADSTATE,
188 * -FDT_ERR_BADSTRUCTURE,
189 * -FDT_ERR_TRUNCATED, standard meanings
190 */
191const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
192 const char *name, int *lenp);
193static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
194 const char *name,
195 int *lenp)
196{
197 return (struct fdt_property *)(uintptr_t)
198 fdt_get_property(fdt, nodeoffset, name, lenp);
199}
200
201/**
202 * fdt_getprop - retrieve the value of a given property
203 * @fdt: pointer to the device tree blob
204 * @nodeoffset: offset of the node whose property to find
205 * @name: name of the property to find
206 * @lenp: pointer to an integer variable (will be overwritten) or NULL
207 *
208 * fdt_getprop() retrieves a pointer to the value of the property
209 * named 'name' of the node at offset nodeoffset (this will be a
210 * pointer to within the device blob itself, not a copy of the value).
211 * If lenp is non-NULL, the length of the property value is also
212 * returned, in the integer pointed to by lenp.
213 *
214 * returns:
215 * pointer to the property's value
216 * if lenp is non-NULL, *lenp contains the length of the property
217 * value (>=0)
218 * NULL, on error
219 * if lenp is non-NULL, *lenp contains an error code (<0):
220 * -FDT_ERR_NOTFOUND, node does not have named property
221 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
222 * -FDT_ERR_BADMAGIC,
223 * -FDT_ERR_BADVERSION,
224 * -FDT_ERR_BADSTATE,
225 * -FDT_ERR_BADSTRUCTURE,
226 * -FDT_ERR_TRUNCATED, standard meanings
227 */
228const void *fdt_getprop(const void *fdt, int nodeoffset,
229 const char *name, int *lenp);
230static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
231 const char *name, int *lenp)
232{
233 return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
234}
235
236uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
237
238/**
239 * fdt_get_path - determine the full path of a node
240 * @fdt: pointer to the device tree blob
241 * @nodeoffset: offset of the node whose path to find
242 * @buf: character buffer to contain the returned path (will be overwritten)
243 * @buflen: size of the character buffer at buf
244 *
245 * fdt_get_path() computes the full path of the node at offset
246 * nodeoffset, and records that path in the buffer at buf.
247 *
248 * NOTE: This function is expensive, as it must scan the device tree
249 * structure from the start to nodeoffset.
250 *
251 * returns:
252 * 0, on success
253 * buf contains the absolute path of the node at
254 * nodeoffset, as a NUL-terminated string.
255 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
256 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
257 * characters and will not fit in the given buffer.
258 * -FDT_ERR_BADMAGIC,
259 * -FDT_ERR_BADVERSION,
260 * -FDT_ERR_BADSTATE,
261 * -FDT_ERR_BADSTRUCTURE, standard meanings
262 */
263int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
264
265/**
266 * fdt_supernode_atdepth_offset - find a specific ancestor of a node
267 * @fdt: pointer to the device tree blob
268 * @nodeoffset: offset of the node whose parent to find
269 * @supernodedepth: depth of the ancestor to find
270 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
271 *
272 * fdt_supernode_atdepth_offset() finds an ancestor of the given node
273 * at a specific depth from the root (where the root itself has depth
274 * 0, its immediate subnodes depth 1 and so forth). So
275 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
276 * will always return 0, the offset of the root node. If the node at
277 * nodeoffset has depth D, then:
278 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
279 * will return nodeoffset itself.
280 *
281 * NOTE: This function is expensive, as it must scan the device tree
282 * structure from the start to nodeoffset.
283 *
284 * returns:
285
286 * structure block offset of the node at node offset's ancestor
287 * of depth supernodedepth (>=0), on success
288 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
289* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
290 * -FDT_ERR_BADMAGIC,
291 * -FDT_ERR_BADVERSION,
292 * -FDT_ERR_BADSTATE,
293 * -FDT_ERR_BADSTRUCTURE, standard meanings
294 */
295int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
296 int supernodedepth, int *nodedepth);
297
298int fdt_node_depth(const void *fdt, int nodeoffset);
299
300int fdt_parent_offset(const void *fdt, int nodeoffset);
301
302int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
303 const char *propname,
304 const void *propval, int proplen);
305
306int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
307
308int fdt_node_check_compatible(const void *fdt, int nodeoffset,
309 const char *compatible);
310
311int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
312 const char *compatible);
313
314
315int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
316 const void *val, int len);
317
318static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
319 const char *name, uint32_t val)
320{
321 val = cpu_to_fdt32(val);
322 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
323}
324
325int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
326
327int fdt_nop_node(void *fdt, int nodeoffset);
328
329
330int fdt_create(void *buf, int bufsize);
331int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
332int fdt_finish_reservemap(void *fdt);
333int fdt_begin_node(void *fdt, const char *name);
334int fdt_property(void *fdt, const char *name, const void *val, int len);
335static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
336{
337 val = cpu_to_fdt32(val);
338 return fdt_property(fdt, name, &val, sizeof(val));
339}
340#define fdt_property_string(fdt, name, str) \
341 fdt_property(fdt, name, str, strlen(str)+1)
342int fdt_end_node(void *fdt);
343int fdt_finish(void *fdt);
344
345
346int fdt_open_into(const void *fdt, void *buf, int bufsize);
347int fdt_pack(void *fdt);
348
349int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
350
351int fdt_del_mem_rsv(void *fdt, int n);
352
353int fdt_set_name(void *fdt, int nodeoffset, const char *name);
354
355int fdt_setprop(void *fdt, int nodeoffset, const char *name,
356 const void *val, int len);
357
358static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
359 uint32_t val)
360{
361 val = cpu_to_fdt32(val);
362 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
363}
364
365#define fdt_setprop_string(fdt, nodeoffset, name, str) \
366 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
367
368int fdt_delprop(void *fdt, int nodeoffset, const char *name);
369
370int fdt_add_subnode_namelen(void *fdt, int parentoffset,
371 const char *name, int namelen);
372
373int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
374
375int fdt_del_node(void *fdt, int nodeoffset);
376
377
378const char *fdt_strerror(int errval);
379
380#endif