1204431Sraj/* 2204431Sraj * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3204431Sraj * 4204431Sraj * 5204431Sraj * This program is free software; you can redistribute it and/or 6204431Sraj * modify it under the terms of the GNU General Public License as 7204431Sraj * published by the Free Software Foundation; either version 2 of the 8204431Sraj * License, or (at your option) any later version. 9204431Sraj * 10204431Sraj * This program is distributed in the hope that it will be useful, 11204431Sraj * but WITHOUT ANY WARRANTY; without even the implied warranty of 12204431Sraj * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13204431Sraj * General Public License for more details. 14204431Sraj * 15204431Sraj * You should have received a copy of the GNU General Public License 16204431Sraj * along with this program; if not, write to the Free Software 17204431Sraj * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18204431Sraj * USA 19204431Sraj */ 20204431Sraj 21204431Sraj#include "dtc.h" 22204431Sraj#include "srcpos.h" 23204431Sraj 24204431Sraj/* 25204431Sraj * Command line options 26204431Sraj */ 27204431Srajint quiet; /* Level of quietness */ 28204431Srajint reservenum; /* Number of memory reservation slots */ 29204431Srajint minsize; /* Minimum blob size */ 30204431Srajint padsize; /* Additional padding to blob */ 31204433Srajint phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ 32204431Sraj 33204431Srajstatic void fill_fullpaths(struct node *tree, const char *prefix) 34204431Sraj{ 35204431Sraj struct node *child; 36204431Sraj const char *unit; 37204431Sraj 38204431Sraj tree->fullpath = join_path(prefix, tree->name); 39204431Sraj 40204431Sraj unit = strchr(tree->name, '@'); 41204431Sraj if (unit) 42204431Sraj tree->basenamelen = unit - tree->name; 43204431Sraj else 44204431Sraj tree->basenamelen = strlen(tree->name); 45204431Sraj 46204431Sraj for_each_child(tree, child) 47204431Sraj fill_fullpaths(child, tree->fullpath); 48204431Sraj} 49204431Sraj 50266130Sian/* Usage related data. */ 51266130Sianstatic const char usage_synopsis[] = "dtc [options] <input file>"; 52266130Sianstatic const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; 53266130Sianstatic struct option const usage_long_opts[] = { 54266130Sian {"quiet", no_argument, NULL, 'q'}, 55266130Sian {"in-format", a_argument, NULL, 'I'}, 56266130Sian {"out", a_argument, NULL, 'o'}, 57266130Sian {"out-format", a_argument, NULL, 'O'}, 58266130Sian {"out-version", a_argument, NULL, 'V'}, 59266130Sian {"out-dependency", a_argument, NULL, 'd'}, 60266130Sian {"reserve", a_argument, NULL, 'R'}, 61266130Sian {"space", a_argument, NULL, 'S'}, 62266130Sian {"pad", a_argument, NULL, 'p'}, 63266130Sian {"boot-cpu", a_argument, NULL, 'b'}, 64266130Sian {"force", no_argument, NULL, 'f'}, 65266130Sian {"include", a_argument, NULL, 'i'}, 66266130Sian {"sort", no_argument, NULL, 's'}, 67266130Sian {"phandle", a_argument, NULL, 'H'}, 68266130Sian {"warning", a_argument, NULL, 'W'}, 69266130Sian {"error", a_argument, NULL, 'E'}, 70266130Sian {"help", no_argument, NULL, 'h'}, 71266130Sian {"version", no_argument, NULL, 'v'}, 72266130Sian {NULL, no_argument, NULL, 0x0}, 73266130Sian}; 74266130Sianstatic const char * const usage_opts_help[] = { 75266130Sian "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", 76266130Sian "\n\tInput formats are:\n" 77266130Sian "\t\tdts - device tree source text\n" 78266130Sian "\t\tdtb - device tree blob\n" 79266130Sian "\t\tfs - /proc/device-tree style directory", 80266130Sian "\n\tOutput file", 81266130Sian "\n\tOutput formats are:\n" 82266130Sian "\t\tdts - device tree source text\n" 83266130Sian "\t\tdtb - device tree blob\n" 84266130Sian "\t\tasm - assembler source", 85266130Sian "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); 86266130Sian "\n\tOutput dependency file", 87266130Sian "\n\ttMake space for <number> reserve map entries (for dtb and asm output)", 88266130Sian "\n\tMake the blob at least <bytes> long (extra space)", 89266130Sian "\n\tAdd padding to the blob of <bytes> long (extra space)", 90266130Sian "\n\tSet the physical boot cpu", 91266130Sian "\n\tTry to produce output even if the input tree has errors", 92266130Sian "\n\tAdd a path to search for include files", 93266130Sian "\n\tSort nodes and properties before outputting (useful for comparing trees)", 94266130Sian "\n\tValid phandle formats are:\n" 95266130Sian "\t\tlegacy - \"linux,phandle\" properties only\n" 96266130Sian "\t\tepapr - \"phandle\" properties only\n" 97266130Sian "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", 98266130Sian "\n\tEnable/disable warnings (prefix with \"no-\")", 99266130Sian "\n\tEnable/disable errors (prefix with \"no-\")", 100266130Sian "\n\tPrint this help and exit", 101266130Sian "\n\tPrint version and exit", 102266130Sian NULL, 103266130Sian}; 104204431Sraj 105204431Srajint main(int argc, char *argv[]) 106204431Sraj{ 107204431Sraj struct boot_info *bi; 108204431Sraj const char *inform = "dts"; 109204431Sraj const char *outform = "dts"; 110204431Sraj const char *outname = "-"; 111238742Simp const char *depname = NULL; 112266130Sian bool force = false, sort = false; 113204431Sraj const char *arg; 114204431Sraj int opt; 115204431Sraj FILE *outf = NULL; 116204431Sraj int outversion = DEFAULT_FDT_VERSION; 117204431Sraj long long cmdline_boot_cpuid = -1; 118204431Sraj 119204431Sraj quiet = 0; 120204431Sraj reservenum = 0; 121204431Sraj minsize = 0; 122204431Sraj padsize = 0; 123204431Sraj 124266130Sian while ((opt = util_getopt_long()) != EOF) { 125204431Sraj switch (opt) { 126204431Sraj case 'I': 127204431Sraj inform = optarg; 128204431Sraj break; 129204431Sraj case 'O': 130204431Sraj outform = optarg; 131204431Sraj break; 132204431Sraj case 'o': 133204431Sraj outname = optarg; 134204431Sraj break; 135204431Sraj case 'V': 136204431Sraj outversion = strtol(optarg, NULL, 0); 137204431Sraj break; 138238742Simp case 'd': 139238742Simp depname = optarg; 140238742Simp break; 141204431Sraj case 'R': 142204431Sraj reservenum = strtol(optarg, NULL, 0); 143204431Sraj break; 144204431Sraj case 'S': 145204431Sraj minsize = strtol(optarg, NULL, 0); 146204431Sraj break; 147204431Sraj case 'p': 148204431Sraj padsize = strtol(optarg, NULL, 0); 149204431Sraj break; 150204431Sraj case 'f': 151266130Sian force = true; 152204431Sraj break; 153204431Sraj case 'q': 154204431Sraj quiet++; 155204431Sraj break; 156204431Sraj case 'b': 157204431Sraj cmdline_boot_cpuid = strtoll(optarg, NULL, 0); 158204431Sraj break; 159238742Simp case 'i': 160238742Simp srcfile_add_search_path(optarg); 161238742Simp break; 162204431Sraj case 'v': 163266130Sian util_version(); 164204433Sraj case 'H': 165204433Sraj if (streq(optarg, "legacy")) 166204433Sraj phandle_format = PHANDLE_LEGACY; 167204433Sraj else if (streq(optarg, "epapr")) 168204433Sraj phandle_format = PHANDLE_EPAPR; 169204433Sraj else if (streq(optarg, "both")) 170204433Sraj phandle_format = PHANDLE_BOTH; 171204433Sraj else 172204433Sraj die("Invalid argument \"%s\" to -H option\n", 173204433Sraj optarg); 174204433Sraj break; 175204433Sraj 176238742Simp case 's': 177266130Sian sort = true; 178238742Simp break; 179238742Simp 180238742Simp case 'W': 181238742Simp parse_checks_option(true, false, optarg); 182238742Simp break; 183238742Simp 184238742Simp case 'E': 185238742Simp parse_checks_option(false, true, optarg); 186238742Simp break; 187238742Simp 188204431Sraj case 'h': 189266130Sian usage(NULL); 190204431Sraj default: 191266130Sian usage("unknown option"); 192204431Sraj } 193204431Sraj } 194204431Sraj 195204431Sraj if (argc > (optind+1)) 196266130Sian usage("missing files"); 197204431Sraj else if (argc < (optind+1)) 198204431Sraj arg = "-"; 199204431Sraj else 200204431Sraj arg = argv[optind]; 201204431Sraj 202204431Sraj /* minsize and padsize are mutually exclusive */ 203204431Sraj if (minsize && padsize) 204204431Sraj die("Can't set both -p and -S\n"); 205204431Sraj 206238742Simp if (depname) { 207238742Simp depfile = fopen(depname, "w"); 208238742Simp if (!depfile) 209238742Simp die("Couldn't open dependency file %s: %s\n", depname, 210238742Simp strerror(errno)); 211238742Simp fprintf(depfile, "%s:", outname); 212238742Simp } 213204431Sraj 214204431Sraj if (streq(inform, "dts")) 215204431Sraj bi = dt_from_source(arg); 216204431Sraj else if (streq(inform, "fs")) 217204431Sraj bi = dt_from_fs(arg); 218204431Sraj else if(streq(inform, "dtb")) 219204431Sraj bi = dt_from_blob(arg); 220204431Sraj else 221204431Sraj die("Unknown input format \"%s\"\n", inform); 222204431Sraj 223238742Simp if (depfile) { 224238742Simp fputc('\n', depfile); 225238742Simp fclose(depfile); 226238742Simp } 227238742Simp 228204431Sraj if (cmdline_boot_cpuid != -1) 229204431Sraj bi->boot_cpuid_phys = cmdline_boot_cpuid; 230204431Sraj 231204431Sraj fill_fullpaths(bi->dt, ""); 232204431Sraj process_checks(force, bi); 233204431Sraj 234238742Simp if (sort) 235238742Simp sort_tree(bi); 236204431Sraj 237204431Sraj if (streq(outname, "-")) { 238204431Sraj outf = stdout; 239204431Sraj } else { 240204431Sraj outf = fopen(outname, "w"); 241204431Sraj if (! outf) 242204431Sraj die("Couldn't open output file %s: %s\n", 243204431Sraj outname, strerror(errno)); 244204431Sraj } 245204431Sraj 246204431Sraj if (streq(outform, "dts")) { 247204431Sraj dt_to_source(outf, bi); 248204431Sraj } else if (streq(outform, "dtb")) { 249204431Sraj dt_to_blob(outf, bi, outversion); 250204431Sraj } else if (streq(outform, "asm")) { 251204431Sraj dt_to_asm(outf, bi, outversion); 252204431Sraj } else if (streq(outform, "null")) { 253204431Sraj /* do nothing */ 254204431Sraj } else { 255204431Sraj die("Unknown output format \"%s\"\n", outform); 256204431Sraj } 257204431Sraj 258204431Sraj exit(0); 259204431Sraj} 260