xref: /optee_os/core/lib/libfdt/fdt_wip.c (revision 17f326eba66aab9ea16549754a95252dd5551a13)
1*17f326ebSJerome Forissier // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
2b908c675SJens Wiklander /*
3b908c675SJens Wiklander  * libfdt - Flat Device Tree manipulation
4b908c675SJens Wiklander  * Copyright (C) 2006 David Gibson, IBM Corporation.
5b908c675SJens Wiklander  */
6b908c675SJens Wiklander #include "libfdt_env.h"
7b908c675SJens Wiklander 
8b908c675SJens Wiklander #include <fdt.h>
9b908c675SJens Wiklander #include <libfdt.h>
10b908c675SJens Wiklander 
11b908c675SJens Wiklander #include "libfdt_internal.h"
12b908c675SJens Wiklander 
fdt_setprop_inplace_namelen_partial(void * fdt,int nodeoffset,const char * name,int namelen,uint32_t idx,const void * val,int len)1301d6a9daSBryan O'Donoghue int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
1401d6a9daSBryan O'Donoghue 					const char *name, int namelen,
1501d6a9daSBryan O'Donoghue 					uint32_t idx, const void *val,
1601d6a9daSBryan O'Donoghue 					int len)
17b908c675SJens Wiklander {
18b908c675SJens Wiklander 	void *propval;
19b908c675SJens Wiklander 	int proplen;
20b908c675SJens Wiklander 
2101d6a9daSBryan O'Donoghue 	propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
2201d6a9daSBryan O'Donoghue 					&proplen);
2301d6a9daSBryan O'Donoghue 	if (!propval)
2401d6a9daSBryan O'Donoghue 		return proplen;
2501d6a9daSBryan O'Donoghue 
2601d6a9daSBryan O'Donoghue 	if (proplen < (len + idx))
2701d6a9daSBryan O'Donoghue 		return -FDT_ERR_NOSPACE;
2801d6a9daSBryan O'Donoghue 
2901d6a9daSBryan O'Donoghue 	memcpy((char *)propval + idx, val, len);
3001d6a9daSBryan O'Donoghue 	return 0;
3101d6a9daSBryan O'Donoghue }
3201d6a9daSBryan O'Donoghue 
fdt_setprop_inplace(void * fdt,int nodeoffset,const char * name,const void * val,int len)3301d6a9daSBryan O'Donoghue int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
3401d6a9daSBryan O'Donoghue 			const void *val, int len)
3501d6a9daSBryan O'Donoghue {
3601d6a9daSBryan O'Donoghue 	const void *propval;
3701d6a9daSBryan O'Donoghue 	int proplen;
3801d6a9daSBryan O'Donoghue 
3901d6a9daSBryan O'Donoghue 	propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
40b908c675SJens Wiklander 	if (!propval)
41b908c675SJens Wiklander 		return proplen;
42b908c675SJens Wiklander 
43b908c675SJens Wiklander 	if (proplen != len)
44b908c675SJens Wiklander 		return -FDT_ERR_NOSPACE;
45b908c675SJens Wiklander 
4601d6a9daSBryan O'Donoghue 	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
4701d6a9daSBryan O'Donoghue 						   strlen(name), 0,
4801d6a9daSBryan O'Donoghue 						   val, len);
49b908c675SJens Wiklander }
50b908c675SJens Wiklander 
fdt_nop_region_(void * start,int len)5101d6a9daSBryan O'Donoghue static void fdt_nop_region_(void *start, int len)
52b908c675SJens Wiklander {
53b908c675SJens Wiklander 	fdt32_t *p;
54b908c675SJens Wiklander 
55b908c675SJens Wiklander 	for (p = start; (char *)p < ((char *)start + len); p++)
56b908c675SJens Wiklander 		*p = cpu_to_fdt32(FDT_NOP);
57b908c675SJens Wiklander }
58b908c675SJens Wiklander 
fdt_nop_property(void * fdt,int nodeoffset,const char * name)59b908c675SJens Wiklander int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
60b908c675SJens Wiklander {
61b908c675SJens Wiklander 	struct fdt_property *prop;
62b908c675SJens Wiklander 	int len;
63b908c675SJens Wiklander 
64b908c675SJens Wiklander 	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
65b908c675SJens Wiklander 	if (!prop)
66b908c675SJens Wiklander 		return len;
67b908c675SJens Wiklander 
6801d6a9daSBryan O'Donoghue 	fdt_nop_region_(prop, len + sizeof(*prop));
69b908c675SJens Wiklander 
70b908c675SJens Wiklander 	return 0;
71b908c675SJens Wiklander }
72b908c675SJens Wiklander 
fdt_node_end_offset_(void * fdt,int offset)7301d6a9daSBryan O'Donoghue int fdt_node_end_offset_(void *fdt, int offset)
74b908c675SJens Wiklander {
75b908c675SJens Wiklander 	int depth = 0;
76b908c675SJens Wiklander 
77b908c675SJens Wiklander 	while ((offset >= 0) && (depth >= 0))
78b908c675SJens Wiklander 		offset = fdt_next_node(fdt, offset, &depth);
79b908c675SJens Wiklander 
80b908c675SJens Wiklander 	return offset;
81b908c675SJens Wiklander }
82b908c675SJens Wiklander 
fdt_nop_node(void * fdt,int nodeoffset)83b908c675SJens Wiklander int fdt_nop_node(void *fdt, int nodeoffset)
84b908c675SJens Wiklander {
85b908c675SJens Wiklander 	int endoffset;
86b908c675SJens Wiklander 
8701d6a9daSBryan O'Donoghue 	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
88b908c675SJens Wiklander 	if (endoffset < 0)
89b908c675SJens Wiklander 		return endoffset;
90b908c675SJens Wiklander 
9101d6a9daSBryan O'Donoghue 	fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
92b908c675SJens Wiklander 			endoffset - nodeoffset);
93b908c675SJens Wiklander 	return 0;
94b908c675SJens Wiklander }
95