58 static int _fdt_blocks_misordered(
const void *fdt,
59 int mem_rsv_size,
int struct_size)
70 static int _fdt_rw_check_header(
void *fdt)
80 fdt_set_version(fdt, 17);
85 #define FDT_RW_CHECK_HEADER(fdt) \
88 if ((err = _fdt_rw_check_header(fdt)) != 0) \
92 static inline int _fdt_data_size(
void *fdt)
97 static int _fdt_splice(
void *fdt,
void *splicepoint,
int oldlen,
int newlen)
99 char *
p = splicepoint;
100 char *
end = (
char *)fdt + _fdt_data_size(fdt);
102 if (((p + oldlen) < p) || ((p + oldlen) > end))
104 if ((end - oldlen + newlen) > ((
char *)fdt +
fdt_totalsize(fdt)))
106 memmove(p + newlen, p + oldlen, end - p - oldlen);
113 int delta = (newn - oldn) *
sizeof(*p);
115 err = _fdt_splice(fdt, p, oldn *
sizeof(*p), newn *
sizeof(*p));
123 static int _fdt_splice_struct(
void *fdt,
void *p,
124 int oldlen,
int newlen)
126 int delta = newlen - oldlen;
129 if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
137 static int _fdt_splice_string(
void *fdt,
int newlen)
139 void *p = (
char *)fdt
143 if ((err = _fdt_splice(fdt, p, 0, newlen)))
150 static int _fdt_find_add_string(
void *fdt,
const char *
s)
164 err = _fdt_splice_string(fdt, len);
169 return (
new - strtab);
180 err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
199 err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
205 static int _fdt_resize_property(
void *fdt,
int nodeoffset,
const char *
name,
211 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
215 if ((err = _fdt_splice_struct(fdt, (*prop)->data,
FDT_TAGALIGN(oldlen),
223 static int _fdt_add_property(
void *fdt,
int nodeoffset,
const char *name,
234 namestroff = _fdt_find_add_string(fdt, name);
238 *prop = _fdt_offset_ptr_w(fdt, nextoffset);
241 err = _fdt_splice_struct(fdt, *prop, 0, proplen);
265 err = _fdt_splice_struct(fdt, namep,
FDT_TAGALIGN(oldlen+1),
270 memcpy(namep, name, newlen+1);
275 const void *
val,
int len)
282 err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
284 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
293 const void *
val,
int len)
296 int err, oldlen, newlen;
300 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
302 newlen = len + oldlen;
303 err = _fdt_splice_struct(fdt, prop->
data,
311 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
326 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
331 return _fdt_splice_struct(fdt, prop, proplen, 0);
359 nh = _fdt_offset_ptr_w(fdt, offset);
362 err = _fdt_splice_struct(fdt, nh, 0, nodelen);
390 return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
391 endoffset - nodeoffset, 0);
394 static void _fdt_packblocks(
const char *old,
char *
new,
395 int mem_rsv_size,
int struct_size)
397 int mem_rsv_off, struct_off, strings_off;
400 struct_off = mem_rsv_off + mem_rsv_size;
401 strings_off = struct_off + struct_size;
404 fdt_set_off_mem_rsvmap(
new, mem_rsv_off);
407 fdt_set_off_dt_struct(
new, struct_off);
408 fdt_set_size_dt_struct(
new, struct_size);
412 fdt_set_off_dt_strings(
new, strings_off);
419 int mem_rsv_size, struct_size;
421 const char *fdtstart = fdt;
440 if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
445 fdt_set_version(buf, 17);
446 fdt_set_size_dt_struct(buf, struct_size);
447 fdt_set_totalsize(buf, bufsize);
455 if (bufsize < newsize)
461 if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
464 if ((tmp + newsize) > ((
char *)buf + bufsize))
468 _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
472 fdt_set_totalsize(buf, bufsize);
473 fdt_set_version(buf, 17);
474 fdt_set_last_comp_version(buf, 16);
489 fdt_set_totalsize(fdt, _fdt_data_size(fdt));