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 static const char usage_synopsis[] = "dtc [options] <input file>"; 52 static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; 53 static struct option const usage_long_opts[] = { 54 {"quiet", no_argument, NULL, 'q'}, 55 {"in-format", a_argument, NULL, 'I'}, 56 {"out", a_argument, NULL, 'o'}, 57 {"out-format", a_argument, NULL, 'O'}, 58 {"out-version", a_argument, NULL, 'V'}, 59 {"out-dependency", a_argument, NULL, 'd'}, 60 {"reserve", a_argument, NULL, 'R'}, 61 {"space", a_argument, NULL, 'S'}, 62 {"pad", a_argument, NULL, 'p'}, 63 {"boot-cpu", a_argument, NULL, 'b'}, 64 {"force", no_argument, NULL, 'f'}, 65 {"include", a_argument, NULL, 'i'}, 66 {"sort", no_argument, NULL, 's'}, 67 {"phandle", a_argument, NULL, 'H'}, 68 {"warning", a_argument, NULL, 'W'}, 69 {"error", a_argument, NULL, 'E'}, 70 {"help", no_argument, NULL, 'h'}, 71 {"version", no_argument, NULL, 'v'}, 72 {NULL, no_argument, NULL, 0x0}, 73 }; 74 static const char * const usage_opts_help[] = { 75 "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", 76 "\n\tInput formats are:\n" 77 "\t\tdts - device tree source text\n" 78 "\t\tdtb - device tree blob\n" 79 "\t\tfs - /proc/device-tree style directory", 80 "\n\tOutput file", 81 "\n\tOutput formats are:\n" 82 "\t\tdts - device tree source text\n" 83 "\t\tdtb - device tree blob\n" 84 "\t\tasm - assembler source", 85 "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); 86 "\n\tOutput dependency file", 87 "\n\ttMake space for <number> reserve map entries (for dtb and asm output)", 88 "\n\tMake the blob at least <bytes> long (extra space)", 89 "\n\tAdd padding to the blob of <bytes> long (extra space)", 90 "\n\tSet the physical boot cpu", 91 "\n\tTry to produce output even if the input tree has errors", 92 "\n\tAdd a path to search for include files", 93 "\n\tSort nodes and properties before outputting (useful for comparing trees)", 94 "\n\tValid phandle formats are:\n" 95 "\t\tlegacy - \"linux,phandle\" properties only\n" 96 "\t\tepapr - \"phandle\" properties only\n" 97 "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", 98 "\n\tEnable/disable warnings (prefix with \"no-\")", 99 "\n\tEnable/disable errors (prefix with \"no-\")", 100 "\n\tPrint this help and exit", 101 "\n\tPrint version and exit", 102 NULL, 103 }; 104 105 int main(int argc, char *argv[]) 106 { 107 struct boot_info *bi; 108 const char *inform = "dts"; 109 const char *outform = "dts"; 110 const char *outname = "-"; 111 const char *depname = NULL; 112 int force = 0, sort = 0; 113 const char *arg; 114 int opt; 115 FILE *outf = NULL; 116 int outversion = DEFAULT_FDT_VERSION; 117 long long cmdline_boot_cpuid = -1; 118 119 quiet = 0; 120 reservenum = 0; 121 minsize = 0; 122 padsize = 0; 123 124 while ((opt = util_getopt_long()) != EOF) { 125 switch (opt) { 126 case 'I': 127 inform = optarg; 128 break; 129 case 'O': 130 outform = optarg; 131 break; 132 case 'o': 133 outname = optarg; 134 break; 135 case 'V': 136 outversion = strtol(optarg, NULL, 0); 137 break; 138 case 'd': 139 depname = optarg; 140 break; 141 case 'R': 142 reservenum = strtol(optarg, NULL, 0); 143 break; 144 case 'S': 145 minsize = strtol(optarg, NULL, 0); 146 break; 147 case 'p': 148 padsize = strtol(optarg, NULL, 0); 149 break; 150 case 'f': 151 force = 1; 152 break; 153 case 'q': 154 quiet++; 155 break; 156 case 'b': 157 cmdline_boot_cpuid = strtoll(optarg, NULL, 0); 158 break; 159 case 'i': 160 srcfile_add_search_path(optarg); 161 break; 162 case 'v': 163 util_version(); 164 case 'H': 165 if (streq(optarg, "legacy")) 166 phandle_format = PHANDLE_LEGACY; 167 else if (streq(optarg, "epapr")) 168 phandle_format = PHANDLE_EPAPR; 169 else if (streq(optarg, "both")) 170 phandle_format = PHANDLE_BOTH; 171 else 172 die("Invalid argument \"%s\" to -H option\n", 173 optarg); 174 break; 175 176 case 's': 177 sort = 1; 178 break; 179 180 case 'W': 181 parse_checks_option(true, false, optarg); 182 break; 183 184 case 'E': 185 parse_checks_option(false, true, optarg); 186 break; 187 188 case 'h': 189 usage(NULL); 190 default: 191 usage("unknown option"); 192 } 193 } 194 195 if (argc > (optind+1)) 196 usage("missing files"); 197 else if (argc < (optind+1)) 198 arg = "-"; 199 else 200 arg = argv[optind]; 201 202 /* minsize and padsize are mutually exclusive */ 203 if (minsize && padsize) 204 die("Can't set both -p and -S\n"); 205 206 if (depname) { 207 depfile = fopen(depname, "w"); 208 if (!depfile) 209 die("Couldn't open dependency file %s: %s\n", depname, 210 strerror(errno)); 211 fprintf(depfile, "%s:", outname); 212 } 213 214 if (streq(inform, "dts")) 215 bi = dt_from_source(arg); 216 else if (streq(inform, "fs")) 217 bi = dt_from_fs(arg); 218 else if(streq(inform, "dtb")) 219 bi = dt_from_blob(arg); 220 else 221 die("Unknown input format \"%s\"\n", inform); 222 223 if (depfile) { 224 fputc('\n', depfile); 225 fclose(depfile); 226 } 227 228 if (cmdline_boot_cpuid != -1) 229 bi->boot_cpuid_phys = cmdline_boot_cpuid; 230 231 fill_fullpaths(bi->dt, ""); 232 process_checks(force, bi); 233 234 if (sort) 235 sort_tree(bi); 236 237 if (streq(outname, "-")) { 238 outf = stdout; 239 } else { 240 outf = fopen(outname, "w"); 241 if (! outf) 242 die("Couldn't open output file %s: %s\n", 243 outname, strerror(errno)); 244 } 245 246 if (streq(outform, "dts")) { 247 dt_to_source(outf, bi); 248 } else if (streq(outform, "dtb")) { 249 dt_to_blob(outf, bi, outversion); 250 } else if (streq(outform, "asm")) { 251 dt_to_asm(outf, bi, outversion); 252 } else if (streq(outform, "null")) { 253 /* do nothing */ 254 } else { 255 die("Unknown output format \"%s\"\n", outform); 256 } 257 258 exit(0); 259 } 260