|
1 /* |
|
2 * libfdt - Flat Device Tree manipulation |
|
3 * Testcase/tool for rearranging blocks of a dtb |
|
4 * Copyright (C) 2006 David Gibson, IBM Corporation. |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public License |
|
8 * as published by the Free Software Foundation; either version 2.1 of |
|
9 * the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public |
|
17 * License along with this library; if not, write to the Free Software |
|
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 */ |
|
20 |
|
21 #include <stdlib.h> |
|
22 #include <stdio.h> |
|
23 #include <string.h> |
|
24 #include <limits.h> |
|
25 #include <stdint.h> |
|
26 |
|
27 #include <fdt.h> |
|
28 #include <libfdt.h> |
|
29 |
|
30 #include "tests.h" |
|
31 #include "testdata.h" |
|
32 |
|
33 int nopulate_struct(char *buf, const char *fdt) |
|
34 { |
|
35 int offset, nextoffset = 0; |
|
36 uint32_t tag; |
|
37 char *p; |
|
38 |
|
39 p = buf; |
|
40 |
|
41 do { |
|
42 offset = nextoffset; |
|
43 tag = fdt_next_tag(fdt, offset, &nextoffset); |
|
44 |
|
45 memcpy(p, (const char *)fdt + fdt_off_dt_struct(fdt) + offset, |
|
46 nextoffset - offset); |
|
47 p += nextoffset - offset; |
|
48 |
|
49 *((uint32_t *)p) = cpu_to_fdt32(FDT_NOP); |
|
50 p += FDT_TAGSIZE; |
|
51 |
|
52 } while (tag != FDT_END); |
|
53 |
|
54 return p - buf; |
|
55 } |
|
56 |
|
57 int main(int argc, char *argv[]) |
|
58 { |
|
59 char *fdt, *fdt2, *buf; |
|
60 int newsize, struct_start, struct_end_old, struct_end_new, delta; |
|
61 const char *inname; |
|
62 char outname[PATH_MAX]; |
|
63 |
|
64 test_init(argc, argv); |
|
65 if (argc != 2) |
|
66 CONFIG("Usage: %s <dtb file>", argv[0]); |
|
67 |
|
68 inname = argv[1]; |
|
69 fdt = load_blob(argv[1]); |
|
70 sprintf(outname, "noppy.%s", inname); |
|
71 |
|
72 if (fdt_version(fdt) < 17) |
|
73 FAIL("Can't deal with version <17"); |
|
74 |
|
75 buf = xmalloc(2 * fdt_size_dt_struct(fdt)); |
|
76 |
|
77 newsize = nopulate_struct(buf, fdt); |
|
78 |
|
79 verbose_printf("Nopulated structure block has new size %d\n", newsize); |
|
80 |
|
81 /* Replace old strcutre block with the new */ |
|
82 |
|
83 fdt2 = xmalloc(fdt_totalsize(fdt) + newsize); |
|
84 |
|
85 struct_start = fdt_off_dt_struct(fdt); |
|
86 delta = newsize - fdt_size_dt_struct(fdt); |
|
87 struct_end_old = struct_start + fdt_size_dt_struct(fdt); |
|
88 struct_end_new = struct_start + newsize; |
|
89 |
|
90 memcpy(fdt2, fdt, struct_start); |
|
91 memcpy(fdt2 + struct_start, buf, newsize); |
|
92 memcpy(fdt2 + struct_end_new, fdt + struct_end_old, |
|
93 fdt_totalsize(fdt) - struct_end_old); |
|
94 |
|
95 fdt_set_totalsize(fdt2, fdt_totalsize(fdt) + delta); |
|
96 fdt_set_size_dt_struct(fdt2, newsize); |
|
97 |
|
98 if (fdt_off_mem_rsvmap(fdt) > struct_start) |
|
99 fdt_set_off_mem_rsvmap(fdt2, fdt_off_mem_rsvmap(fdt) + delta); |
|
100 if (fdt_off_dt_strings(fdt) > struct_start) |
|
101 fdt_set_off_dt_strings(fdt2, fdt_off_dt_strings(fdt) + delta); |
|
102 |
|
103 save_blob(outname, fdt2); |
|
104 |
|
105 PASS(); |
|
106 } |