diff options
Diffstat (limited to 'arch/powerpc/boot/libfdt/fdt_rw.c')
-rw-r--r-- | arch/powerpc/boot/libfdt/fdt_rw.c | 200 |
1 files changed, 108 insertions, 92 deletions
diff --git a/arch/powerpc/boot/libfdt/fdt_rw.c b/arch/powerpc/boot/libfdt/fdt_rw.c index 6673f8ec962a..8e7ec4cb7bcd 100644 --- a/arch/powerpc/boot/libfdt/fdt_rw.c +++ b/arch/powerpc/boot/libfdt/fdt_rw.c | |||
@@ -55,10 +55,10 @@ | |||
55 | 55 | ||
56 | #include "libfdt_internal.h" | 56 | #include "libfdt_internal.h" |
57 | 57 | ||
58 | static int _blocks_misordered(const void *fdt, | 58 | static int _fdt_blocks_misordered(const void *fdt, |
59 | int mem_rsv_size, int struct_size) | 59 | int mem_rsv_size, int struct_size) |
60 | { | 60 | { |
61 | return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8)) | 61 | return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) |
62 | || (fdt_off_dt_struct(fdt) < | 62 | || (fdt_off_dt_struct(fdt) < |
63 | (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) | 63 | (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) |
64 | || (fdt_off_dt_strings(fdt) < | 64 | || (fdt_off_dt_strings(fdt) < |
@@ -67,16 +67,14 @@ static int _blocks_misordered(const void *fdt, | |||
67 | (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); | 67 | (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); |
68 | } | 68 | } |
69 | 69 | ||
70 | static int rw_check_header(void *fdt) | 70 | static int _fdt_rw_check_header(void *fdt) |
71 | { | 71 | { |
72 | int err; | 72 | FDT_CHECK_HEADER(fdt); |
73 | 73 | ||
74 | if ((err = fdt_check_header(fdt))) | ||
75 | return err; | ||
76 | if (fdt_version(fdt) < 17) | 74 | if (fdt_version(fdt) < 17) |
77 | return -FDT_ERR_BADVERSION; | 75 | return -FDT_ERR_BADVERSION; |
78 | if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), | 76 | if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), |
79 | fdt_size_dt_struct(fdt))) | 77 | fdt_size_dt_struct(fdt))) |
80 | return -FDT_ERR_BADLAYOUT; | 78 | return -FDT_ERR_BADLAYOUT; |
81 | if (fdt_version(fdt) > 17) | 79 | if (fdt_version(fdt) > 17) |
82 | fdt_set_version(fdt, 17); | 80 | fdt_set_version(fdt, 17); |
@@ -84,36 +82,37 @@ static int rw_check_header(void *fdt) | |||
84 | return 0; | 82 | return 0; |
85 | } | 83 | } |
86 | 84 | ||
87 | #define RW_CHECK_HEADER(fdt) \ | 85 | #define FDT_RW_CHECK_HEADER(fdt) \ |
88 | { \ | 86 | { \ |
89 | int err; \ | 87 | int err; \ |
90 | if ((err = rw_check_header(fdt)) != 0) \ | 88 | if ((err = _fdt_rw_check_header(fdt)) != 0) \ |
91 | return err; \ | 89 | return err; \ |
92 | } | 90 | } |
93 | 91 | ||
94 | static inline int _blob_data_size(void *fdt) | 92 | static inline int _fdt_data_size(void *fdt) |
95 | { | 93 | { |
96 | return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); | 94 | return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); |
97 | } | 95 | } |
98 | 96 | ||
99 | static int _blob_splice(void *fdt, void *p, int oldlen, int newlen) | 97 | static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) |
100 | { | 98 | { |
101 | void *end = fdt + _blob_data_size(fdt); | 99 | char *p = splicepoint; |
100 | char *end = (char *)fdt + _fdt_data_size(fdt); | ||
102 | 101 | ||
103 | if (((p + oldlen) < p) || ((p + oldlen) > end)) | 102 | if (((p + oldlen) < p) || ((p + oldlen) > end)) |
104 | return -FDT_ERR_BADOFFSET; | 103 | return -FDT_ERR_BADOFFSET; |
105 | if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt))) | 104 | if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) |
106 | return -FDT_ERR_NOSPACE; | 105 | return -FDT_ERR_NOSPACE; |
107 | memmove(p + newlen, p + oldlen, end - p - oldlen); | 106 | memmove(p + newlen, p + oldlen, end - p - oldlen); |
108 | return 0; | 107 | return 0; |
109 | } | 108 | } |
110 | 109 | ||
111 | static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, | 110 | static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, |
112 | int oldn, int newn) | 111 | int oldn, int newn) |
113 | { | 112 | { |
114 | int delta = (newn - oldn) * sizeof(*p); | 113 | int delta = (newn - oldn) * sizeof(*p); |
115 | int err; | 114 | int err; |
116 | err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); | 115 | err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); |
117 | if (err) | 116 | if (err) |
118 | return err; | 117 | return err; |
119 | fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); | 118 | fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); |
@@ -121,13 +120,13 @@ static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, | |||
121 | return 0; | 120 | return 0; |
122 | } | 121 | } |
123 | 122 | ||
124 | static int _blob_splice_struct(void *fdt, void *p, | 123 | static int _fdt_splice_struct(void *fdt, void *p, |
125 | int oldlen, int newlen) | 124 | int oldlen, int newlen) |
126 | { | 125 | { |
127 | int delta = newlen - oldlen; | 126 | int delta = newlen - oldlen; |
128 | int err; | 127 | int err; |
129 | 128 | ||
130 | if ((err = _blob_splice(fdt, p, oldlen, newlen))) | 129 | if ((err = _fdt_splice(fdt, p, oldlen, newlen))) |
131 | return err; | 130 | return err; |
132 | 131 | ||
133 | fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); | 132 | fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); |
@@ -135,19 +134,20 @@ static int _blob_splice_struct(void *fdt, void *p, | |||
135 | return 0; | 134 | return 0; |
136 | } | 135 | } |
137 | 136 | ||
138 | static int _blob_splice_string(void *fdt, int newlen) | 137 | static int _fdt_splice_string(void *fdt, int newlen) |
139 | { | 138 | { |
140 | void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); | 139 | void *p = (char *)fdt |
140 | + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); | ||
141 | int err; | 141 | int err; |
142 | 142 | ||
143 | if ((err = _blob_splice(fdt, p, 0, newlen))) | 143 | if ((err = _fdt_splice(fdt, p, 0, newlen))) |
144 | return err; | 144 | return err; |
145 | 145 | ||
146 | fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); | 146 | fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int _find_add_string(void *fdt, const char *s) | 150 | static int _fdt_find_add_string(void *fdt, const char *s) |
151 | { | 151 | { |
152 | char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); | 152 | char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); |
153 | const char *p; | 153 | const char *p; |
@@ -161,7 +161,7 @@ static int _find_add_string(void *fdt, const char *s) | |||
161 | return (p - strtab); | 161 | return (p - strtab); |
162 | 162 | ||
163 | new = strtab + fdt_size_dt_strings(fdt); | 163 | new = strtab + fdt_size_dt_strings(fdt); |
164 | err = _blob_splice_string(fdt, len); | 164 | err = _fdt_splice_string(fdt, len); |
165 | if (err) | 165 | if (err) |
166 | return err; | 166 | return err; |
167 | 167 | ||
@@ -174,11 +174,10 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) | |||
174 | struct fdt_reserve_entry *re; | 174 | struct fdt_reserve_entry *re; |
175 | int err; | 175 | int err; |
176 | 176 | ||
177 | if ((err = rw_check_header(fdt))) | 177 | FDT_RW_CHECK_HEADER(fdt); |
178 | return err; | ||
179 | 178 | ||
180 | re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); | 179 | re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); |
181 | err = _blob_splice_mem_rsv(fdt, re, 0, 1); | 180 | err = _fdt_splice_mem_rsv(fdt, re, 0, 1); |
182 | if (err) | 181 | if (err) |
183 | return err; | 182 | return err; |
184 | 183 | ||
@@ -192,19 +191,19 @@ int fdt_del_mem_rsv(void *fdt, int n) | |||
192 | struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); | 191 | struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); |
193 | int err; | 192 | int err; |
194 | 193 | ||
195 | if ((err = rw_check_header(fdt))) | 194 | FDT_RW_CHECK_HEADER(fdt); |
196 | return err; | 195 | |
197 | if (n >= fdt_num_mem_rsv(fdt)) | 196 | if (n >= fdt_num_mem_rsv(fdt)) |
198 | return -FDT_ERR_NOTFOUND; | 197 | return -FDT_ERR_NOTFOUND; |
199 | 198 | ||
200 | err = _blob_splice_mem_rsv(fdt, re, 1, 0); | 199 | err = _fdt_splice_mem_rsv(fdt, re, 1, 0); |
201 | if (err) | 200 | if (err) |
202 | return err; | 201 | return err; |
203 | return 0; | 202 | return 0; |
204 | } | 203 | } |
205 | 204 | ||
206 | static int _resize_property(void *fdt, int nodeoffset, const char *name, int len, | 205 | static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, |
207 | struct fdt_property **prop) | 206 | int len, struct fdt_property **prop) |
208 | { | 207 | { |
209 | int oldlen; | 208 | int oldlen; |
210 | int err; | 209 | int err; |
@@ -213,36 +212,33 @@ static int _resize_property(void *fdt, int nodeoffset, const char *name, int len | |||
213 | if (! (*prop)) | 212 | if (! (*prop)) |
214 | return oldlen; | 213 | return oldlen; |
215 | 214 | ||
216 | if ((err = _blob_splice_struct(fdt, (*prop)->data, | 215 | if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), |
217 | ALIGN(oldlen, FDT_TAGSIZE), | 216 | FDT_TAGALIGN(len)))) |
218 | ALIGN(len, FDT_TAGSIZE)))) | ||
219 | return err; | 217 | return err; |
220 | 218 | ||
221 | (*prop)->len = cpu_to_fdt32(len); | 219 | (*prop)->len = cpu_to_fdt32(len); |
222 | return 0; | 220 | return 0; |
223 | } | 221 | } |
224 | 222 | ||
225 | static int _add_property(void *fdt, int nodeoffset, const char *name, int len, | 223 | static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, |
226 | struct fdt_property **prop) | 224 | int len, struct fdt_property **prop) |
227 | { | 225 | { |
228 | uint32_t tag; | ||
229 | int proplen; | 226 | int proplen; |
230 | int nextoffset; | 227 | int nextoffset; |
231 | int namestroff; | 228 | int namestroff; |
232 | int err; | 229 | int err; |
233 | 230 | ||
234 | tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); | 231 | if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) |
235 | if (tag != FDT_BEGIN_NODE) | 232 | return nextoffset; |
236 | return -FDT_ERR_BADOFFSET; | ||
237 | 233 | ||
238 | namestroff = _find_add_string(fdt, name); | 234 | namestroff = _fdt_find_add_string(fdt, name); |
239 | if (namestroff < 0) | 235 | if (namestroff < 0) |
240 | return namestroff; | 236 | return namestroff; |
241 | 237 | ||
242 | *prop = _fdt_offset_ptr_w(fdt, nextoffset); | 238 | *prop = _fdt_offset_ptr_w(fdt, nextoffset); |
243 | proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE); | 239 | proplen = sizeof(**prop) + FDT_TAGALIGN(len); |
244 | 240 | ||
245 | err = _blob_splice_struct(fdt, *prop, 0, proplen); | 241 | err = _fdt_splice_struct(fdt, *prop, 0, proplen); |
246 | if (err) | 242 | if (err) |
247 | return err; | 243 | return err; |
248 | 244 | ||
@@ -252,18 +248,40 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len, | |||
252 | return 0; | 248 | return 0; |
253 | } | 249 | } |
254 | 250 | ||
251 | int fdt_set_name(void *fdt, int nodeoffset, const char *name) | ||
252 | { | ||
253 | char *namep; | ||
254 | int oldlen, newlen; | ||
255 | int err; | ||
256 | |||
257 | FDT_RW_CHECK_HEADER(fdt); | ||
258 | |||
259 | namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); | ||
260 | if (!namep) | ||
261 | return oldlen; | ||
262 | |||
263 | newlen = strlen(name); | ||
264 | |||
265 | err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), | ||
266 | FDT_TAGALIGN(newlen+1)); | ||
267 | if (err) | ||
268 | return err; | ||
269 | |||
270 | memcpy(namep, name, newlen+1); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
255 | int fdt_setprop(void *fdt, int nodeoffset, const char *name, | 274 | int fdt_setprop(void *fdt, int nodeoffset, const char *name, |
256 | const void *val, int len) | 275 | const void *val, int len) |
257 | { | 276 | { |
258 | struct fdt_property *prop; | 277 | struct fdt_property *prop; |
259 | int err; | 278 | int err; |
260 | 279 | ||
261 | if ((err = rw_check_header(fdt))) | 280 | FDT_RW_CHECK_HEADER(fdt); |
262 | return err; | ||
263 | 281 | ||
264 | err = _resize_property(fdt, nodeoffset, name, len, &prop); | 282 | err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); |
265 | if (err == -FDT_ERR_NOTFOUND) | 283 | if (err == -FDT_ERR_NOTFOUND) |
266 | err = _add_property(fdt, nodeoffset, name, len, &prop); | 284 | err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); |
267 | if (err) | 285 | if (err) |
268 | return err; | 286 | return err; |
269 | 287 | ||
@@ -276,14 +294,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) | |||
276 | struct fdt_property *prop; | 294 | struct fdt_property *prop; |
277 | int len, proplen; | 295 | int len, proplen; |
278 | 296 | ||
279 | RW_CHECK_HEADER(fdt); | 297 | FDT_RW_CHECK_HEADER(fdt); |
280 | 298 | ||
281 | prop = fdt_get_property_w(fdt, nodeoffset, name, &len); | 299 | prop = fdt_get_property_w(fdt, nodeoffset, name, &len); |
282 | if (! prop) | 300 | if (! prop) |
283 | return len; | 301 | return len; |
284 | 302 | ||
285 | proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE); | 303 | proplen = sizeof(*prop) + FDT_TAGALIGN(len); |
286 | return _blob_splice_struct(fdt, prop, proplen, 0); | 304 | return _fdt_splice_struct(fdt, prop, proplen, 0); |
287 | } | 305 | } |
288 | 306 | ||
289 | int fdt_add_subnode_namelen(void *fdt, int parentoffset, | 307 | int fdt_add_subnode_namelen(void *fdt, int parentoffset, |
@@ -296,7 +314,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, | |||
296 | uint32_t tag; | 314 | uint32_t tag; |
297 | uint32_t *endtag; | 315 | uint32_t *endtag; |
298 | 316 | ||
299 | RW_CHECK_HEADER(fdt); | 317 | FDT_RW_CHECK_HEADER(fdt); |
300 | 318 | ||
301 | offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); | 319 | offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); |
302 | if (offset >= 0) | 320 | if (offset >= 0) |
@@ -309,19 +327,19 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, | |||
309 | do { | 327 | do { |
310 | offset = nextoffset; | 328 | offset = nextoffset; |
311 | tag = fdt_next_tag(fdt, offset, &nextoffset); | 329 | tag = fdt_next_tag(fdt, offset, &nextoffset); |
312 | } while (tag == FDT_PROP); | 330 | } while ((tag == FDT_PROP) || (tag == FDT_NOP)); |
313 | 331 | ||
314 | nh = _fdt_offset_ptr_w(fdt, offset); | 332 | nh = _fdt_offset_ptr_w(fdt, offset); |
315 | nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; | 333 | nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; |
316 | 334 | ||
317 | err = _blob_splice_struct(fdt, nh, 0, nodelen); | 335 | err = _fdt_splice_struct(fdt, nh, 0, nodelen); |
318 | if (err) | 336 | if (err) |
319 | return err; | 337 | return err; |
320 | 338 | ||
321 | nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); | 339 | nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); |
322 | memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE)); | 340 | memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); |
323 | memcpy(nh->name, name, namelen); | 341 | memcpy(nh->name, name, namelen); |
324 | endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE); | 342 | endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE); |
325 | *endtag = cpu_to_fdt32(FDT_END_NODE); | 343 | *endtag = cpu_to_fdt32(FDT_END_NODE); |
326 | 344 | ||
327 | return offset; | 345 | return offset; |
@@ -336,36 +354,36 @@ int fdt_del_node(void *fdt, int nodeoffset) | |||
336 | { | 354 | { |
337 | int endoffset; | 355 | int endoffset; |
338 | 356 | ||
339 | RW_CHECK_HEADER(fdt); | 357 | FDT_RW_CHECK_HEADER(fdt); |
340 | 358 | ||
341 | endoffset = _fdt_node_end_offset(fdt, nodeoffset); | 359 | endoffset = _fdt_node_end_offset(fdt, nodeoffset); |
342 | if (endoffset < 0) | 360 | if (endoffset < 0) |
343 | return endoffset; | 361 | return endoffset; |
344 | 362 | ||
345 | return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), | 363 | return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), |
346 | endoffset - nodeoffset, 0); | 364 | endoffset - nodeoffset, 0); |
347 | } | 365 | } |
348 | 366 | ||
349 | static void _packblocks(const void *fdt, void *buf, | 367 | static void _fdt_packblocks(const char *old, char *new, |
350 | int mem_rsv_size, int struct_size) | 368 | int mem_rsv_size, int struct_size) |
351 | { | 369 | { |
352 | int mem_rsv_off, struct_off, strings_off; | 370 | int mem_rsv_off, struct_off, strings_off; |
353 | 371 | ||
354 | mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8); | 372 | mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); |
355 | struct_off = mem_rsv_off + mem_rsv_size; | 373 | struct_off = mem_rsv_off + mem_rsv_size; |
356 | strings_off = struct_off + struct_size; | 374 | strings_off = struct_off + struct_size; |
357 | 375 | ||
358 | memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size); | 376 | memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); |
359 | fdt_set_off_mem_rsvmap(buf, mem_rsv_off); | 377 | fdt_set_off_mem_rsvmap(new, mem_rsv_off); |
360 | 378 | ||
361 | memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size); | 379 | memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); |
362 | fdt_set_off_dt_struct(buf, struct_off); | 380 | fdt_set_off_dt_struct(new, struct_off); |
363 | fdt_set_size_dt_struct(buf, struct_size); | 381 | fdt_set_size_dt_struct(new, struct_size); |
364 | 382 | ||
365 | memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt), | 383 | memmove(new + strings_off, old + fdt_off_dt_strings(old), |
366 | fdt_size_dt_strings(fdt)); | 384 | fdt_size_dt_strings(old)); |
367 | fdt_set_off_dt_strings(buf, strings_off); | 385 | fdt_set_off_dt_strings(new, strings_off); |
368 | fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt)); | 386 | fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); |
369 | } | 387 | } |
370 | 388 | ||
371 | int fdt_open_into(const void *fdt, void *buf, int bufsize) | 389 | int fdt_open_into(const void *fdt, void *buf, int bufsize) |
@@ -373,11 +391,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) | |||
373 | int err; | 391 | int err; |
374 | int mem_rsv_size, struct_size; | 392 | int mem_rsv_size, struct_size; |
375 | int newsize; | 393 | int newsize; |
376 | void *tmp; | 394 | const char *fdtstart = fdt; |
395 | const char *fdtend = fdtstart + fdt_totalsize(fdt); | ||
396 | char *tmp; | ||
377 | 397 | ||
378 | err = fdt_check_header(fdt); | 398 | FDT_CHECK_HEADER(fdt); |
379 | if (err) | ||
380 | return err; | ||
381 | 399 | ||
382 | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | 400 | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) |
383 | * sizeof(struct fdt_reserve_entry); | 401 | * sizeof(struct fdt_reserve_entry); |
@@ -390,7 +408,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) | |||
390 | ; | 408 | ; |
391 | } | 409 | } |
392 | 410 | ||
393 | if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) { | 411 | if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { |
394 | /* no further work necessary */ | 412 | /* no further work necessary */ |
395 | err = fdt_move(fdt, buf, bufsize); | 413 | err = fdt_move(fdt, buf, bufsize); |
396 | if (err) | 414 | if (err) |
@@ -402,22 +420,23 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) | |||
402 | } | 420 | } |
403 | 421 | ||
404 | /* Need to reorder */ | 422 | /* Need to reorder */ |
405 | newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size | 423 | newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size |
406 | + struct_size + fdt_size_dt_strings(fdt); | 424 | + struct_size + fdt_size_dt_strings(fdt); |
407 | 425 | ||
408 | if (bufsize < newsize) | 426 | if (bufsize < newsize) |
409 | return -FDT_ERR_NOSPACE; | 427 | return -FDT_ERR_NOSPACE; |
410 | 428 | ||
411 | if (((buf + newsize) <= fdt) | 429 | /* First attempt to build converted tree at beginning of buffer */ |
412 | || (buf >= (fdt + fdt_totalsize(fdt)))) { | 430 | tmp = buf; |
413 | tmp = buf; | 431 | /* But if that overlaps with the old tree... */ |
414 | } else { | 432 | if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { |
415 | tmp = (void *)fdt + fdt_totalsize(fdt); | 433 | /* Try right after the old tree instead */ |
416 | if ((tmp + newsize) > (buf + bufsize)) | 434 | tmp = (char *)(uintptr_t)fdtend; |
435 | if ((tmp + newsize) > ((char *)buf + bufsize)) | ||
417 | return -FDT_ERR_NOSPACE; | 436 | return -FDT_ERR_NOSPACE; |
418 | } | 437 | } |
419 | 438 | ||
420 | _packblocks(fdt, tmp, mem_rsv_size, struct_size); | 439 | _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); |
421 | memmove(buf, tmp, newsize); | 440 | memmove(buf, tmp, newsize); |
422 | 441 | ||
423 | fdt_set_magic(buf, FDT_MAGIC); | 442 | fdt_set_magic(buf, FDT_MAGIC); |
@@ -432,16 +451,13 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) | |||
432 | int fdt_pack(void *fdt) | 451 | int fdt_pack(void *fdt) |
433 | { | 452 | { |
434 | int mem_rsv_size; | 453 | int mem_rsv_size; |
435 | int err; | ||
436 | 454 | ||
437 | err = rw_check_header(fdt); | 455 | FDT_RW_CHECK_HEADER(fdt); |
438 | if (err) | ||
439 | return err; | ||
440 | 456 | ||
441 | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) | 457 | mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) |
442 | * sizeof(struct fdt_reserve_entry); | 458 | * sizeof(struct fdt_reserve_entry); |
443 | _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); | 459 | _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); |
444 | fdt_set_totalsize(fdt, _blob_data_size(fdt)); | 460 | fdt_set_totalsize(fdt, _fdt_data_size(fdt)); |
445 | 461 | ||
446 | return 0; | 462 | return 0; |
447 | } | 463 | } |