162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * libfdt - Flat Device Tree manipulation 462306a36Sopenharmony_ci * Copyright (C) 2006 David Gibson, IBM Corporation. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include "libfdt_env.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <fdt.h> 962306a36Sopenharmony_ci#include <libfdt.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "libfdt_internal.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic int fdt_sw_probe_(void *fdt) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci if (!can_assume(VALID_INPUT)) { 1662306a36Sopenharmony_ci if (fdt_magic(fdt) == FDT_MAGIC) 1762306a36Sopenharmony_ci return -FDT_ERR_BADSTATE; 1862306a36Sopenharmony_ci else if (fdt_magic(fdt) != FDT_SW_MAGIC) 1962306a36Sopenharmony_ci return -FDT_ERR_BADMAGIC; 2062306a36Sopenharmony_ci } 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci return 0; 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define FDT_SW_PROBE(fdt) \ 2662306a36Sopenharmony_ci { \ 2762306a36Sopenharmony_ci int err; \ 2862306a36Sopenharmony_ci if ((err = fdt_sw_probe_(fdt)) != 0) \ 2962306a36Sopenharmony_ci return err; \ 3062306a36Sopenharmony_ci } 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 'memrsv' state: Initial state after fdt_create() 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * Allowed functions: 3562306a36Sopenharmony_ci * fdt_add_reservemap_entry() 3662306a36Sopenharmony_ci * fdt_finish_reservemap() [moves to 'struct' state] 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_cistatic int fdt_sw_probe_memrsv_(void *fdt) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci int err = fdt_sw_probe_(fdt); 4162306a36Sopenharmony_ci if (err) 4262306a36Sopenharmony_ci return err; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0) 4562306a36Sopenharmony_ci return -FDT_ERR_BADSTATE; 4662306a36Sopenharmony_ci return 0; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define FDT_SW_PROBE_MEMRSV(fdt) \ 5062306a36Sopenharmony_ci { \ 5162306a36Sopenharmony_ci int err; \ 5262306a36Sopenharmony_ci if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \ 5362306a36Sopenharmony_ci return err; \ 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* 'struct' state: Enter this state after fdt_finish_reservemap() 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * Allowed functions: 5962306a36Sopenharmony_ci * fdt_begin_node() 6062306a36Sopenharmony_ci * fdt_end_node() 6162306a36Sopenharmony_ci * fdt_property*() 6262306a36Sopenharmony_ci * fdt_finish() [moves to 'complete' state] 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_cistatic int fdt_sw_probe_struct_(void *fdt) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci int err = fdt_sw_probe_(fdt); 6762306a36Sopenharmony_ci if (err) 6862306a36Sopenharmony_ci return err; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (!can_assume(VALID_INPUT) && 7162306a36Sopenharmony_ci fdt_off_dt_strings(fdt) != fdt_totalsize(fdt)) 7262306a36Sopenharmony_ci return -FDT_ERR_BADSTATE; 7362306a36Sopenharmony_ci return 0; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define FDT_SW_PROBE_STRUCT(fdt) \ 7762306a36Sopenharmony_ci { \ 7862306a36Sopenharmony_ci int err; \ 7962306a36Sopenharmony_ci if ((err = fdt_sw_probe_struct_(fdt)) != 0) \ 8062306a36Sopenharmony_ci return err; \ 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistatic inline uint32_t sw_flags(void *fdt) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci /* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */ 8662306a36Sopenharmony_ci return fdt_last_comp_version(fdt); 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* 'complete' state: Enter this state after fdt_finish() 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * Allowed functions: none 9262306a36Sopenharmony_ci */ 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic void *fdt_grab_space_(void *fdt, size_t len) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci unsigned int offset = fdt_size_dt_struct(fdt); 9762306a36Sopenharmony_ci unsigned int spaceleft; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) 10062306a36Sopenharmony_ci - fdt_size_dt_strings(fdt); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci if ((offset + len < offset) || (offset + len > spaceleft)) 10362306a36Sopenharmony_ci return NULL; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci fdt_set_size_dt_struct(fdt, offset + len); 10662306a36Sopenharmony_ci return fdt_offset_ptr_w_(fdt, offset); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciint fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci const int hdrsize = FDT_ALIGN(sizeof(struct fdt_header), 11262306a36Sopenharmony_ci sizeof(struct fdt_reserve_entry)); 11362306a36Sopenharmony_ci void *fdt = buf; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if (bufsize < hdrsize) 11662306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (flags & ~FDT_CREATE_FLAGS_ALL) 11962306a36Sopenharmony_ci return -FDT_ERR_BADFLAGS; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci memset(buf, 0, bufsize); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* 12462306a36Sopenharmony_ci * magic and last_comp_version keep intermediate state during the fdt 12562306a36Sopenharmony_ci * creation process, which is replaced with the proper FDT format by 12662306a36Sopenharmony_ci * fdt_finish(). 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * flags should be accessed with sw_flags(). 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci fdt_set_magic(fdt, FDT_SW_MAGIC); 13162306a36Sopenharmony_ci fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); 13262306a36Sopenharmony_ci fdt_set_last_comp_version(fdt, flags); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci fdt_set_totalsize(fdt, bufsize); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci fdt_set_off_mem_rsvmap(fdt, hdrsize); 13762306a36Sopenharmony_ci fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); 13862306a36Sopenharmony_ci fdt_set_off_dt_strings(fdt, 0); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci return 0; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ciint fdt_create(void *buf, int bufsize) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci return fdt_create_with_flags(buf, bufsize, 0); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ciint fdt_resize(void *fdt, void *buf, int bufsize) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci size_t headsize, tailsize; 15162306a36Sopenharmony_ci char *oldtail, *newtail; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci FDT_SW_PROBE(fdt); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (bufsize < 0) 15662306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); 15962306a36Sopenharmony_ci tailsize = fdt_size_dt_strings(fdt); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci if (!can_assume(VALID_DTB) && 16262306a36Sopenharmony_ci headsize + tailsize > fdt_totalsize(fdt)) 16362306a36Sopenharmony_ci return -FDT_ERR_INTERNAL; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci if ((headsize + tailsize) > (unsigned)bufsize) 16662306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize; 16962306a36Sopenharmony_ci newtail = (char *)buf + bufsize - tailsize; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* Two cases to avoid clobbering data if the old and new 17262306a36Sopenharmony_ci * buffers partially overlap */ 17362306a36Sopenharmony_ci if (buf <= fdt) { 17462306a36Sopenharmony_ci memmove(buf, fdt, headsize); 17562306a36Sopenharmony_ci memmove(newtail, oldtail, tailsize); 17662306a36Sopenharmony_ci } else { 17762306a36Sopenharmony_ci memmove(newtail, oldtail, tailsize); 17862306a36Sopenharmony_ci memmove(buf, fdt, headsize); 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci fdt_set_totalsize(buf, bufsize); 18262306a36Sopenharmony_ci if (fdt_off_dt_strings(buf)) 18362306a36Sopenharmony_ci fdt_set_off_dt_strings(buf, bufsize); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci return 0; 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciint fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci struct fdt_reserve_entry *re; 19162306a36Sopenharmony_ci int offset; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci FDT_SW_PROBE_MEMRSV(fdt); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci offset = fdt_off_dt_struct(fdt); 19662306a36Sopenharmony_ci if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) 19762306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci re = (struct fdt_reserve_entry *)((char *)fdt + offset); 20062306a36Sopenharmony_ci re->address = cpu_to_fdt64(addr); 20162306a36Sopenharmony_ci re->size = cpu_to_fdt64(size); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ciint fdt_finish_reservemap(void *fdt) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci int err = fdt_add_reservemap_entry(fdt, 0, 0); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci if (err) 21362306a36Sopenharmony_ci return err; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt)); 21662306a36Sopenharmony_ci return 0; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ciint fdt_begin_node(void *fdt, const char *name) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci struct fdt_node_header *nh; 22262306a36Sopenharmony_ci int namelen; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci FDT_SW_PROBE_STRUCT(fdt); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci namelen = strlen(name) + 1; 22762306a36Sopenharmony_ci nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); 22862306a36Sopenharmony_ci if (! nh) 22962306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); 23262306a36Sopenharmony_ci memcpy(nh->name, name, namelen); 23362306a36Sopenharmony_ci return 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciint fdt_end_node(void *fdt) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci fdt32_t *en; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci FDT_SW_PROBE_STRUCT(fdt); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci en = fdt_grab_space_(fdt, FDT_TAGSIZE); 24362306a36Sopenharmony_ci if (! en) 24462306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci *en = cpu_to_fdt32(FDT_END_NODE); 24762306a36Sopenharmony_ci return 0; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic int fdt_add_string_(void *fdt, const char *s) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci char *strtab = (char *)fdt + fdt_totalsize(fdt); 25362306a36Sopenharmony_ci unsigned int strtabsize = fdt_size_dt_strings(fdt); 25462306a36Sopenharmony_ci unsigned int len = strlen(s) + 1; 25562306a36Sopenharmony_ci unsigned int struct_top, offset; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci offset = strtabsize + len; 25862306a36Sopenharmony_ci struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); 25962306a36Sopenharmony_ci if (fdt_totalsize(fdt) - offset < struct_top) 26062306a36Sopenharmony_ci return 0; /* no more room :( */ 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci memcpy(strtab - offset, s, len); 26362306a36Sopenharmony_ci fdt_set_size_dt_strings(fdt, strtabsize + len); 26462306a36Sopenharmony_ci return -offset; 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/* Must only be used to roll back in case of error */ 26862306a36Sopenharmony_cistatic void fdt_del_last_string_(void *fdt, const char *s) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci int strtabsize = fdt_size_dt_strings(fdt); 27162306a36Sopenharmony_ci int len = strlen(s) + 1; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci fdt_set_size_dt_strings(fdt, strtabsize - len); 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic int fdt_find_add_string_(void *fdt, const char *s, int *allocated) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci char *strtab = (char *)fdt + fdt_totalsize(fdt); 27962306a36Sopenharmony_ci int strtabsize = fdt_size_dt_strings(fdt); 28062306a36Sopenharmony_ci const char *p; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci *allocated = 0; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci p = fdt_find_string_(strtab - strtabsize, strtabsize, s); 28562306a36Sopenharmony_ci if (p) 28662306a36Sopenharmony_ci return p - strtab; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci *allocated = 1; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci return fdt_add_string_(fdt, s); 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ciint fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci struct fdt_property *prop; 29662306a36Sopenharmony_ci int nameoff; 29762306a36Sopenharmony_ci int allocated; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci FDT_SW_PROBE_STRUCT(fdt); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci /* String de-duplication can be slow, _NO_NAME_DEDUP skips it */ 30262306a36Sopenharmony_ci if (sw_flags(fdt) & FDT_CREATE_FLAG_NO_NAME_DEDUP) { 30362306a36Sopenharmony_ci allocated = 1; 30462306a36Sopenharmony_ci nameoff = fdt_add_string_(fdt, name); 30562306a36Sopenharmony_ci } else { 30662306a36Sopenharmony_ci nameoff = fdt_find_add_string_(fdt, name, &allocated); 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci if (nameoff == 0) 30962306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); 31262306a36Sopenharmony_ci if (! prop) { 31362306a36Sopenharmony_ci if (allocated) 31462306a36Sopenharmony_ci fdt_del_last_string_(fdt, name); 31562306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci prop->tag = cpu_to_fdt32(FDT_PROP); 31962306a36Sopenharmony_ci prop->nameoff = cpu_to_fdt32(nameoff); 32062306a36Sopenharmony_ci prop->len = cpu_to_fdt32(len); 32162306a36Sopenharmony_ci *valp = prop->data; 32262306a36Sopenharmony_ci return 0; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ciint fdt_property(void *fdt, const char *name, const void *val, int len) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci void *ptr; 32862306a36Sopenharmony_ci int ret; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci ret = fdt_property_placeholder(fdt, name, len, &ptr); 33162306a36Sopenharmony_ci if (ret) 33262306a36Sopenharmony_ci return ret; 33362306a36Sopenharmony_ci memcpy(ptr, val, len); 33462306a36Sopenharmony_ci return 0; 33562306a36Sopenharmony_ci} 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ciint fdt_finish(void *fdt) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci char *p = (char *)fdt; 34062306a36Sopenharmony_ci fdt32_t *end; 34162306a36Sopenharmony_ci int oldstroffset, newstroffset; 34262306a36Sopenharmony_ci uint32_t tag; 34362306a36Sopenharmony_ci int offset, nextoffset; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci FDT_SW_PROBE_STRUCT(fdt); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci /* Add terminator */ 34862306a36Sopenharmony_ci end = fdt_grab_space_(fdt, sizeof(*end)); 34962306a36Sopenharmony_ci if (! end) 35062306a36Sopenharmony_ci return -FDT_ERR_NOSPACE; 35162306a36Sopenharmony_ci *end = cpu_to_fdt32(FDT_END); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci /* Relocate the string table */ 35462306a36Sopenharmony_ci oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); 35562306a36Sopenharmony_ci newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); 35662306a36Sopenharmony_ci memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); 35762306a36Sopenharmony_ci fdt_set_off_dt_strings(fdt, newstroffset); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* Walk the structure, correcting string offsets */ 36062306a36Sopenharmony_ci offset = 0; 36162306a36Sopenharmony_ci while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { 36262306a36Sopenharmony_ci if (tag == FDT_PROP) { 36362306a36Sopenharmony_ci struct fdt_property *prop = 36462306a36Sopenharmony_ci fdt_offset_ptr_w_(fdt, offset); 36562306a36Sopenharmony_ci int nameoff; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci nameoff = fdt32_to_cpu(prop->nameoff); 36862306a36Sopenharmony_ci nameoff += fdt_size_dt_strings(fdt); 36962306a36Sopenharmony_ci prop->nameoff = cpu_to_fdt32(nameoff); 37062306a36Sopenharmony_ci } 37162306a36Sopenharmony_ci offset = nextoffset; 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci if (nextoffset < 0) 37462306a36Sopenharmony_ci return nextoffset; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci /* Finally, adjust the header */ 37762306a36Sopenharmony_ci fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci /* And fix up fields that were keeping intermediate state. */ 38062306a36Sopenharmony_ci fdt_set_last_comp_version(fdt, FDT_LAST_COMPATIBLE_VERSION); 38162306a36Sopenharmony_ci fdt_set_magic(fdt, FDT_MAGIC); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci return 0; 38462306a36Sopenharmony_ci} 385