^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "dtc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "srcpos.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Command line options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) int quiet; /* Level of quietness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) int reservenum; /* Number of memory reservation slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int minsize; /* Minimum blob size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) int padsize; /* Additional padding to blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int alignsize; /* Additional padding to blob accroding to the alignsize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int generate_symbols; /* enable symbols & fixup support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int generate_fixups; /* suppress generation of fixups on symbol support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int auto_label_aliases; /* auto generate labels -> aliases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int annotate; /* Level of annotation: 1 for input source location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) >1 for full input source location. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static int is_power_of_2(int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return (x > 0) && ((x & (x - 1)) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static void fill_fullpaths(struct node *tree, const char *prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const char *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) tree->fullpath = join_path(prefix, tree->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unit = strchr(tree->name, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) tree->basenamelen = unit - tree->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) tree->basenamelen = strlen(tree->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for_each_child(tree, child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) fill_fullpaths(child, tree->fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Usage related data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const char usage_synopsis[] = "dtc [options] <input file>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct option const usage_long_opts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {"quiet", no_argument, NULL, 'q'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {"in-format", a_argument, NULL, 'I'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {"out", a_argument, NULL, 'o'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {"out-format", a_argument, NULL, 'O'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {"out-version", a_argument, NULL, 'V'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {"out-dependency", a_argument, NULL, 'd'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {"reserve", a_argument, NULL, 'R'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {"space", a_argument, NULL, 'S'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {"pad", a_argument, NULL, 'p'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {"align", a_argument, NULL, 'a'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {"boot-cpu", a_argument, NULL, 'b'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {"force", no_argument, NULL, 'f'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {"include", a_argument, NULL, 'i'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {"sort", no_argument, NULL, 's'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {"phandle", a_argument, NULL, 'H'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {"warning", a_argument, NULL, 'W'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {"error", a_argument, NULL, 'E'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {"symbols", no_argument, NULL, '@'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {"auto-alias", no_argument, NULL, 'A'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {"annotate", no_argument, NULL, 'T'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {"help", no_argument, NULL, 'h'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {"version", no_argument, NULL, 'v'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {NULL, no_argument, NULL, 0x0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static const char * const usage_opts_help[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "\n\tInput formats are:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "\t\tdts - device tree source text\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "\t\tdtb - device tree blob\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "\t\tfs - /proc/device-tree style directory",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "\n\tOutput file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "\n\tOutput formats are:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "\t\tdts - device tree source text\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "\t\tdtb - device tree blob\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #ifndef NO_YAML
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) "\t\tyaml - device tree encoded as YAML\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) "\t\tasm - assembler source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) "\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) "\n\tOutput dependency file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) "\n\tMake space for <number> reserve map entries (for dtb and asm output)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) "\n\tMake the blob at least <bytes> long (extra space)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) "\n\tAdd padding to the blob of <bytes> long (extra space)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) "\n\tMake the blob align to the <bytes> (extra space)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) "\n\tSet the physical boot cpu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) "\n\tTry to produce output even if the input tree has errors",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) "\n\tAdd a path to search for include files",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) "\n\tSort nodes and properties before outputting (useful for comparing trees)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) "\n\tValid phandle formats are:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) "\t\tlegacy - \"linux,phandle\" properties only\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "\t\tepapr - \"phandle\" properties only\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "\n\tEnable/disable warnings (prefix with \"no-\")",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "\n\tEnable/disable errors (prefix with \"no-\")",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) "\n\tEnable generation of symbols",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) "\n\tEnable auto-alias of labels",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "\n\tPrint this help and exit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) "\n\tPrint version and exit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const char *guess_type_by_name(const char *fname, const char *fallback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) s = strrchr(fname, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (s == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!strcasecmp(s, ".dts"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return "dts";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!strcasecmp(s, ".yaml"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return "yaml";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (!strcasecmp(s, ".dtbo"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return "dtb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!strcasecmp(s, ".dtb"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return "dtb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const char *guess_input_format(const char *fname, const char *fallback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct stat statbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) fdt32_t magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) FILE *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (stat(fname, &statbuf) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (S_ISDIR(statbuf.st_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return "fs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!S_ISREG(statbuf.st_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) f = fopen(fname, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (f == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (fread(&magic, 4, 1, f) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) fclose(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return fallback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) fclose(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (fdt32_to_cpu(magic) == FDT_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return "dtb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return guess_type_by_name(fname, fallback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct dt_info *dti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) const char *inform = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) const char *outform = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) const char *outname = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) const char *depname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bool force = false, sort = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const char *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) FILE *outf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int outversion = DEFAULT_FDT_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) long long cmdline_boot_cpuid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) quiet = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) reservenum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) minsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) padsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) alignsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) while ((opt = util_getopt_long()) != EOF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) inform = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case 'O':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) outform = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) outname = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case 'V':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) outversion = strtol(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) depname = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case 'R':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) reservenum = strtol(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) minsize = strtol(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) padsize = strtol(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) alignsize = strtol(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!is_power_of_2(alignsize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) die("Invalid argument \"%d\" to -a option\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) alignsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) force = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) quiet++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) srcfile_add_search_path(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case 'v':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) util_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 'H':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (streq(optarg, "legacy"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) phandle_format = PHANDLE_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) else if (streq(optarg, "epapr"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) phandle_format = PHANDLE_EPAPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) else if (streq(optarg, "both"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) phandle_format = PHANDLE_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) die("Invalid argument \"%s\" to -H option\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sort = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case 'W':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) parse_checks_option(true, false, optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case 'E':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) parse_checks_option(false, true, optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case '@':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) generate_symbols = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case 'A':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) auto_label_aliases = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) annotate++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) usage(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) usage("unknown option");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (argc > (optind+1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) usage("missing files");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) else if (argc < (optind+1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) arg = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) arg = argv[optind];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* minsize and padsize are mutually exclusive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (minsize && padsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) die("Can't set both -p and -S\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (depname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) depfile = fopen(depname, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!depfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) die("Couldn't open dependency file %s: %s\n", depname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fprintf(depfile, "%s:", outname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (inform == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) inform = guess_input_format(arg, "dts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (outform == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) outform = guess_type_by_name(outname, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (outform == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (streq(inform, "dts"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) outform = "dtb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) outform = "dts";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) die("--annotate requires -I dts -O dts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (streq(inform, "dts"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dti = dt_from_source(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) else if (streq(inform, "fs"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dti = dt_from_fs(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else if(streq(inform, "dtb"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dti = dt_from_blob(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) die("Unknown input format \"%s\"\n", inform);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dti->outname = outname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (depfile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) fputc('\n', depfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fclose(depfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (cmdline_boot_cpuid != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) dti->boot_cpuid_phys = cmdline_boot_cpuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fill_fullpaths(dti->dt, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* on a plugin, generate by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (dti->dtsflags & DTSF_PLUGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) generate_fixups = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) process_checks(force, dti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (auto_label_aliases)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) generate_label_tree(dti, "aliases", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (generate_symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) generate_label_tree(dti, "__symbols__", true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (generate_fixups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) generate_fixups_tree(dti, "__fixups__");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) generate_local_fixups_tree(dti, "__local_fixups__");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sort_tree(dti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (streq(outname, "-")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) outf = stdout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) outf = fopen(outname, "wb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (! outf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) die("Couldn't open output file %s: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) outname, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (streq(outform, "dts")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dt_to_source(outf, dti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #ifndef NO_YAML
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) } else if (streq(outform, "yaml")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (!streq(inform, "dts"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) die("YAML output format requires dts input format\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dt_to_yaml(outf, dti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) } else if (streq(outform, "dtb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dt_to_blob(outf, dti, outversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) } else if (streq(outform, "dtbo")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dt_to_blob(outf, dti, outversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } else if (streq(outform, "asm")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dt_to_asm(outf, dti, outversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else if (streq(outform, "null")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) die("Unknown output format \"%s\"\n", outform);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }