1 /* $NetBSD: dtb_reverse.c,v 1.1.1.2 2017/06/08 15:59:26 skrll Exp $ */ 2 3 /* 4 * libfdt - Flat Device Tree manipulation 5 * Tests if two given dtbs are structurally equal (including order) 6 * Copyright (C) 2010 David Gibson, IBM Corporation. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <stdint.h> 27 #include <limits.h> 28 29 #include <libfdt.h> 30 31 #include "tests.h" 32 #include "testdata.h" 33 34 #define CHECK(code) \ 35 { \ 36 err = (code); \ 37 if (err) \ 38 FAIL(#code ": %s", fdt_strerror(err)); \ 39 } 40 41 static void reverse_reservemap(void *in, void *out, int n) 42 { 43 int err; 44 uint64_t addr, size; 45 46 verbose_printf("reverse_reservemap(): %d/%d\n", 47 n, fdt_num_mem_rsv(in)); 48 49 if (n < (fdt_num_mem_rsv(in)-1)) 50 reverse_reservemap(in, out, n+1); 51 52 CHECK(fdt_get_mem_rsv(in, n, &addr, &size)); 53 CHECK(fdt_add_reservemap_entry(out, addr, size)); 54 verbose_printf("Added entry 0x%llx 0x%llx\n", 55 (unsigned long long)addr, (unsigned long long)size); 56 } 57 58 static void reverse_properties(void *in, void *out, int offset) 59 { 60 int err; 61 int len; 62 const char *name; 63 const void *data; 64 65 data = fdt_getprop_by_offset(in, offset, &name, &len); 66 if (!data) 67 FAIL("fdt_getprop_by_offset(): %s\n", fdt_strerror(len)); 68 69 verbose_printf("reverse_properties(): offset=%d name=%s\n", 70 offset, name); 71 72 offset = fdt_next_property_offset(in, offset); 73 if (offset >= 0) 74 reverse_properties(in, out, offset); 75 else if (offset != -FDT_ERR_NOTFOUND) 76 FAIL("fdt_next_property_offset(): %s\n", fdt_strerror(offset)); 77 78 CHECK(fdt_property(out, name, data, len)); 79 verbose_printf(" -> output property %s\n", name); 80 } 81 82 static void reverse_node(void *in, void *out, int nodeoffset); 83 84 static void reverse_children(void *in, void *out, int offset) 85 { 86 int err; 87 int nextoffset = offset; 88 int depth = 1; 89 90 do { 91 char path[PATH_MAX]; 92 93 CHECK(fdt_get_path(in, nextoffset, path, sizeof(path))); 94 verbose_printf("reverse_children() offset=%d nextoffset=%d [%s]" 95 " depth=%d\n", offset, nextoffset, path, depth); 96 97 nextoffset = fdt_next_node(in, nextoffset, &depth); 98 } while ((depth >= 0) && (depth != 1)); 99 100 if (depth == 1) 101 reverse_children(in, out, nextoffset); 102 103 reverse_node(in, out, offset); 104 } 105 106 static void reverse_node(void *in, void *out, int nodeoffset) 107 { 108 const char *name = fdt_get_name(in, nodeoffset, NULL); 109 char path[PATH_MAX]; 110 int err; 111 int offset; 112 int depth = 0; 113 114 CHECK(fdt_get_path(in, nodeoffset, path, sizeof(path))); 115 verbose_printf("reverse_node(): nodeoffset=%d [%s]\n", 116 nodeoffset, path); 117 118 CHECK(fdt_begin_node(out, name)); 119 120 offset = fdt_first_property_offset(in, nodeoffset); 121 if (offset >= 0) 122 reverse_properties(in, out, offset); 123 else if (offset != -FDT_ERR_NOTFOUND) 124 FAIL("fdt_first_property(): %s\n", fdt_strerror(offset)); 125 126 offset = fdt_next_node(in, nodeoffset, &depth); 127 128 if (depth == 1) 129 reverse_children(in, out, offset); 130 131 CHECK(fdt_end_node(out)); 132 } 133 134 int main(int argc, char *argv[]) 135 { 136 void *in, *out; 137 char outname[PATH_MAX]; 138 int bufsize; 139 int err; 140 141 test_init(argc, argv); 142 if (argc != 2) 143 CONFIG("Usage: %s <dtb file>", argv[0]); 144 145 in = load_blob(argv[1]); 146 sprintf(outname, "%s.reversed.test.dtb", argv[1]); 147 148 bufsize = fdt_totalsize(in); 149 out = xmalloc(bufsize); 150 151 CHECK(fdt_create(out, bufsize)); 152 153 fdt_set_boot_cpuid_phys(out, fdt_boot_cpuid_phys(in)); 154 155 reverse_reservemap(in, out, 0); 156 CHECK(fdt_finish_reservemap(out)); 157 158 reverse_node(in, out, 0); 159 160 CHECK(fdt_finish(out)); 161 162 save_blob(outname, out); 163 164 PASS(); 165 } 166