1 /* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 * USA 19 */ 20 21 #include "dtc.h" 22 #include "srcpos.h" 23 24 /* 25 * Command line options 26 */ 27 int quiet; /* Level of quietness */ 28 int reservenum; /* Number of memory reservation slots */ 29 int minsize; /* Minimum blob size */ 30 int padsize; /* Additional padding to blob */ 31 int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ 32 33 static void fill_fullpaths(struct node *tree, const char *prefix) 34 { 35 struct node *child; 36 const char *unit; 37 38 tree->fullpath = join_path(prefix, tree->name); 39 40 unit = strchr(tree->name, '@'); 41 if (unit) 42 tree->basenamelen = unit - tree->name; 43 else 44 tree->basenamelen = strlen(tree->name); 45 46 for_each_child(tree, child) 47 fill_fullpaths(child, tree->fullpath); 48 } 49 50 /* Usage related data. */ 51 #define FDT_VERSION(version) _FDT_VERSION(version) 52 #define _FDT_VERSION(version) #version 53 static const char usage_synopsis[] = "dtc [options] <input file>"; 54 static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; 55 static struct option const usage_long_opts[] = { 56 {"quiet", no_argument, NULL, 'q'}, 57 {"in-format", a_argument, NULL, 'I'}, 58 {"out", a_argument, NULL, 'o'}, 59 {"out-format", a_argument, NULL, 'O'}, 60 {"out-version", a_argument, NULL, 'V'}, 61 {"out-dependency", a_argument, NULL, 'd'}, 62 {"reserve", a_argument, NULL, 'R'}, 63 {"space", a_argument, NULL, 'S'}, 64 {"pad", a_argument, NULL, 'p'}, 65 {"boot-cpu", a_argument, NULL, 'b'}, 66 {"force", no_argument, NULL, 'f'}, 67 {"include", a_argument, NULL, 'i'}, 68 {"sort", no_argument, NULL, 's'}, 69 {"phandle", a_argument, NULL, 'H'}, 70 {"warning", a_argument, NULL, 'W'}, 71 {"error", a_argument, NULL, 'E'}, 72 {"help", no_argument, NULL, 'h'}, 73 {"version", no_argument, NULL, 'v'}, 74 {NULL, no_argument, NULL, 0x0}, 75 }; 76 static const char * const usage_opts_help[] = { 77 "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", 78 "\n\tInput formats are:\n" 79 "\t\tdts - device tree source text\n" 80 "\t\tdtb - device tree blob\n" 81 "\t\tfs - /proc/device-tree style directory", 82 "\n\tOutput file", 83 "\n\tOutput formats are:\n" 84 "\t\tdts - device tree source text\n" 85 "\t\tdtb - device tree blob\n" 86 "\t\tasm - assembler source", 87 "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", 88 "\n\tOutput dependency file", 89 "\n\tMake space for <number> reserve map entries (for dtb and asm output)", 90 "\n\tMake the blob at least <bytes> long (extra space)", 91 "\n\tAdd padding to the blob of <bytes> long (extra space)", 92 "\n\tSet the physical boot cpu", 93 "\n\tTry to produce output even if the input tree has errors", 94 "\n\tAdd a path to search for include files", 95 "\n\tSort nodes and properties before outputting (useful for comparing trees)", 96 "\n\tValid phandle formats are:\n" 97 "\t\tlegacy - \"linux,phandle\" properties only\n" 98 "\t\tepapr - \"phandle\" properties only\n" 99 "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", 100 "\n\tEnable/disable warnings (prefix with \"no-\")", 101 "\n\tEnable/disable errors (prefix with \"no-\")", 102 "\n\tPrint this help and exit", 103 "\n\tPrint version and exit", 104 NULL, 105 }; 106 107 int main(int argc, char *argv[]) 108 { 109 struct boot_info *bi; 110 const char *inform = "dts"; 111 const char *outform = "dts"; 112 const char *outname = "-"; 113 const char *depname = NULL; 114 bool force = false, sort = false; 115 const char *arg; 116 int opt; 117 FILE *outf = NULL; 118 int outversion = DEFAULT_FDT_VERSION; 119 long long cmdline_boot_cpuid = -1; 120 121 quiet = 0; 122 reservenum = 0; 123 minsize = 0; 124 padsize = 0; 125 126 while ((opt = util_getopt_long()) != EOF) { 127 switch (opt) { 128 case 'I': 129 inform = optarg; 130 break; 131 case 'O': 132 outform = optarg; 133 break; 134 case 'o': 135 outname = optarg; 136 break; 137 case 'V': 138 outversion = strtol(optarg, NULL, 0); 139 break; 140 case 'd': 141 depname = optarg; 142 break; 143 case 'R': 144 reservenum = strtol(optarg, NULL, 0); 145 break; 146 case 'S': 147 minsize = strtol(optarg, NULL, 0); 148 break; 149 case 'p': 150 padsize = strtol(optarg, NULL, 0); 151 break; 152 case 'f': 153 force = true; 154 break; 155 case 'q': 156 quiet++; 157 break; 158 case 'b': 159 cmdline_boot_cpuid = strtoll(optarg, NULL, 0); 160 break; 161 case 'i': 162 srcfile_add_search_path(optarg); 163 break; 164 case 'v': 165 util_version(); 166 case 'H': 167 if (streq(optarg, "legacy")) 168 phandle_format = PHANDLE_LEGACY; 169 else if (streq(optarg, "epapr")) 170 phandle_format = PHANDLE_EPAPR; 171 else if (streq(optarg, "both")) 172 phandle_format = PHANDLE_BOTH; 173 else 174 die("Invalid argument \"%s\" to -H option\n", 175 optarg); 176 break; 177 178 case 's': 179 sort = true; 180 break; 181 182 case 'W': 183 parse_checks_option(true, false, optarg); 184 break; 185 186 case 'E': 187 parse_checks_option(false, true, optarg); 188 break; 189 190 case 'h': 191 usage(NULL); 192 default: 193 usage("unknown option"); 194 } 195 } 196 197 if (argc > (optind+1)) 198 usage("missing files"); 199 else if (argc < (optind+1)) 200 arg = "-"; 201 else 202 arg = argv[optind]; 203 204 /* minsize and padsize are mutually exclusive */ 205 if (minsize && padsize) 206 die("Can't set both -p and -S\n"); 207 208 if (depname) { 209 depfile = fopen(depname, "w"); 210 if (!depfile) 211 die("Couldn't open dependency file %s: %s\n", depname, 212 strerror(errno)); 213 fprintf(depfile, "%s:", outname); 214 } 215 216 if (streq(inform, "dts")) 217 bi = dt_from_source(arg); 218 else if (streq(inform, "fs")) 219 bi = dt_from_fs(arg); 220 else if(streq(inform, "dtb")) 221 bi = dt_from_blob(arg); 222 else 223 die("Unknown input format \"%s\"\n", inform); 224 225 if (depfile) { 226 fputc('\n', depfile); 227 fclose(depfile); 228 } 229 230 if (cmdline_boot_cpuid != -1) 231 bi->boot_cpuid_phys = cmdline_boot_cpuid; 232 233 fill_fullpaths(bi->dt, ""); 234 process_checks(force, bi); 235 236 if (sort) 237 sort_tree(bi); 238 239 if (streq(outname, "-")) { 240 outf = stdout; 241 } else { 242 outf = fopen(outname, "wb"); 243 if (! outf) 244 die("Couldn't open output file %s: %s\n", 245 outname, strerror(errno)); 246 } 247 248 if (streq(outform, "dts")) { 249 dt_to_source(outf, bi); 250 } else if (streq(outform, "dtb")) { 251 dt_to_blob(outf, bi, outversion); 252 } else if (streq(outform, "asm")) { 253 dt_to_asm(outf, bi, outversion); 254 } else if (streq(outform, "null")) { 255 /* do nothing */ 256 } else { 257 die("Unknown output format \"%s\"\n", outform); 258 } 259 260 exit(0); 261 } 262