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 32static 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 56int 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} 106