fdt_rw.c revision 1.1.1.3 1 1.1.1.2 skrll /* $NetBSD: fdt_rw.c,v 1.1.1.3 2019/12/22 12:30:37 skrll Exp $ */
2 1.1.1.2 skrll
3 1.1.1.3 skrll // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
4 1.1 macallan /*
5 1.1 macallan * libfdt - Flat Device Tree manipulation
6 1.1 macallan * Copyright (C) 2006 David Gibson, IBM Corporation.
7 1.1 macallan */
8 1.1 macallan #include "libfdt_env.h"
9 1.1 macallan
10 1.1 macallan #include <fdt.h>
11 1.1 macallan #include <libfdt.h>
12 1.1 macallan
13 1.1 macallan #include "libfdt_internal.h"
14 1.1 macallan
15 1.1.1.3 skrll static int fdt_blocks_misordered_(const void *fdt,
16 1.1.1.3 skrll int mem_rsv_size, int struct_size)
17 1.1 macallan {
18 1.1 macallan return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
19 1.1 macallan || (fdt_off_dt_struct(fdt) <
20 1.1 macallan (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
21 1.1 macallan || (fdt_off_dt_strings(fdt) <
22 1.1 macallan (fdt_off_dt_struct(fdt) + struct_size))
23 1.1 macallan || (fdt_totalsize(fdt) <
24 1.1 macallan (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
25 1.1 macallan }
26 1.1 macallan
27 1.1.1.3 skrll static int fdt_rw_probe_(void *fdt)
28 1.1 macallan {
29 1.1.1.3 skrll FDT_RO_PROBE(fdt);
30 1.1 macallan
31 1.1 macallan if (fdt_version(fdt) < 17)
32 1.1 macallan return -FDT_ERR_BADVERSION;
33 1.1.1.3 skrll if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
34 1.1 macallan fdt_size_dt_struct(fdt)))
35 1.1 macallan return -FDT_ERR_BADLAYOUT;
36 1.1 macallan if (fdt_version(fdt) > 17)
37 1.1 macallan fdt_set_version(fdt, 17);
38 1.1 macallan
39 1.1 macallan return 0;
40 1.1 macallan }
41 1.1 macallan
42 1.1.1.3 skrll #define FDT_RW_PROBE(fdt) \
43 1.1 macallan { \
44 1.1.1.3 skrll int err_; \
45 1.1.1.3 skrll if ((err_ = fdt_rw_probe_(fdt)) != 0) \
46 1.1.1.3 skrll return err_; \
47 1.1 macallan }
48 1.1 macallan
49 1.1.1.3 skrll static inline int fdt_data_size_(void *fdt)
50 1.1 macallan {
51 1.1 macallan return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
52 1.1 macallan }
53 1.1 macallan
54 1.1.1.3 skrll static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
55 1.1 macallan {
56 1.1 macallan char *p = splicepoint;
57 1.1.1.3 skrll char *end = (char *)fdt + fdt_data_size_(fdt);
58 1.1 macallan
59 1.1 macallan if (((p + oldlen) < p) || ((p + oldlen) > end))
60 1.1 macallan return -FDT_ERR_BADOFFSET;
61 1.1 macallan if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
62 1.1 macallan return -FDT_ERR_BADOFFSET;
63 1.1 macallan if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
64 1.1 macallan return -FDT_ERR_NOSPACE;
65 1.1 macallan memmove(p + newlen, p + oldlen, end - p - oldlen);
66 1.1 macallan return 0;
67 1.1 macallan }
68 1.1 macallan
69 1.1.1.3 skrll static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,
70 1.1 macallan int oldn, int newn)
71 1.1 macallan {
72 1.1 macallan int delta = (newn - oldn) * sizeof(*p);
73 1.1 macallan int err;
74 1.1.1.3 skrll err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
75 1.1 macallan if (err)
76 1.1 macallan return err;
77 1.1 macallan fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
78 1.1 macallan fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
79 1.1 macallan return 0;
80 1.1 macallan }
81 1.1 macallan
82 1.1.1.3 skrll static int fdt_splice_struct_(void *fdt, void *p,
83 1.1 macallan int oldlen, int newlen)
84 1.1 macallan {
85 1.1 macallan int delta = newlen - oldlen;
86 1.1 macallan int err;
87 1.1 macallan
88 1.1.1.3 skrll if ((err = fdt_splice_(fdt, p, oldlen, newlen)))
89 1.1 macallan return err;
90 1.1 macallan
91 1.1 macallan fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
92 1.1 macallan fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
93 1.1 macallan return 0;
94 1.1 macallan }
95 1.1 macallan
96 1.1.1.3 skrll /* Must only be used to roll back in case of error */
97 1.1.1.3 skrll static void fdt_del_last_string_(void *fdt, const char *s)
98 1.1.1.3 skrll {
99 1.1.1.3 skrll int newlen = strlen(s) + 1;
100 1.1.1.3 skrll
101 1.1.1.3 skrll fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - newlen);
102 1.1.1.3 skrll }
103 1.1.1.3 skrll
104 1.1.1.3 skrll static int fdt_splice_string_(void *fdt, int newlen)
105 1.1 macallan {
106 1.1 macallan void *p = (char *)fdt
107 1.1 macallan + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
108 1.1 macallan int err;
109 1.1 macallan
110 1.1.1.3 skrll if ((err = fdt_splice_(fdt, p, 0, newlen)))
111 1.1 macallan return err;
112 1.1 macallan
113 1.1 macallan fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
114 1.1 macallan return 0;
115 1.1 macallan }
116 1.1 macallan
117 1.1.1.3 skrll static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
118 1.1 macallan {
119 1.1 macallan char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
120 1.1 macallan const char *p;
121 1.1 macallan char *new;
122 1.1 macallan int len = strlen(s) + 1;
123 1.1 macallan int err;
124 1.1 macallan
125 1.1.1.3 skrll *allocated = 0;
126 1.1.1.3 skrll
127 1.1.1.3 skrll p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
128 1.1 macallan if (p)
129 1.1 macallan /* found it */
130 1.1 macallan return (p - strtab);
131 1.1 macallan
132 1.1 macallan new = strtab + fdt_size_dt_strings(fdt);
133 1.1.1.3 skrll err = fdt_splice_string_(fdt, len);
134 1.1 macallan if (err)
135 1.1 macallan return err;
136 1.1 macallan
137 1.1.1.3 skrll *allocated = 1;
138 1.1.1.3 skrll
139 1.1 macallan memcpy(new, s, len);
140 1.1 macallan return (new - strtab);
141 1.1 macallan }
142 1.1 macallan
143 1.1 macallan int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
144 1.1 macallan {
145 1.1 macallan struct fdt_reserve_entry *re;
146 1.1 macallan int err;
147 1.1 macallan
148 1.1.1.3 skrll FDT_RW_PROBE(fdt);
149 1.1 macallan
150 1.1.1.3 skrll re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
151 1.1.1.3 skrll err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
152 1.1 macallan if (err)
153 1.1 macallan return err;
154 1.1 macallan
155 1.1 macallan re->address = cpu_to_fdt64(address);
156 1.1 macallan re->size = cpu_to_fdt64(size);
157 1.1 macallan return 0;
158 1.1 macallan }
159 1.1 macallan
160 1.1 macallan int fdt_del_mem_rsv(void *fdt, int n)
161 1.1 macallan {
162 1.1.1.3 skrll struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
163 1.1 macallan
164 1.1.1.3 skrll FDT_RW_PROBE(fdt);
165 1.1 macallan
166 1.1 macallan if (n >= fdt_num_mem_rsv(fdt))
167 1.1 macallan return -FDT_ERR_NOTFOUND;
168 1.1 macallan
169 1.1.1.3 skrll return fdt_splice_mem_rsv_(fdt, re, 1, 0);
170 1.1 macallan }
171 1.1 macallan
172 1.1.1.3 skrll static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
173 1.1 macallan int len, struct fdt_property **prop)
174 1.1 macallan {
175 1.1 macallan int oldlen;
176 1.1 macallan int err;
177 1.1 macallan
178 1.1 macallan *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
179 1.1.1.3 skrll if (!*prop)
180 1.1 macallan return oldlen;
181 1.1 macallan
182 1.1.1.3 skrll if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
183 1.1 macallan FDT_TAGALIGN(len))))
184 1.1 macallan return err;
185 1.1 macallan
186 1.1 macallan (*prop)->len = cpu_to_fdt32(len);
187 1.1 macallan return 0;
188 1.1 macallan }
189 1.1 macallan
190 1.1.1.3 skrll static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
191 1.1 macallan int len, struct fdt_property **prop)
192 1.1 macallan {
193 1.1 macallan int proplen;
194 1.1 macallan int nextoffset;
195 1.1 macallan int namestroff;
196 1.1 macallan int err;
197 1.1.1.3 skrll int allocated;
198 1.1 macallan
199 1.1.1.3 skrll if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
200 1.1 macallan return nextoffset;
201 1.1 macallan
202 1.1.1.3 skrll namestroff = fdt_find_add_string_(fdt, name, &allocated);
203 1.1 macallan if (namestroff < 0)
204 1.1 macallan return namestroff;
205 1.1 macallan
206 1.1.1.3 skrll *prop = fdt_offset_ptr_w_(fdt, nextoffset);
207 1.1 macallan proplen = sizeof(**prop) + FDT_TAGALIGN(len);
208 1.1 macallan
209 1.1.1.3 skrll err = fdt_splice_struct_(fdt, *prop, 0, proplen);
210 1.1.1.3 skrll if (err) {
211 1.1.1.3 skrll if (allocated)
212 1.1.1.3 skrll fdt_del_last_string_(fdt, name);
213 1.1 macallan return err;
214 1.1.1.3 skrll }
215 1.1 macallan
216 1.1 macallan (*prop)->tag = cpu_to_fdt32(FDT_PROP);
217 1.1 macallan (*prop)->nameoff = cpu_to_fdt32(namestroff);
218 1.1 macallan (*prop)->len = cpu_to_fdt32(len);
219 1.1 macallan return 0;
220 1.1 macallan }
221 1.1 macallan
222 1.1 macallan int fdt_set_name(void *fdt, int nodeoffset, const char *name)
223 1.1 macallan {
224 1.1 macallan char *namep;
225 1.1 macallan int oldlen, newlen;
226 1.1 macallan int err;
227 1.1 macallan
228 1.1.1.3 skrll FDT_RW_PROBE(fdt);
229 1.1 macallan
230 1.1 macallan namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
231 1.1 macallan if (!namep)
232 1.1 macallan return oldlen;
233 1.1 macallan
234 1.1 macallan newlen = strlen(name);
235 1.1 macallan
236 1.1.1.3 skrll err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),
237 1.1 macallan FDT_TAGALIGN(newlen+1));
238 1.1 macallan if (err)
239 1.1 macallan return err;
240 1.1 macallan
241 1.1 macallan memcpy(namep, name, newlen+1);
242 1.1 macallan return 0;
243 1.1 macallan }
244 1.1 macallan
245 1.1.1.3 skrll int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
246 1.1.1.3 skrll int len, void **prop_data)
247 1.1 macallan {
248 1.1 macallan struct fdt_property *prop;
249 1.1 macallan int err;
250 1.1 macallan
251 1.1.1.3 skrll FDT_RW_PROBE(fdt);
252 1.1 macallan
253 1.1.1.3 skrll err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
254 1.1 macallan if (err == -FDT_ERR_NOTFOUND)
255 1.1.1.3 skrll err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
256 1.1.1.3 skrll if (err)
257 1.1.1.3 skrll return err;
258 1.1.1.3 skrll
259 1.1.1.3 skrll *prop_data = prop->data;
260 1.1.1.3 skrll return 0;
261 1.1.1.3 skrll }
262 1.1.1.3 skrll
263 1.1.1.3 skrll int fdt_setprop(void *fdt, int nodeoffset, const char *name,
264 1.1.1.3 skrll const void *val, int len)
265 1.1.1.3 skrll {
266 1.1.1.3 skrll void *prop_data;
267 1.1.1.3 skrll int err;
268 1.1.1.3 skrll
269 1.1.1.3 skrll err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
270 1.1 macallan if (err)
271 1.1 macallan return err;
272 1.1 macallan
273 1.1.1.2 skrll if (len)
274 1.1.1.3 skrll memcpy(prop_data, val, len);
275 1.1 macallan return 0;
276 1.1 macallan }
277 1.1 macallan
278 1.1 macallan int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
279 1.1 macallan const void *val, int len)
280 1.1 macallan {
281 1.1 macallan struct fdt_property *prop;
282 1.1 macallan int err, oldlen, newlen;
283 1.1 macallan
284 1.1.1.3 skrll FDT_RW_PROBE(fdt);
285 1.1 macallan
286 1.1 macallan prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
287 1.1 macallan if (prop) {
288 1.1 macallan newlen = len + oldlen;
289 1.1.1.3 skrll err = fdt_splice_struct_(fdt, prop->data,
290 1.1 macallan FDT_TAGALIGN(oldlen),
291 1.1 macallan FDT_TAGALIGN(newlen));
292 1.1 macallan if (err)
293 1.1 macallan return err;
294 1.1 macallan prop->len = cpu_to_fdt32(newlen);
295 1.1 macallan memcpy(prop->data + oldlen, val, len);
296 1.1 macallan } else {
297 1.1.1.3 skrll err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
298 1.1 macallan if (err)
299 1.1 macallan return err;
300 1.1 macallan memcpy(prop->data, val, len);
301 1.1 macallan }
302 1.1 macallan return 0;
303 1.1 macallan }
304 1.1 macallan
305 1.1 macallan int fdt_delprop(void *fdt, int nodeoffset, const char *name)
306 1.1 macallan {
307 1.1 macallan struct fdt_property *prop;
308 1.1 macallan int len, proplen;
309 1.1 macallan
310 1.1.1.3 skrll FDT_RW_PROBE(fdt);
311 1.1 macallan
312 1.1 macallan prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
313 1.1.1.3 skrll if (!prop)
314 1.1 macallan return len;
315 1.1 macallan
316 1.1 macallan proplen = sizeof(*prop) + FDT_TAGALIGN(len);
317 1.1.1.3 skrll return fdt_splice_struct_(fdt, prop, proplen, 0);
318 1.1 macallan }
319 1.1 macallan
320 1.1 macallan int fdt_add_subnode_namelen(void *fdt, int parentoffset,
321 1.1 macallan const char *name, int namelen)
322 1.1 macallan {
323 1.1 macallan struct fdt_node_header *nh;
324 1.1 macallan int offset, nextoffset;
325 1.1 macallan int nodelen;
326 1.1 macallan int err;
327 1.1 macallan uint32_t tag;
328 1.1 macallan fdt32_t *endtag;
329 1.1 macallan
330 1.1.1.3 skrll FDT_RW_PROBE(fdt);
331 1.1 macallan
332 1.1 macallan offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
333 1.1 macallan if (offset >= 0)
334 1.1 macallan return -FDT_ERR_EXISTS;
335 1.1 macallan else if (offset != -FDT_ERR_NOTFOUND)
336 1.1 macallan return offset;
337 1.1 macallan
338 1.1 macallan /* Try to place the new node after the parent's properties */
339 1.1 macallan fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
340 1.1 macallan do {
341 1.1 macallan offset = nextoffset;
342 1.1 macallan tag = fdt_next_tag(fdt, offset, &nextoffset);
343 1.1 macallan } while ((tag == FDT_PROP) || (tag == FDT_NOP));
344 1.1 macallan
345 1.1.1.3 skrll nh = fdt_offset_ptr_w_(fdt, offset);
346 1.1 macallan nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
347 1.1 macallan
348 1.1.1.3 skrll err = fdt_splice_struct_(fdt, nh, 0, nodelen);
349 1.1 macallan if (err)
350 1.1 macallan return err;
351 1.1 macallan
352 1.1 macallan nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
353 1.1 macallan memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
354 1.1 macallan memcpy(nh->name, name, namelen);
355 1.1 macallan endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
356 1.1 macallan *endtag = cpu_to_fdt32(FDT_END_NODE);
357 1.1 macallan
358 1.1 macallan return offset;
359 1.1 macallan }
360 1.1 macallan
361 1.1 macallan int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
362 1.1 macallan {
363 1.1 macallan return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
364 1.1 macallan }
365 1.1 macallan
366 1.1 macallan int fdt_del_node(void *fdt, int nodeoffset)
367 1.1 macallan {
368 1.1 macallan int endoffset;
369 1.1 macallan
370 1.1.1.3 skrll FDT_RW_PROBE(fdt);
371 1.1 macallan
372 1.1.1.3 skrll endoffset = fdt_node_end_offset_(fdt, nodeoffset);
373 1.1 macallan if (endoffset < 0)
374 1.1 macallan return endoffset;
375 1.1 macallan
376 1.1.1.3 skrll return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
377 1.1 macallan endoffset - nodeoffset, 0);
378 1.1 macallan }
379 1.1 macallan
380 1.1.1.3 skrll static void fdt_packblocks_(const char *old, char *new,
381 1.1 macallan int mem_rsv_size, int struct_size)
382 1.1 macallan {
383 1.1 macallan int mem_rsv_off, struct_off, strings_off;
384 1.1 macallan
385 1.1 macallan mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
386 1.1 macallan struct_off = mem_rsv_off + mem_rsv_size;
387 1.1 macallan strings_off = struct_off + struct_size;
388 1.1 macallan
389 1.1 macallan memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
390 1.1 macallan fdt_set_off_mem_rsvmap(new, mem_rsv_off);
391 1.1 macallan
392 1.1 macallan memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
393 1.1 macallan fdt_set_off_dt_struct(new, struct_off);
394 1.1 macallan fdt_set_size_dt_struct(new, struct_size);
395 1.1 macallan
396 1.1 macallan memmove(new + strings_off, old + fdt_off_dt_strings(old),
397 1.1 macallan fdt_size_dt_strings(old));
398 1.1 macallan fdt_set_off_dt_strings(new, strings_off);
399 1.1 macallan fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
400 1.1 macallan }
401 1.1 macallan
402 1.1 macallan int fdt_open_into(const void *fdt, void *buf, int bufsize)
403 1.1 macallan {
404 1.1 macallan int err;
405 1.1 macallan int mem_rsv_size, struct_size;
406 1.1 macallan int newsize;
407 1.1 macallan const char *fdtstart = fdt;
408 1.1 macallan const char *fdtend = fdtstart + fdt_totalsize(fdt);
409 1.1 macallan char *tmp;
410 1.1 macallan
411 1.1.1.3 skrll FDT_RO_PROBE(fdt);
412 1.1 macallan
413 1.1 macallan mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
414 1.1 macallan * sizeof(struct fdt_reserve_entry);
415 1.1 macallan
416 1.1 macallan if (fdt_version(fdt) >= 17) {
417 1.1 macallan struct_size = fdt_size_dt_struct(fdt);
418 1.1 macallan } else {
419 1.1 macallan struct_size = 0;
420 1.1 macallan while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
421 1.1 macallan ;
422 1.1 macallan if (struct_size < 0)
423 1.1 macallan return struct_size;
424 1.1 macallan }
425 1.1 macallan
426 1.1.1.3 skrll if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
427 1.1 macallan /* no further work necessary */
428 1.1 macallan err = fdt_move(fdt, buf, bufsize);
429 1.1 macallan if (err)
430 1.1 macallan return err;
431 1.1 macallan fdt_set_version(buf, 17);
432 1.1 macallan fdt_set_size_dt_struct(buf, struct_size);
433 1.1 macallan fdt_set_totalsize(buf, bufsize);
434 1.1 macallan return 0;
435 1.1 macallan }
436 1.1 macallan
437 1.1 macallan /* Need to reorder */
438 1.1 macallan newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
439 1.1 macallan + struct_size + fdt_size_dt_strings(fdt);
440 1.1 macallan
441 1.1 macallan if (bufsize < newsize)
442 1.1 macallan return -FDT_ERR_NOSPACE;
443 1.1 macallan
444 1.1 macallan /* First attempt to build converted tree at beginning of buffer */
445 1.1 macallan tmp = buf;
446 1.1 macallan /* But if that overlaps with the old tree... */
447 1.1 macallan if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
448 1.1 macallan /* Try right after the old tree instead */
449 1.1 macallan tmp = (char *)(uintptr_t)fdtend;
450 1.1 macallan if ((tmp + newsize) > ((char *)buf + bufsize))
451 1.1 macallan return -FDT_ERR_NOSPACE;
452 1.1 macallan }
453 1.1 macallan
454 1.1.1.3 skrll fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
455 1.1 macallan memmove(buf, tmp, newsize);
456 1.1 macallan
457 1.1 macallan fdt_set_magic(buf, FDT_MAGIC);
458 1.1 macallan fdt_set_totalsize(buf, bufsize);
459 1.1 macallan fdt_set_version(buf, 17);
460 1.1 macallan fdt_set_last_comp_version(buf, 16);
461 1.1 macallan fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
462 1.1 macallan
463 1.1 macallan return 0;
464 1.1 macallan }
465 1.1 macallan
466 1.1 macallan int fdt_pack(void *fdt)
467 1.1 macallan {
468 1.1 macallan int mem_rsv_size;
469 1.1 macallan
470 1.1.1.3 skrll FDT_RW_PROBE(fdt);
471 1.1 macallan
472 1.1 macallan mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
473 1.1 macallan * sizeof(struct fdt_reserve_entry);
474 1.1.1.3 skrll fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
475 1.1.1.3 skrll fdt_set_totalsize(fdt, fdt_data_size_(fdt));
476 1.1 macallan
477 1.1 macallan return 0;
478 1.1 macallan }
479