Add qemu 2.4.0
[kvmfornfv.git] / qemu / dtc / tests / nopulate.c
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 <libfdt.h>
28
29 #include "tests.h"
30 #include "testdata.h"
31
32 static int nopulate_struct(char *buf, const char *fdt)
33 {
34         int offset, nextoffset = 0;
35         uint32_t tag;
36         char *p;
37
38         p = buf;
39
40         do {
41                 offset = nextoffset;
42                 tag = fdt_next_tag(fdt, offset, &nextoffset);
43
44                 memcpy(p, (const char *)fdt + fdt_off_dt_struct(fdt) + offset,
45                        nextoffset - offset);
46                 p += nextoffset - offset;
47
48                 *((uint32_t *)p) = cpu_to_fdt32(FDT_NOP);
49                 p += FDT_TAGSIZE;
50
51         } while (tag != FDT_END);
52
53         return p - buf;
54 }
55
56 int main(int argc, char *argv[])
57 {
58         char *fdt, *fdt2, *buf;
59         int newsize, struct_start, struct_end_old, struct_end_new, delta;
60         const char *inname;
61         char outname[PATH_MAX];
62
63         test_init(argc, argv);
64         if (argc != 2)
65                 CONFIG("Usage: %s <dtb file>", argv[0]);
66
67         inname = argv[1];
68         fdt = load_blob(argv[1]);
69         sprintf(outname, "noppy.%s", inname);
70
71         if (fdt_version(fdt) < 17)
72                 FAIL("Can't deal with version <17");
73
74         buf = xmalloc(2 * fdt_size_dt_struct(fdt));
75
76         newsize = nopulate_struct(buf, fdt);
77
78         verbose_printf("Nopulated structure block has new size %d\n", newsize);
79
80         /* Replace old strcutre block with the new */
81
82         fdt2 = xmalloc(fdt_totalsize(fdt) + newsize);
83
84         struct_start = fdt_off_dt_struct(fdt);
85         delta = newsize - fdt_size_dt_struct(fdt);
86         struct_end_old = struct_start + fdt_size_dt_struct(fdt);
87         struct_end_new = struct_start + newsize;
88
89         memcpy(fdt2, fdt, struct_start);
90         memcpy(fdt2 + struct_start, buf, newsize);
91         memcpy(fdt2 + struct_end_new, fdt + struct_end_old,
92                fdt_totalsize(fdt) - struct_end_old);
93
94         fdt_set_totalsize(fdt2, fdt_totalsize(fdt) + delta);
95         fdt_set_size_dt_struct(fdt2, newsize);
96
97         if (fdt_off_mem_rsvmap(fdt) > struct_start)
98                 fdt_set_off_mem_rsvmap(fdt2, fdt_off_mem_rsvmap(fdt) + delta);
99         if (fdt_off_dt_strings(fdt) > struct_start)
100                 fdt_set_off_dt_strings(fdt2, fdt_off_dt_strings(fdt) + delta);
101
102         save_blob(outname, fdt2);
103
104         PASS();
105 }