coreboot-v3/util/dtc/dtc.c
<<
>>
Prefs
   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
  23char *join_path(char *path, char *name)
  24{
  25        int lenp = strlen(path);
  26        int lenn = strlen(name);
  27        int len;
  28        int needslash = 1;
  29        char *str;
  30
  31        len = lenp + lenn + 2;
  32        if ((lenp > 0) && (path[lenp-1] == '/')) {
  33                needslash = 0;
  34                len--;
  35        }
  36
  37        str = xmalloc(len);
  38        memcpy(str, path, lenp);
  39        if (needslash) {
  40                str[lenp] = '/';
  41                lenp++;
  42        }
  43        memcpy(str+lenp, name, lenn+1);
  44        return str;
  45}
  46
  47void fill_fullpaths(struct node *tree, char *prefix)
  48{
  49        struct node *child;
  50        char *unit;
  51
  52        tree->fullpath = join_path(prefix, tree->name);
  53
  54        unit = strchr(tree->name, '@');
  55        if (unit)
  56                tree->basenamelen = unit - tree->name;
  57        else
  58                tree->basenamelen = strlen(tree->name);
  59
  60        for_each_child(tree, child)
  61                fill_fullpaths(child, tree->fullpath);
  62}
  63
  64/* How stupid is POSIX? This stupid: you can fopen a directory if mode
  65 * is "r", but then there is very little you can do with it except get errors. 
  66 * This function now makes sure that the thing you open is a file. 
  67 */
  68FILE *fopenfile(char *fname)
  69{
  70        FILE *f = NULL;
  71
  72        if (streq(fname, "-")){
  73                f = stdin;
  74        } else {
  75                struct stat buf;
  76                if (stat(fname, &buf) < 0) {
  77                        errno = EISDIR;
  78                        goto no;
  79                }
  80
  81                if (! S_ISREG(buf.st_mode)){
  82                        errno = EISDIR;
  83                        goto no;
  84                }
  85
  86                f = fopen(fname, "r");
  87        }
  88
  89no:
  90
  91        return f;
  92}
  93
  94FILE *dtc_open_file(char *fname)
  95{
  96        FILE *f = fopenfile(fname);
  97
  98        if (! f)
  99                die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
 100
 101        return f;
 102}
 103
 104
 105static void usage(void)
 106{
 107        fprintf(stderr, "Usage:\n");
 108        fprintf(stderr, "\tdtc [options] <input file>\n");
 109        fprintf(stderr, "\nOptions:\n");
 110        fprintf(stderr, "\t-I <input format>\n");
 111        fprintf(stderr, "\t\tInput formats are:\n");
 112        fprintf(stderr, "\t\t\tdts - device tree source text\n");
 113        fprintf(stderr, "\t\t\tdtb - device tree blob\n");
 114        fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
 115        fprintf(stderr, "\t-O <output format>\n");
 116        fprintf(stderr, "\t\tOutput formats are:\n");
 117        fprintf(stderr, "\t\t\tdts - device tree source text\n");
 118        fprintf(stderr, "\t\t\tdtb - device tree blob\n");
 119        fprintf(stderr, "\t\t\tasm - assembler source\n");
 120        fprintf(stderr, "\t\t\tcoreboot (or just lb) - coreboot source\n");
 121        fprintf(stderr, "\t-V <output version>\n");
 122        fprintf(stderr, "\t\tBlob version to produce, defaults to 3 (relevant for dtb\n\t\tand asm output only)\n");
 123        fprintf(stderr, "\t-R <number>\n");
 124        fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
 125        fprintf(stderr, "\t-b <number>\n");
 126        fprintf(stderr, "\t\tSet the physical boot cpu\n");
 127        fprintf(stderr, "\t-f\n");
 128        fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
 129        exit(2);
 130}
 131
 132int main(int argc, char *argv[])
 133{
 134        struct boot_info *bi=NULL;
 135        char *inform = "dts";
 136        char *outform = "dts";
 137        char *outname = "-";
 138        int force = 0;
 139        char *arg=NULL;
 140        int opt;
 141        FILE *inf = NULL;
 142        FILE *outf = NULL;
 143        int outversion = 3;
 144        int reservenum = 1;
 145        int boot_cpuid_phys = 0xfeedbeef;
 146
 147        while ((opt = getopt(argc, argv, "I:O:o:V:R:fb:")) != EOF) {
 148                switch (opt) {
 149                case 'I':
 150                        inform = optarg;
 151                        break;
 152                case 'O':
 153                        outform = optarg;
 154                        break;
 155                case 'o':
 156                        outname = optarg;
 157                        break;
 158                case 'V':
 159                        outversion = strtol(optarg, NULL, 0);
 160                        break;
 161                case 'R':
 162                        reservenum = strtol(optarg, NULL, 0);
 163                        break;
 164                case 'f':
 165                        force = 1;
 166                        break;
 167                case 'b':
 168                        boot_cpuid_phys = strtol(optarg, NULL, 0);
 169                        break;
 170                default:
 171                        usage();
 172                }
 173        }
 174
 175        if (argc > (optind+1))
 176                usage();
 177        else if (argc < (optind+1))
 178                arg = "-";
 179        else
 180                arg = argv[optind];
 181
 182        // fprintf(stderr, "DTC: %s->%s  on file \"%s\"\n",
 183        //      inform, outform, arg);
 184        fprintf(stderr, "  DTC     %s (%s->%s)\n",
 185                arg, inform, outform);
 186
 187        if (streq(inform, "dts")) {
 188                inf = dtc_open_file(arg);
 189                bi = dt_from_source(inf);
 190        } else if (streq(inform, "fs")) {
 191                bi = dt_from_fs(arg);
 192        } else if(streq(inform, "dtb")) {
 193                inf = dtc_open_file(arg);
 194                bi = dt_from_blob(inf);
 195        } else {
 196                die("Unknown input format \"%s\"\n", inform);
 197        }
 198
 199        if (inf && (inf != stdin))
 200                fclose(inf);
 201
 202        if (! bi || ! bi->dt)
 203                die("Couldn't read input tree\n");
 204
 205        if (! check_device_tree(bi->dt, outversion, boot_cpuid_phys)) {
 206                fprintf(stderr, "Input tree has errors\n");
 207                if (! force)
 208                        exit(1);
 209        }
 210
 211        if (streq(outname, "-")) {
 212                outf = stdout;
 213        } else {
 214                outf = fopen(outname, "w");
 215                if (! outf)
 216                        die("Couldn't open output file %s: %s\n",
 217                            outname, strerror(errno));
 218        }
 219
 220        if (streq(outform, "dts")) {
 221                dt_to_source(outf, bi);
 222        } else if (streq(outform, "dtb")) {
 223                dt_to_blob(outf, bi, outversion, boot_cpuid_phys);
 224        } else if (streq(outform, "asm")) {
 225                dt_to_asm(outf, bi, outversion, boot_cpuid_phys);
 226        } else if (streq(outform, "C")) {
 227                dt_to_C(outf, bi, outversion, boot_cpuid_phys);
 228        } else if (streq(outform, "coreboot") || streq(outform, "lb")) {
 229                dt_to_coreboot(outf, bi, outversion, boot_cpuid_phys);
 230        } else if (streq(outform, "corebootinclude") || streq(outform, "lbh")) {
 231                dt_to_corebooth(outf, bi, outversion, boot_cpuid_phys);
 232        } else if (streq(outform, "null")) {
 233                /* do nothing */
 234        } else {
 235                die("Unknown output format \"%s\"\n", outform);
 236        }
 237                
 238        exit(0);
 239}
 240
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.