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