fdt_rw.c (c1144d29f405ce1f4e6ede6482beb3d0d09750c6) fdt_rw.c (f858927fd6ce394a7f431153d44ad0a09e8f49a1)
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or

--- 53 unchanged lines hidden (view full) ---

62 || (fdt_off_dt_struct(fdt) <
63 (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
64 || (fdt_off_dt_strings(fdt) <
65 (fdt_off_dt_struct(fdt) + struct_size))
66 || (fdt_totalsize(fdt) <
67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
68}
69
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or

--- 53 unchanged lines hidden (view full) ---

62 || (fdt_off_dt_struct(fdt) <
63 (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
64 || (fdt_off_dt_strings(fdt) <
65 (fdt_off_dt_struct(fdt) + struct_size))
66 || (fdt_totalsize(fdt) <
67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
68}
69
70static int fdt_rw_check_header_(void *fdt)
70static int fdt_rw_probe_(void *fdt)
71{
71{
72 FDT_CHECK_HEADER(fdt);
72 FDT_RO_PROBE(fdt);
73
74 if (fdt_version(fdt) < 17)
75 return -FDT_ERR_BADVERSION;
76 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
77 fdt_size_dt_struct(fdt)))
78 return -FDT_ERR_BADLAYOUT;
79 if (fdt_version(fdt) > 17)
80 fdt_set_version(fdt, 17);
81
82 return 0;
83}
84
73
74 if (fdt_version(fdt) < 17)
75 return -FDT_ERR_BADVERSION;
76 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
77 fdt_size_dt_struct(fdt)))
78 return -FDT_ERR_BADLAYOUT;
79 if (fdt_version(fdt) > 17)
80 fdt_set_version(fdt, 17);
81
82 return 0;
83}
84
85#define FDT_RW_CHECK_HEADER(fdt) \
85#define FDT_RW_PROBE(fdt) \
86 { \
87 int err_; \
86 { \
87 int err_; \
88 if ((err_ = fdt_rw_check_header_(fdt)) != 0) \
88 if ((err_ = fdt_rw_probe_(fdt)) != 0) \
89 return err_; \
90 }
91
92static inline int fdt_data_size_(void *fdt)
93{
94 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
95}
96

--- 74 unchanged lines hidden (view full) ---

171 return (new - strtab);
172}
173
174int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
175{
176 struct fdt_reserve_entry *re;
177 int err;
178
89 return err_; \
90 }
91
92static inline int fdt_data_size_(void *fdt)
93{
94 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
95}
96

--- 74 unchanged lines hidden (view full) ---

171 return (new - strtab);
172}
173
174int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
175{
176 struct fdt_reserve_entry *re;
177 int err;
178
179 FDT_RW_CHECK_HEADER(fdt);
179 FDT_RW_PROBE(fdt);
180
181 re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
182 err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
183 if (err)
184 return err;
185
186 re->address = cpu_to_fdt64(address);
187 re->size = cpu_to_fdt64(size);
188 return 0;
189}
190
191int fdt_del_mem_rsv(void *fdt, int n)
192{
193 struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
194
180
181 re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
182 err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
183 if (err)
184 return err;
185
186 re->address = cpu_to_fdt64(address);
187 re->size = cpu_to_fdt64(size);
188 return 0;
189}
190
191int fdt_del_mem_rsv(void *fdt, int n)
192{
193 struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
194
195 FDT_RW_CHECK_HEADER(fdt);
195 FDT_RW_PROBE(fdt);
196
197 if (n >= fdt_num_mem_rsv(fdt))
198 return -FDT_ERR_NOTFOUND;
199
200 return fdt_splice_mem_rsv_(fdt, re, 1, 0);
201}
202
203static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,

--- 43 unchanged lines hidden (view full) ---

247}
248
249int fdt_set_name(void *fdt, int nodeoffset, const char *name)
250{
251 char *namep;
252 int oldlen, newlen;
253 int err;
254
196
197 if (n >= fdt_num_mem_rsv(fdt))
198 return -FDT_ERR_NOTFOUND;
199
200 return fdt_splice_mem_rsv_(fdt, re, 1, 0);
201}
202
203static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,

--- 43 unchanged lines hidden (view full) ---

247}
248
249int fdt_set_name(void *fdt, int nodeoffset, const char *name)
250{
251 char *namep;
252 int oldlen, newlen;
253 int err;
254
255 FDT_RW_CHECK_HEADER(fdt);
255 FDT_RW_PROBE(fdt);
256
257 namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
258 if (!namep)
259 return oldlen;
260
261 newlen = strlen(name);
262
263 err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),

--- 6 unchanged lines hidden (view full) ---

270}
271
272int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
273 int len, void **prop_data)
274{
275 struct fdt_property *prop;
276 int err;
277
256
257 namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
258 if (!namep)
259 return oldlen;
260
261 newlen = strlen(name);
262
263 err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),

--- 6 unchanged lines hidden (view full) ---

270}
271
272int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
273 int len, void **prop_data)
274{
275 struct fdt_property *prop;
276 int err;
277
278 FDT_RW_CHECK_HEADER(fdt);
278 FDT_RW_PROBE(fdt);
279
280 err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
281 if (err == -FDT_ERR_NOTFOUND)
282 err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
283 if (err)
284 return err;
285
286 *prop_data = prop->data;

--- 16 unchanged lines hidden (view full) ---

303}
304
305int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
306 const void *val, int len)
307{
308 struct fdt_property *prop;
309 int err, oldlen, newlen;
310
279
280 err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
281 if (err == -FDT_ERR_NOTFOUND)
282 err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
283 if (err)
284 return err;
285
286 *prop_data = prop->data;

--- 16 unchanged lines hidden (view full) ---

303}
304
305int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
306 const void *val, int len)
307{
308 struct fdt_property *prop;
309 int err, oldlen, newlen;
310
311 FDT_RW_CHECK_HEADER(fdt);
311 FDT_RW_PROBE(fdt);
312
313 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
314 if (prop) {
315 newlen = len + oldlen;
316 err = fdt_splice_struct_(fdt, prop->data,
317 FDT_TAGALIGN(oldlen),
318 FDT_TAGALIGN(newlen));
319 if (err)

--- 9 unchanged lines hidden (view full) ---

329 return 0;
330}
331
332int fdt_delprop(void *fdt, int nodeoffset, const char *name)
333{
334 struct fdt_property *prop;
335 int len, proplen;
336
312
313 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
314 if (prop) {
315 newlen = len + oldlen;
316 err = fdt_splice_struct_(fdt, prop->data,
317 FDT_TAGALIGN(oldlen),
318 FDT_TAGALIGN(newlen));
319 if (err)

--- 9 unchanged lines hidden (view full) ---

329 return 0;
330}
331
332int fdt_delprop(void *fdt, int nodeoffset, const char *name)
333{
334 struct fdt_property *prop;
335 int len, proplen;
336
337 FDT_RW_CHECK_HEADER(fdt);
337 FDT_RW_PROBE(fdt);
338
339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
340 if (!prop)
341 return len;
342
343 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
344 return fdt_splice_struct_(fdt, prop, proplen, 0);
345}
346
347int fdt_add_subnode_namelen(void *fdt, int parentoffset,
348 const char *name, int namelen)
349{
350 struct fdt_node_header *nh;
351 int offset, nextoffset;
352 int nodelen;
353 int err;
354 uint32_t tag;
355 fdt32_t *endtag;
356
338
339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
340 if (!prop)
341 return len;
342
343 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
344 return fdt_splice_struct_(fdt, prop, proplen, 0);
345}
346
347int fdt_add_subnode_namelen(void *fdt, int parentoffset,
348 const char *name, int namelen)
349{
350 struct fdt_node_header *nh;
351 int offset, nextoffset;
352 int nodelen;
353 int err;
354 uint32_t tag;
355 fdt32_t *endtag;
356
357 FDT_RW_CHECK_HEADER(fdt);
357 FDT_RW_PROBE(fdt);
358
359 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
360 if (offset >= 0)
361 return -FDT_ERR_EXISTS;
362 else if (offset != -FDT_ERR_NOTFOUND)
363 return offset;
364
365 /* Try to place the new node after the parent's properties */

--- 23 unchanged lines hidden (view full) ---

389{
390 return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
391}
392
393int fdt_del_node(void *fdt, int nodeoffset)
394{
395 int endoffset;
396
358
359 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
360 if (offset >= 0)
361 return -FDT_ERR_EXISTS;
362 else if (offset != -FDT_ERR_NOTFOUND)
363 return offset;
364
365 /* Try to place the new node after the parent's properties */

--- 23 unchanged lines hidden (view full) ---

389{
390 return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
391}
392
393int fdt_del_node(void *fdt, int nodeoffset)
394{
395 int endoffset;
396
397 FDT_RW_CHECK_HEADER(fdt);
397 FDT_RW_PROBE(fdt);
398
399 endoffset = fdt_node_end_offset_(fdt, nodeoffset);
400 if (endoffset < 0)
401 return endoffset;
402
403 return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
404 endoffset - nodeoffset, 0);
405}

--- 24 unchanged lines hidden (view full) ---

430{
431 int err;
432 int mem_rsv_size, struct_size;
433 int newsize;
434 const char *fdtstart = fdt;
435 const char *fdtend = fdtstart + fdt_totalsize(fdt);
436 char *tmp;
437
398
399 endoffset = fdt_node_end_offset_(fdt, nodeoffset);
400 if (endoffset < 0)
401 return endoffset;
402
403 return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
404 endoffset - nodeoffset, 0);
405}

--- 24 unchanged lines hidden (view full) ---

430{
431 int err;
432 int mem_rsv_size, struct_size;
433 int newsize;
434 const char *fdtstart = fdt;
435 const char *fdtend = fdtstart + fdt_totalsize(fdt);
436 char *tmp;
437
438 FDT_CHECK_HEADER(fdt);
438 FDT_RO_PROBE(fdt);
439
440 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
441 * sizeof(struct fdt_reserve_entry);
442
443 if (fdt_version(fdt) >= 17) {
444 struct_size = fdt_size_dt_struct(fdt);
445 } else {
446 struct_size = 0;

--- 42 unchanged lines hidden (view full) ---

489
490 return 0;
491}
492
493int fdt_pack(void *fdt)
494{
495 int mem_rsv_size;
496
439
440 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
441 * sizeof(struct fdt_reserve_entry);
442
443 if (fdt_version(fdt) >= 17) {
444 struct_size = fdt_size_dt_struct(fdt);
445 } else {
446 struct_size = 0;

--- 42 unchanged lines hidden (view full) ---

489
490 return 0;
491}
492
493int fdt_pack(void *fdt)
494{
495 int mem_rsv_size;
496
497 FDT_RW_CHECK_HEADER(fdt);
497 FDT_RW_PROBE(fdt);
498
499 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
500 * sizeof(struct fdt_reserve_entry);
501 fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
502 fdt_set_totalsize(fdt, fdt_data_size_(fdt));
503
504 return 0;
505}
498
499 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
500 * sizeof(struct fdt_reserve_entry);
501 fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
502 fdt_set_totalsize(fdt, fdt_data_size_(fdt));
503
504 return 0;
505}