xref: /arm-trusted-firmware/lib/libfdt/fdt_wip.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
2*91f16700Schasinglulu /*
3*91f16700Schasinglulu  * libfdt - Flat Device Tree manipulation
4*91f16700Schasinglulu  * Copyright (C) 2006 David Gibson, IBM Corporation.
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu #include "libfdt_env.h"
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <fdt.h>
9*91f16700Schasinglulu #include <libfdt.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include "libfdt_internal.h"
12*91f16700Schasinglulu 
13*91f16700Schasinglulu int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
14*91f16700Schasinglulu 					const char *name, int namelen,
15*91f16700Schasinglulu 					uint32_t idx, const void *val,
16*91f16700Schasinglulu 					int len)
17*91f16700Schasinglulu {
18*91f16700Schasinglulu 	void *propval;
19*91f16700Schasinglulu 	int proplen;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu 	propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
22*91f16700Schasinglulu 					&proplen);
23*91f16700Schasinglulu 	if (!propval)
24*91f16700Schasinglulu 		return proplen;
25*91f16700Schasinglulu 
26*91f16700Schasinglulu 	if ((unsigned)proplen < (len + idx))
27*91f16700Schasinglulu 		return -FDT_ERR_NOSPACE;
28*91f16700Schasinglulu 
29*91f16700Schasinglulu 	memcpy((char *)propval + idx, val, len);
30*91f16700Schasinglulu 	return 0;
31*91f16700Schasinglulu }
32*91f16700Schasinglulu 
33*91f16700Schasinglulu int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
34*91f16700Schasinglulu 			const void *val, int len)
35*91f16700Schasinglulu {
36*91f16700Schasinglulu 	const void *propval;
37*91f16700Schasinglulu 	int proplen;
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
40*91f16700Schasinglulu 	if (!propval)
41*91f16700Schasinglulu 		return proplen;
42*91f16700Schasinglulu 
43*91f16700Schasinglulu 	if (proplen != len)
44*91f16700Schasinglulu 		return -FDT_ERR_NOSPACE;
45*91f16700Schasinglulu 
46*91f16700Schasinglulu 	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
47*91f16700Schasinglulu 						   strlen(name), 0,
48*91f16700Schasinglulu 						   val, len);
49*91f16700Schasinglulu }
50*91f16700Schasinglulu 
51*91f16700Schasinglulu static void fdt_nop_region_(void *start, int len)
52*91f16700Schasinglulu {
53*91f16700Schasinglulu 	fdt32_t *p;
54*91f16700Schasinglulu 
55*91f16700Schasinglulu 	for (p = start; (char *)p < ((char *)start + len); p++)
56*91f16700Schasinglulu 		*p = cpu_to_fdt32(FDT_NOP);
57*91f16700Schasinglulu }
58*91f16700Schasinglulu 
59*91f16700Schasinglulu int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
60*91f16700Schasinglulu {
61*91f16700Schasinglulu 	struct fdt_property *prop;
62*91f16700Schasinglulu 	int len;
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
65*91f16700Schasinglulu 	if (!prop)
66*91f16700Schasinglulu 		return len;
67*91f16700Schasinglulu 
68*91f16700Schasinglulu 	fdt_nop_region_(prop, len + sizeof(*prop));
69*91f16700Schasinglulu 
70*91f16700Schasinglulu 	return 0;
71*91f16700Schasinglulu }
72*91f16700Schasinglulu 
73*91f16700Schasinglulu int fdt_node_end_offset_(void *fdt, int offset)
74*91f16700Schasinglulu {
75*91f16700Schasinglulu 	int depth = 0;
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 	while ((offset >= 0) && (depth >= 0))
78*91f16700Schasinglulu 		offset = fdt_next_node(fdt, offset, &depth);
79*91f16700Schasinglulu 
80*91f16700Schasinglulu 	return offset;
81*91f16700Schasinglulu }
82*91f16700Schasinglulu 
83*91f16700Schasinglulu int fdt_nop_node(void *fdt, int nodeoffset)
84*91f16700Schasinglulu {
85*91f16700Schasinglulu 	int endoffset;
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
88*91f16700Schasinglulu 	if (endoffset < 0)
89*91f16700Schasinglulu 		return endoffset;
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
92*91f16700Schasinglulu 			endoffset - nodeoffset);
93*91f16700Schasinglulu 	return 0;
94*91f16700Schasinglulu }
95