1/* $NetBSD: nopulate.c,v 1.1.1.3 2019/12/22 12:34:05 skrll Exp $ */ 2 3// SPDX-License-Identifier: LGPL-2.1-or-later 4/* 5 * libfdt - Flat Device Tree manipulation 6 * Testcase/tool for rearranging blocks of a dtb 7 * Copyright (C) 2006 David Gibson, IBM Corporation. 8 */ 9 10#include <stdlib.h> 11#include <stdio.h> 12#include <string.h> 13#include <limits.h> 14#include <stdint.h> 15 16#include <libfdt.h> 17 18#include "tests.h" 19#include "testdata.h" 20 21static int nopulate_struct(char *buf, const char *fdt) 22{ 23 int offset, nextoffset = 0; 24 uint32_t tag; 25 char *p; 26 27 p = buf; 28 29 do { 30 offset = nextoffset; 31 tag = fdt_next_tag(fdt, offset, &nextoffset); 32 33 memcpy(p, (const char *)fdt + fdt_off_dt_struct(fdt) + offset, 34 nextoffset - offset); 35 p += nextoffset - offset; 36 37 *((fdt32_t *)p) = cpu_to_fdt32(FDT_NOP); 38 p += FDT_TAGSIZE; 39 40 } while (tag != FDT_END); 41 42 return p - buf; 43} 44 45int main(int argc, char *argv[]) 46{ 47 char *fdt, *fdt2, *buf; 48 int newsize, struct_start, struct_end_old, struct_end_new, delta; 49 const char *inname; 50 char outname[PATH_MAX]; 51 52 test_init(argc, argv); 53 if (argc != 2) 54 CONFIG("Usage: %s <dtb file>", argv[0]); 55 56 inname = argv[1]; 57 fdt = load_blob(argv[1]); 58 sprintf(outname, "noppy.%s", inname); 59 60 if (fdt_version(fdt) < 17) 61 FAIL("Can't deal with version <17"); 62 63 buf = xmalloc(2 * fdt_size_dt_struct(fdt)); 64 65 newsize = nopulate_struct(buf, fdt); 66 67 verbose_printf("Nopulated structure block has new size %d\n", newsize); 68 69 /* Replace old strcutre block with the new */ 70 71 fdt2 = xmalloc(fdt_totalsize(fdt) + newsize); 72 73 struct_start = fdt_off_dt_struct(fdt); 74 delta = newsize - fdt_size_dt_struct(fdt); 75 struct_end_old = struct_start + fdt_size_dt_struct(fdt); 76 struct_end_new = struct_start + newsize; 77 78 memcpy(fdt2, fdt, struct_start); 79 memcpy(fdt2 + struct_start, buf, newsize); 80 memcpy(fdt2 + struct_end_new, fdt + struct_end_old, 81 fdt_totalsize(fdt) - struct_end_old); 82 83 fdt_set_totalsize(fdt2, fdt_totalsize(fdt) + delta); 84 fdt_set_size_dt_struct(fdt2, newsize); 85 86 if (fdt_off_mem_rsvmap(fdt) > struct_start) 87 fdt_set_off_mem_rsvmap(fdt2, fdt_off_mem_rsvmap(fdt) + delta); 88 if (fdt_off_dt_strings(fdt) > struct_start) 89 fdt_set_off_dt_strings(fdt2, fdt_off_dt_strings(fdt) + delta); 90 91 save_blob(outname, fdt2); 92 93 PASS(); 94} 95