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