dtc.c revision 302408
1139749Simp/* 2113584Ssimokawa * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3103285Sikob * 4103285Sikob * 5103285Sikob * This program is free software; you can redistribute it and/or 6103285Sikob * modify it under the terms of the GNU General Public License as 7103285Sikob * published by the Free Software Foundation; either version 2 of the 8103285Sikob * License, or (at your option) any later version. 9103285Sikob * 10103285Sikob * This program is distributed in the hope that it will be useful, 11103285Sikob * but WITHOUT ANY WARRANTY; without even the implied warranty of 12103285Sikob * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13103285Sikob * General Public License for more details. 14103285Sikob * 15103285Sikob * You should have received a copy of the GNU General Public License 16103285Sikob * along with this program; if not, write to the Free Software 17106802Ssimokawa * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18103285Sikob * USA 19103285Sikob */ 20103285Sikob 21103285Sikob#include "dtc.h" 22103285Sikob#include "srcpos.h" 23103285Sikob 24103285Sikob/* 25103285Sikob * Command line options 26103285Sikob */ 27103285Sikobint quiet; /* Level of quietness */ 28103285Sikobint reservenum; /* Number of memory reservation slots */ 29103285Sikobint minsize; /* Minimum blob size */ 30103285Sikobint padsize; /* Additional padding to blob */ 31103285Sikobint phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ 32103285Sikob 33103285Sikobstatic void fill_fullpaths(struct node *tree, const char *prefix) 34103285Sikob{ 35103285Sikob struct node *child; 36103285Sikob const char *unit; 37106802Ssimokawa 38103285Sikob tree->fullpath = join_path(prefix, tree->name); 39103285Sikob 40103285Sikob unit = strchr(tree->name, '@'); 41103285Sikob if (unit) 42103285Sikob tree->basenamelen = unit - tree->name; 43103285Sikob else 44103285Sikob tree->basenamelen = strlen(tree->name); 45103285Sikob 46103285Sikob for_each_child(tree, child) 47103285Sikob fill_fullpaths(child, tree->fullpath); 48103285Sikob} 49103285Sikob 50103285Sikob/* Usage related data. */ 51103285Sikobstatic const char usage_synopsis[] = "dtc [options] <input file>"; 52103285Sikobstatic const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; 53113584Ssimokawastatic struct option const usage_long_opts[] = { 54103285Sikob {"quiet", no_argument, NULL, 'q'}, 55103285Sikob {"in-format", a_argument, NULL, 'I'}, 56103285Sikob {"out", a_argument, NULL, 'o'}, 57127468Ssimokawa {"out-format", a_argument, NULL, 'O'}, 58117067Ssimokawa {"out-version", a_argument, NULL, 'V'}, 59117067Ssimokawa {"out-dependency", a_argument, NULL, 'd'}, 60117067Ssimokawa {"reserve", a_argument, NULL, 'R'}, 61127468Ssimokawa {"space", a_argument, NULL, 'S'}, 62127468Ssimokawa {"pad", a_argument, NULL, 'p'}, 63127468Ssimokawa {"boot-cpu", a_argument, NULL, 'b'}, 64127468Ssimokawa {"force", no_argument, NULL, 'f'}, 65127468Ssimokawa {"include", a_argument, NULL, 'i'}, 66127468Ssimokawa {"sort", no_argument, NULL, 's'}, 67127468Ssimokawa {"phandle", a_argument, NULL, 'H'}, 68127468Ssimokawa {"warning", a_argument, NULL, 'W'}, 69103285Sikob {"error", a_argument, NULL, 'E'}, 70103285Sikob {"help", no_argument, NULL, 'h'}, 71113584Ssimokawa {"version", no_argument, NULL, 'v'}, 72103285Sikob {NULL, no_argument, NULL, 0x0}, 73103285Sikob}; 74103285Sikobstatic const char * const usage_opts_help[] = { 75127468Ssimokawa "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", 76103285Sikob "\n\tInput formats are:\n" 77103285Sikob "\t\tdts - device tree source text\n" 78106802Ssimokawa "\t\tdtb - device tree blob\n" 79103285Sikob "\t\tfs - /proc/device-tree style directory", 80103285Sikob "\n\tOutput file", 81113584Ssimokawa "\n\tOutput formats are:\n" 82103285Sikob "\t\tdts - device tree source text\n" 83103285Sikob "\t\tdtb - device tree blob\n" 84113584Ssimokawa "\t\tasm - assembler source", 85103285Sikob "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); 86103285Sikob "\n\tOutput dependency file", 87103285Sikob "\n\ttMake space for <number> reserve map entries (for dtb and asm output)", 88103285Sikob "\n\tMake the blob at least <bytes> long (extra space)", 89103285Sikob "\n\tAdd padding to the blob of <bytes> long (extra space)", 90103285Sikob "\n\tSet the physical boot cpu", 91103285Sikob "\n\tTry to produce output even if the input tree has errors", 92103285Sikob "\n\tAdd a path to search for include files", 93103285Sikob "\n\tSort nodes and properties before outputting (useful for comparing trees)", 94113584Ssimokawa "\n\tValid phandle formats are:\n" 95116376Ssimokawa "\t\tlegacy - \"linux,phandle\" properties only\n" 96124378Ssimokawa "\t\tepapr - \"phandle\" properties only\n" 97129585Sdfr "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", 98103285Sikob "\n\tEnable/disable warnings (prefix with \"no-\")", 99103285Sikob "\n\tEnable/disable errors (prefix with \"no-\")", 100103285Sikob "\n\tPrint this help and exit", 101103285Sikob "\n\tPrint version and exit", 102103285Sikob NULL, 103103285Sikob}; 104103285Sikob 105103285Sikobint main(int argc, char *argv[]) 106103285Sikob{ 107103285Sikob struct boot_info *bi; 108103285Sikob const char *inform = "dts"; 109103285Sikob const char *outform = "dts"; 110103285Sikob const char *outname = "-"; 111103285Sikob const char *depname = NULL; 112103285Sikob bool force = false, sort = false; 113103285Sikob const char *arg; 114103285Sikob int opt; 115103285Sikob FILE *outf = NULL; 116103285Sikob int outversion = DEFAULT_FDT_VERSION; 117103285Sikob long long cmdline_boot_cpuid = -1; 118103285Sikob 119103285Sikob quiet = 0; 120103285Sikob reservenum = 0; 121103285Sikob minsize = 0; 122103285Sikob padsize = 0; 123103285Sikob 124103285Sikob while ((opt = util_getopt_long()) != EOF) { 125124169Ssimokawa switch (opt) { 126124169Ssimokawa case 'I': 127124169Ssimokawa inform = optarg; 128124169Ssimokawa break; 129124169Ssimokawa case 'O': 130124169Ssimokawa outform = optarg; 131124169Ssimokawa break; 132124169Ssimokawa case 'o': 133129585Sdfr outname = optarg; 134129585Sdfr break; 135124169Ssimokawa case 'V': 136124169Ssimokawa outversion = strtol(optarg, NULL, 0); 137124169Ssimokawa break; 138124169Ssimokawa case 'd': 139113584Ssimokawa depname = optarg; 140129585Sdfr break; 141113584Ssimokawa case 'R': 142124169Ssimokawa reservenum = strtol(optarg, NULL, 0); 143124169Ssimokawa break; 144124169Ssimokawa case 'S': 145124169Ssimokawa minsize = strtol(optarg, NULL, 0); 146113584Ssimokawa break; 147124169Ssimokawa case 'p': 148124169Ssimokawa padsize = strtol(optarg, NULL, 0); 149129585Sdfr break; 150129585Sdfr case 'f': 151129585Sdfr force = true; 152129585Sdfr break; 153124169Ssimokawa case 'q': 154124169Ssimokawa quiet++; 155124169Ssimokawa break; 156113584Ssimokawa case 'b': 157113584Ssimokawa cmdline_boot_cpuid = strtoll(optarg, NULL, 0); 158113584Ssimokawa break; 159103285Sikob case 'i': 160103285Sikob srcfile_add_search_path(optarg); 161103285Sikob break; 162103285Sikob case 'v': 163103285Sikob util_version(); 164103285Sikob case 'H': 165103285Sikob if (streq(optarg, "legacy")) 166103285Sikob phandle_format = PHANDLE_LEGACY; 167103285Sikob else if (streq(optarg, "epapr")) 168112523Ssimokawa phandle_format = PHANDLE_EPAPR; 169103285Sikob else if (streq(optarg, "both")) 170103285Sikob phandle_format = PHANDLE_BOTH; 171103285Sikob else 172103285Sikob die("Invalid argument \"%s\" to -H option\n", 173103285Sikob optarg); 174103285Sikob break; 175103285Sikob 176103285Sikob case 's': 177103285Sikob sort = true; 178103285Sikob break; 179103285Sikob 180103285Sikob case 'W': 181103285Sikob parse_checks_option(true, false, optarg); 182103285Sikob break; 183103285Sikob 184103285Sikob case 'E': 185103285Sikob parse_checks_option(false, true, optarg); 186103285Sikob break; 187103285Sikob 188103285Sikob case 'h': 189103285Sikob usage(NULL); 190103285Sikob default: 191103285Sikob usage("unknown option"); 192103285Sikob } 193103285Sikob } 194103285Sikob 195103285Sikob if (argc > (optind+1)) 196103285Sikob usage("missing files"); 197113584Ssimokawa else if (argc < (optind+1)) 198103285Sikob arg = "-"; 199103285Sikob else 200103285Sikob arg = argv[optind]; 201103285Sikob 202103285Sikob /* minsize and padsize are mutually exclusive */ 203103285Sikob if (minsize && padsize) 204103285Sikob die("Can't set both -p and -S\n"); 205103285Sikob 206103285Sikob if (depname) { 207103285Sikob depfile = fopen(depname, "w"); 208103285Sikob if (!depfile) 209103285Sikob die("Couldn't open dependency file %s: %s\n", depname, 210103285Sikob strerror(errno)); 211103285Sikob fprintf(depfile, "%s:", outname); 212103285Sikob } 213103285Sikob 214103285Sikob if (streq(inform, "dts")) 215103285Sikob bi = dt_from_source(arg); 216103285Sikob else if (streq(inform, "fs")) 217103285Sikob bi = dt_from_fs(arg); 218103285Sikob else if(streq(inform, "dtb")) 219103285Sikob bi = dt_from_blob(arg); 220103285Sikob else 221103285Sikob die("Unknown input format \"%s\"\n", inform); 222103285Sikob 223103285Sikob if (depfile) { 224103285Sikob fputc('\n', depfile); 225103285Sikob fclose(depfile); 226103285Sikob } 227103285Sikob 228103285Sikob if (cmdline_boot_cpuid != -1) 229103285Sikob bi->boot_cpuid_phys = cmdline_boot_cpuid; 230103285Sikob 231103285Sikob fill_fullpaths(bi->dt, ""); 232103285Sikob process_checks(force, bi); 233103285Sikob 234103285Sikob if (sort) 235103285Sikob sort_tree(bi); 236103285Sikob 237103285Sikob if (streq(outname, "-")) { 238103285Sikob outf = stdout; 239103285Sikob } else { 240103285Sikob outf = fopen(outname, "w"); 241103285Sikob if (! outf) 242103285Sikob die("Couldn't open output file %s: %s\n", 243103285Sikob outname, strerror(errno)); 244103285Sikob } 245103285Sikob 246103285Sikob if (streq(outform, "dts")) { 247103285Sikob dt_to_source(outf, bi); 248103285Sikob } else if (streq(outform, "dtb")) { 249103285Sikob dt_to_blob(outf, bi, outversion); 250103285Sikob } else if (streq(outform, "asm")) { 251103285Sikob dt_to_asm(outf, bi, outversion); 252103285Sikob } else if (streq(outform, "null")) { 253103285Sikob /* do nothing */ 254103285Sikob } else { 255103285Sikob die("Unknown output format \"%s\"\n", outform); 256103285Sikob } 257103285Sikob 258103285Sikob exit(0); 259103285Sikob} 260103285Sikob