56#include "libfdt_internal.h"
59_fdt_blocks_misordered (
65 return (fdt_off_mem_rsvmap (fdt) < FDT_ALIGN (
sizeof (
struct fdt_header), 8))
66 || (fdt_off_dt_struct (fdt) <
67 (fdt_off_mem_rsvmap (fdt) + mem_rsv_size))
68 || (fdt_off_dt_strings (fdt) <
69 (fdt_off_dt_struct (fdt) + struct_size))
70 || (fdt_totalsize (fdt) <
71 (fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt)));
79 FDT_CHECK_HEADER (fdt);
81 if (fdt_version (fdt) < 17) {
82 return -FDT_ERR_BADVERSION;
85 if (_fdt_blocks_misordered (
88 fdt_size_dt_struct (fdt)
91 return -FDT_ERR_BADLAYOUT;
94 if (fdt_version (fdt) > 17) {
95 fdt_set_version (fdt, 17);
101#define FDT_RW_CHECK_HEADER(fdt) \
104 if ((__err = _fdt_rw_check_header(fdt)) != 0) \
113 return fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
124 char *p = splicepoint;
125 char *end = (
char *)fdt + _fdt_data_size (fdt);
127 if (((p + oldlen) < p) || ((p + oldlen) > end)) {
128 return -FDT_ERR_BADOFFSET;
131 if ((p < (
char *)fdt) || ((end - oldlen + newlen) < (
char *)fdt)) {
132 return -FDT_ERR_BADOFFSET;
135 if ((end - oldlen + newlen) > ((
char *)fdt + fdt_totalsize (fdt))) {
136 return -FDT_ERR_NOSPACE;
139 memmove (p + newlen, p + oldlen, end - p - oldlen);
151 int delta = (newn - oldn) *
sizeof (*p);
154 err = _fdt_splice (fdt, p, oldn *
sizeof (*p), newn *
sizeof (*p));
159 fdt_set_off_dt_struct (fdt, fdt_off_dt_struct (fdt) + delta);
160 fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
172 int delta = newlen - oldlen;
175 if ((err = _fdt_splice (fdt, p, oldlen, newlen))) {
179 fdt_set_size_dt_struct (fdt, fdt_size_dt_struct (fdt) + delta);
180 fdt_set_off_dt_strings (fdt, fdt_off_dt_strings (fdt) + delta);
190 void *p = (
char *)fdt
191 + fdt_off_dt_strings (fdt) + fdt_size_dt_strings (fdt);
194 if ((err = _fdt_splice (fdt, p, 0, newlen))) {
198 fdt_set_size_dt_strings (fdt, fdt_size_dt_strings (fdt) + newlen);
203_fdt_find_add_string (
208 char *strtab = (
char *)fdt + fdt_off_dt_strings (fdt);
211 int len = strlen (s) + 1;
214 p = _fdt_find_string (strtab, fdt_size_dt_strings (fdt), s);
220 new = strtab + fdt_size_dt_strings (fdt);
221 err = _fdt_splice_string (fdt, len);
226 memcpy (
new, s, len);
227 return (
new - strtab);
240 FDT_RW_CHECK_HEADER (fdt);
242 re = _fdt_mem_rsv_w (fdt, fdt_num_mem_rsv (fdt));
243 err = _fdt_splice_mem_rsv (fdt, re, 0, 1);
248 re->address = cpu_to_fdt64 (address);
249 re->size = cpu_to_fdt64 (size);
261 FDT_RW_CHECK_HEADER (fdt);
263 if (n >= fdt_num_mem_rsv (fdt)) {
264 return -FDT_ERR_NOTFOUND;
267 return _fdt_splice_mem_rsv (fdt, re, 1, 0);
271_fdt_resize_property (
282 *prop = fdt_get_property_w (fdt, nodeoffset, name, &oldlen);
287 if ((err = _fdt_splice_struct (
290 FDT_TAGALIGN (oldlen),
297 (*prop)->len = cpu_to_fdt32 (len);
315 if ((nextoffset = _fdt_check_node_offset (fdt, nodeoffset)) < 0) {
319 namestroff = _fdt_find_add_string (fdt, name);
320 if (namestroff < 0) {
324 *prop = _fdt_offset_ptr_w (fdt, nextoffset);
325 proplen =
sizeof (**prop) + FDT_TAGALIGN (len);
327 err = _fdt_splice_struct (fdt, *prop, 0, proplen);
332 (*prop)->tag = cpu_to_fdt32 (FDT_PROP);
333 (*prop)->nameoff = cpu_to_fdt32 (namestroff);
334 (*prop)->len = cpu_to_fdt32 (len);
349 FDT_RW_CHECK_HEADER (fdt);
351 namep = (
char *)(uintptr_t)fdt_get_name (fdt, nodeoffset, &oldlen);
356 newlen = strlen (name);
358 err = _fdt_splice_struct (
361 FDT_TAGALIGN (oldlen+1),
362 FDT_TAGALIGN (newlen+1)
368 memcpy (namep, name, newlen+1);
373fdt_setprop_placeholder (
384 FDT_RW_CHECK_HEADER (fdt);
386 err = _fdt_resize_property (fdt, nodeoffset, name, len, &prop);
387 if (err == -FDT_ERR_NOTFOUND) {
388 err = _fdt_add_property (fdt, nodeoffset, name, len, &prop);
395 *prop_data = prop->data;
411 err = fdt_setprop_placeholder (fdt, nodeoffset, name, len, &prop_data);
417 memcpy (prop_data, val, len);
433 int err, oldlen, newlen;
435 FDT_RW_CHECK_HEADER (fdt);
437 prop = fdt_get_property_w (fdt, nodeoffset, name, &oldlen);
439 newlen = len + oldlen;
440 err = _fdt_splice_struct (
443 FDT_TAGALIGN (oldlen),
444 FDT_TAGALIGN (newlen)
450 prop->len = cpu_to_fdt32 (newlen);
451 memcpy (prop->data + oldlen, val, len);
453 err = _fdt_add_property (fdt, nodeoffset, name, len, &prop);
458 memcpy (prop->data, val, len);
474 FDT_RW_CHECK_HEADER (fdt);
476 prop = fdt_get_property_w (fdt, nodeoffset, name, &len);
481 proplen =
sizeof (*prop) + FDT_TAGALIGN (len);
482 return _fdt_splice_struct (fdt, prop, proplen, 0);
486fdt_add_subnode_namelen (
494 int offset, nextoffset;
500 FDT_RW_CHECK_HEADER (fdt);
502 offset = fdt_subnode_offset_namelen (fdt, parentoffset, name, namelen);
504 return -FDT_ERR_EXISTS;
505 }
else if (offset != -FDT_ERR_NOTFOUND) {
510 fdt_next_tag (fdt, parentoffset, &nextoffset);
513 tag = fdt_next_tag (fdt, offset, &nextoffset);
514 }
while ((tag == FDT_PROP) || (tag == FDT_NOP));
516 nh = _fdt_offset_ptr_w (fdt, offset);
517 nodelen =
sizeof (*nh) + FDT_TAGALIGN (namelen+1) + FDT_TAGSIZE;
519 err = _fdt_splice_struct (fdt, nh, 0, nodelen);
524 nh->tag = cpu_to_fdt32 (FDT_BEGIN_NODE);
525 memset (nh->name, 0, FDT_TAGALIGN (namelen+1));
526 memcpy (nh->name, name, namelen);
527 endtag = (fdt32_t *)((
char *)nh + nodelen - FDT_TAGSIZE);
528 *endtag = cpu_to_fdt32 (FDT_END_NODE);
540 return fdt_add_subnode_namelen (fdt, parentoffset, name, strlen (name));
551 FDT_RW_CHECK_HEADER (fdt);
553 endoffset = _fdt_node_end_offset (fdt, nodeoffset);
558 return _fdt_splice_struct (
560 _fdt_offset_ptr_w (fdt, nodeoffset),
561 endoffset - nodeoffset,
574 int mem_rsv_off, struct_off, strings_off;
576 mem_rsv_off = FDT_ALIGN (
sizeof (
struct fdt_header), 8);
577 struct_off = mem_rsv_off + mem_rsv_size;
578 strings_off = struct_off + struct_size;
580 memmove (
new + mem_rsv_off, old + fdt_off_mem_rsvmap (old), mem_rsv_size);
581 fdt_set_off_mem_rsvmap (
new, mem_rsv_off);
583 memmove (
new + struct_off, old + fdt_off_dt_struct (old), struct_size);
584 fdt_set_off_dt_struct (
new, struct_off);
585 fdt_set_size_dt_struct (
new, struct_size);
589 old + fdt_off_dt_strings (old),
590 fdt_size_dt_strings (old)
592 fdt_set_off_dt_strings (
new, strings_off);
593 fdt_set_size_dt_strings (
new, fdt_size_dt_strings (old));
604 int mem_rsv_size, struct_size;
606 const char *fdtstart = fdt;
607 const char *fdtend = fdtstart + fdt_totalsize (fdt);
610 FDT_CHECK_HEADER (fdt);
612 mem_rsv_size = (fdt_num_mem_rsv (fdt)+1)
615 if (fdt_version (fdt) >= 17) {
616 struct_size = fdt_size_dt_struct (fdt);
619 while (fdt_next_tag (fdt, struct_size, &struct_size) != FDT_END) {
622 if (struct_size < 0) {
627 if (!_fdt_blocks_misordered (fdt, mem_rsv_size, struct_size)) {
629 err = fdt_move (fdt, buf, bufsize);
634 fdt_set_version (buf, 17);
635 fdt_set_size_dt_struct (buf, struct_size);
636 fdt_set_totalsize (buf, bufsize);
641 newsize = FDT_ALIGN (
sizeof (
struct fdt_header), 8) + mem_rsv_size
642 + struct_size + fdt_size_dt_strings (fdt);
644 if (bufsize < newsize) {
645 return -FDT_ERR_NOSPACE;
651 if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
653 tmp = (
char *)(uintptr_t)fdtend;
654 if ((tmp + newsize) > ((
char *)buf + bufsize)) {
655 return -FDT_ERR_NOSPACE;
659 _fdt_packblocks (fdt, tmp, mem_rsv_size, struct_size);
660 memmove (buf, tmp, newsize);
662 fdt_set_magic (buf, FDT_MAGIC);
663 fdt_set_totalsize (buf, bufsize);
664 fdt_set_version (buf, 17);
665 fdt_set_last_comp_version (buf, 16);
666 fdt_set_boot_cpuid_phys (buf, fdt_boot_cpuid_phys (fdt));
678 FDT_RW_CHECK_HEADER (fdt);
680 mem_rsv_size = (fdt_num_mem_rsv (fdt)+1)
682 _fdt_packblocks (fdt, fdt, mem_rsv_size, fdt_size_dt_struct (fdt));
683 fdt_set_totalsize (fdt, _fdt_data_size (fdt));