Author: imp
Date: Tue Jul 24 04:12:44 2012
New Revision: 238737
URL: http://svn.freebsd.org/changeset/base/238737

Log:
  Add missing files in f807af192828222dee7a5c9f94d999673bb4d8a1 import.

Added:
  vendor/dtc/dist/Makefile.utils   (contents, props changed)
  vendor/dtc/dist/dtdiff
  vendor/dtc/dist/fdtdump.c   (contents, props changed)
  vendor/dtc/dist/fdtget.c   (contents, props changed)
  vendor/dtc/dist/fdtput.c   (contents, props changed)
  vendor/dtc/dist/libfdt/fdt_empty_tree.c   (contents, props changed)
  vendor/dtc/dist/tests/appendprop.dts
  vendor/dtc/dist/tests/appendprop1.c   (contents, props changed)
  vendor/dtc/dist/tests/appendprop2.c   (contents, props changed)
  vendor/dtc/dist/tests/boot-cpuid.dts
  vendor/dtc/dist/tests/char_literal.c   (contents, props changed)
  vendor/dtc/dist/tests/char_literal.dts
  vendor/dtc/dist/tests/dependencies.cmp
  vendor/dtc/dist/tests/dependencies.dts
  vendor/dtc/dist/tests/deps_inc1.dtsi
  vendor/dtc/dist/tests/deps_inc2.dtsi
  vendor/dtc/dist/tests/dtb_reverse.c   (contents, props changed)
  vendor/dtc/dist/tests/dtbs_equal_unordered.c   (contents, props changed)
  vendor/dtc/dist/tests/dtc-fails.sh   (contents, props changed)
  vendor/dtc/dist/tests/fdtget-runtest.sh   (contents, props changed)
  vendor/dtc/dist/tests/fdtput-runtest.sh   (contents, props changed)
  vendor/dtc/dist/tests/include5a.dts
  vendor/dtc/dist/tests/integer-expressions.c   (contents, props changed)
  vendor/dtc/dist/tests/label_repeated.dts
  vendor/dtc/dist/tests/lorem.txt   (contents, props changed)
  vendor/dtc/dist/tests/multilabel.dts
  vendor/dtc/dist/tests/multilabel_merge.dts
  vendor/dtc/dist/tests/nonexist-node-ref2.dts
  vendor/dtc/dist/tests/reuse-label.dts
  vendor/dtc/dist/tests/reuse-label1.dts
  vendor/dtc/dist/tests/reuse-label2.dts
  vendor/dtc/dist/tests/reuse-label3.dts
  vendor/dtc/dist/tests/reuse-label4.dts
  vendor/dtc/dist/tests/reuse-label5.dts
  vendor/dtc/dist/tests/reuse-label6.dts
  vendor/dtc/dist/tests/search_dir/
  vendor/dtc/dist/tests/search_dir/search_test.dtsi
  vendor/dtc/dist/tests/search_dir/search_test2.dtsi
  vendor/dtc/dist/tests/search_dir_b/
  vendor/dtc/dist/tests/search_dir_b/search_paths_subdir.dts
  vendor/dtc/dist/tests/search_dir_b/search_test_b.dtsi
  vendor/dtc/dist/tests/search_dir_b/search_test_b2.dtsi
  vendor/dtc/dist/tests/search_dir_b/search_test_c.dtsi
  vendor/dtc/dist/tests/search_paths.dts
  vendor/dtc/dist/tests/search_paths_b.dts
  vendor/dtc/dist/tests/sized_cells.c   (contents, props changed)
  vendor/dtc/dist/tests/sized_cells.dts
  vendor/dtc/dist/tests/test_tree1_merge.dts
  vendor/dtc/dist/tests/test_tree1_merge_labelled.dts
  vendor/dtc/dist/tests/test_tree1_merge_path.dts
  vendor/dtc/dist/tests/test_tree1_wrong1.dts
  vendor/dtc/dist/tests/test_tree1_wrong2.dts
  vendor/dtc/dist/tests/test_tree1_wrong3.dts
  vendor/dtc/dist/tests/test_tree1_wrong4.dts
  vendor/dtc/dist/tests/test_tree1_wrong5.dts
  vendor/dtc/dist/tests/test_tree1_wrong6.dts
  vendor/dtc/dist/tests/test_tree1_wrong7.dts
  vendor/dtc/dist/tests/test_tree1_wrong8.dts
  vendor/dtc/dist/tests/test_tree1_wrong9.dts
  vendor/dtc/dist/tests/utilfdt_test.c   (contents, props changed)

Added: vendor/dtc/dist/Makefile.utils
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/Makefile.utils      Tue Jul 24 04:12:44 2012        
(r238737)
@@ -0,0 +1,24 @@
+#
+# This is not a complete Makefile of itself.  Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.
+#
+
+FDTDUMP_SRCS = \
+       fdtdump.c \
+       util.c
+
+FDTDUMP_OBJS = $(FDTDUMP_SRCS:%.c=%.o)
+
+
+FDTGET_SRCS = \
+       fdtget.c \
+       util.c
+
+FDTGET_OBJS = $(FDTGET_SRCS:%.c=%.o)
+
+
+FDTPUT_SRCS = \
+       fdtput.c \
+       util.c
+
+FDTPUT_OBJS = $(FDTPUT_SRCS:%.c=%.o)

Added: vendor/dtc/dist/dtdiff
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/dtdiff      Tue Jul 24 04:12:44 2012        (r238737)
@@ -0,0 +1,38 @@
+#! /bin/bash
+
+# This script uses the bash <(...) extension.
+# If you want to change this to work with a generic /bin/sh, make sure
+# you fix that.
+
+
+DTC=dtc
+
+source_and_sort () {
+    DT="$1"
+    if [ -d "$DT" ]; then
+       IFORMAT=fs
+    elif [ -f "$DT" ]; then
+       case "$DT" in
+           *.dts)
+               IFORMAT=dts
+               ;;
+           *.dtb)
+               IFORMAT=dtb
+               ;;
+       esac
+    fi
+
+    if [ -z "$IFORMAT" ]; then
+       echo "Unrecognized format for $DT" >&2
+       exit 2
+    fi
+
+    $DTC -I $IFORMAT -O dts -qq -f -s -o - "$DT"
+}
+
+if [ $# != 2 ]; then
+    echo "Usage: dtdiff <device tree> <device tree>" >&2
+    exit 1
+fi
+
+diff -u <(source_and_sort "$1") <(source_and_sort "$2")

Added: vendor/dtc/dist/fdtdump.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/fdtdump.c   Tue Jul 24 04:12:44 2012        (r238737)
@@ -0,0 +1,162 @@
+/*
+ * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT 
gmail.com>
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <fdt.h>
+#include <libfdt_env.h>
+
+#include "util.h"
+
+#define ALIGN(x, a)    (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a)   ((void *)(ALIGN((unsigned long)(p), (a))))
+#define GET_CELL(p)    (p += 4, *((const uint32_t *)(p-4)))
+
+static void print_data(const char *data, int len)
+{
+       int i;
+       const char *p = data;
+
+       /* no data, don't print */
+       if (len == 0)
+               return;
+
+       if (util_is_printable_string(data, len)) {
+               printf(" = \"%s\"", (const char *)data);
+       } else if ((len % 4) == 0) {
+               printf(" = <");
+               for (i = 0; i < len; i += 4)
+                       printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
+                              i < (len - 4) ? " " : "");
+               printf(">");
+       } else {
+               printf(" = [");
+               for (i = 0; i < len; i++)
+                       printf("%02x%s", *p++, i < len - 1 ? " " : "");
+               printf("]");
+       }
+}
+
+static void dump_blob(void *blob)
+{
+       struct fdt_header *bph = blob;
+       uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
+       uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
+       uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
+       struct fdt_reserve_entry *p_rsvmap =
+               (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
+       const char *p_struct = (const char *)blob + off_dt;
+       const char *p_strings = (const char *)blob + off_str;
+       uint32_t version = fdt32_to_cpu(bph->version);
+       uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
+       uint32_t tag;
+       const char *p, *s, *t;
+       int depth, sz, shift;
+       int i;
+       uint64_t addr, size;
+
+       depth = 0;
+       shift = 4;
+
+       printf("/dts-v1/;\n");
+       printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
+       printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
+       printf("// off_dt_struct:\t0x%x\n", off_dt);
+       printf("// off_dt_strings:\t0x%x\n", off_str);
+       printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
+       printf("// version:\t\t%d\n", version);
+       printf("// last_comp_version:\t%d\n",
+              fdt32_to_cpu(bph->last_comp_version));
+       if (version >= 2)
+               printf("// boot_cpuid_phys:\t0x%x\n",
+                      fdt32_to_cpu(bph->boot_cpuid_phys));
+
+       if (version >= 3)
+               printf("// size_dt_strings:\t0x%x\n",
+                      fdt32_to_cpu(bph->size_dt_strings));
+       if (version >= 17)
+               printf("// size_dt_struct:\t0x%x\n",
+                      fdt32_to_cpu(bph->size_dt_struct));
+       printf("\n");
+
+       for (i = 0; ; i++) {
+               addr = fdt64_to_cpu(p_rsvmap[i].address);
+               size = fdt64_to_cpu(p_rsvmap[i].size);
+               if (addr == 0 && size == 0)
+                       break;
+
+               printf("/memreserve/ %llx %llx;\n",
+                      (unsigned long long)addr, (unsigned long long)size);
+       }
+
+       p = p_struct;
+       while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
+
+               /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
+
+               if (tag == FDT_BEGIN_NODE) {
+                       s = p;
+                       p = PALIGN(p + strlen(s) + 1, 4);
+
+                       if (*s == '\0')
+                               s = "/";
+
+                       printf("%*s%s {\n", depth * shift, "", s);
+
+                       depth++;
+                       continue;
+               }
+
+               if (tag == FDT_END_NODE) {
+                       depth--;
+
+                       printf("%*s};\n", depth * shift, "");
+                       continue;
+               }
+
+               if (tag == FDT_NOP) {
+                       printf("%*s// [NOP]\n", depth * shift, "");
+                       continue;
+               }
+
+               if (tag != FDT_PROP) {
+                       fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * 
shift, "", tag);
+                       break;
+               }
+               sz = fdt32_to_cpu(GET_CELL(p));
+               s = p_strings + fdt32_to_cpu(GET_CELL(p));
+               if (version < 16 && sz >= 8)
+                       p = PALIGN(p, 8);
+               t = p;
+
+               p = PALIGN(p + sz, 4);
+
+               printf("%*s%s", depth * shift, "", s);
+               print_data(t, sz);
+               printf(";\n");
+       }
+}
+
+
+int main(int argc, char *argv[])
+{
+       char *buf;
+
+       if (argc < 2) {
+               fprintf(stderr, "supply input filename\n");
+               return 5;
+       }
+
+       buf = utilfdt_read(argv[1]);
+       if (buf)
+               dump_blob(buf);
+       else
+               return 10;
+
+       return 0;
+}

Added: vendor/dtc/dist/fdtget.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/fdtget.c    Tue Jul 24 04:12:44 2012        (r238737)
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * Portions from U-Boot cmd_fdt.c (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, [email protected]
+ * Based on code written by:
+ *   Pantelis Antoniou <[email protected]> and
+ *   Matthew McClintock <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libfdt.h>
+
+#include "util.h"
+
+enum display_mode {
+       MODE_SHOW_VALUE,        /* show values for node properties */
+       MODE_LIST_PROPS,        /* list the properties for a node */
+       MODE_LIST_SUBNODES,     /* list the subnodes of a node */
+};
+
+/* Holds information which controls our output and options */
+struct display_info {
+       int type;               /* data type (s/i/u/x or 0 for default) */
+       int size;               /* data size (1/2/4) */
+       enum display_mode mode; /* display mode that we are using */
+       const char *default_val; /* default value if node/property not found */
+};
+
+static void report_error(const char *where, int err)
+{
+       fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
+}
+
+/**
+ * Displays data of a given length according to selected options
+ *
+ * If a specific data type is provided in disp, then this is used. Otherwise
+ * we try to guess the data type / size from the contents.
+ *
+ * @param disp         Display information / options
+ * @param data         Data to display
+ * @param len          Maximum length of buffer
+ * @return 0 if ok, -1 if data does not match format
+ */
+static int show_data(struct display_info *disp, const char *data, int len)
+{
+       int i, size;
+       const uint8_t *p = (const uint8_t *)data;
+       const char *s;
+       int value;
+       int is_string;
+       char fmt[3];
+
+       /* no data, don't print */
+       if (len == 0)
+               return 0;
+
+       is_string = (disp->type) == 's' ||
+               (!disp->type && util_is_printable_string(data, len));
+       if (is_string) {
+               if (data[len - 1] != '\0') {
+                       fprintf(stderr, "Unterminated string\n");
+                       return -1;
+               }
+               for (s = data; s - data < len; s += strlen(s) + 1) {
+                       if (s != data)
+                               printf(" ");
+                       printf("%s", (const char *)s);
+               }
+               return 0;
+       }
+       size = disp->size;
+       if (size == -1) {
+               size = (len % 4) == 0 ? 4 : 1;
+       } else if (len % size) {
+               fprintf(stderr, "Property length must be a multiple of "
+                               "selected data size\n");
+               return -1;
+       }
+       fmt[0] = '%';
+       fmt[1] = disp->type ? disp->type : 'd';
+       fmt[2] = '\0';
+       for (i = 0; i < len; i += size, p += size) {
+               if (i)
+                       printf(" ");
+               value = size == 4 ? fdt32_to_cpu(*(const uint32_t *)p) :
+                       size == 2 ? (*p << 8) | p[1] : *p;
+               printf(fmt, value);
+       }
+       return 0;
+}
+
+/**
+ * List all properties in a node, one per line.
+ *
+ * @param blob         FDT blob
+ * @param node         Node to display
+ * @return 0 if ok, or FDT_ERR... if not.
+ */
+static int list_properties(const void *blob, int node)
+{
+       const struct fdt_property *data;
+       const char *name;
+       int prop;
+
+       prop = fdt_first_property_offset(blob, node);
+       do {
+               /* Stop silently when there are no more properties */
+               if (prop < 0)
+                       return prop == -FDT_ERR_NOTFOUND ? 0 : prop;
+               data = fdt_get_property_by_offset(blob, prop, NULL);
+               name = fdt_string(blob, fdt32_to_cpu(data->nameoff));
+               if (name)
+                       puts(name);
+               prop = fdt_next_property_offset(blob, prop);
+       } while (1);
+}
+
+#define MAX_LEVEL      32              /* how deeply nested we will go */
+
+/**
+ * List all subnodes in a node, one per line
+ *
+ * @param blob         FDT blob
+ * @param node         Node to display
+ * @return 0 if ok, or FDT_ERR... if not.
+ */
+static int list_subnodes(const void *blob, int node)
+{
+       int nextoffset;         /* next node offset from libfdt */
+       uint32_t tag;           /* current tag */
+       int level = 0;          /* keep track of nesting level */
+       const char *pathp;
+       int depth = 1;          /* the assumed depth of this node */
+
+       while (level >= 0) {
+               tag = fdt_next_tag(blob, node, &nextoffset);
+               switch (tag) {
+               case FDT_BEGIN_NODE:
+                       pathp = fdt_get_name(blob, node, NULL);
+                       if (level <= depth) {
+                               if (pathp == NULL)
+                                       pathp = "/* NULL pointer error */";
+                               if (*pathp == '\0')
+                                       pathp = "/";    /* root is nameless */
+                               if (level == 1)
+                                       puts(pathp);
+                       }
+                       level++;
+                       if (level >= MAX_LEVEL) {
+                               printf("Nested too deep, aborting.\n");
+                               return 1;
+                       }
+                       break;
+               case FDT_END_NODE:
+                       level--;
+                       if (level == 0)
+                               level = -1;             /* exit the loop */
+                       break;
+               case FDT_END:
+                       return 1;
+               case FDT_PROP:
+                       break;
+               default:
+                       if (level <= depth)
+                               printf("Unknown tag 0x%08X\n", tag);
+                       return 1;
+               }
+               node = nextoffset;
+       }
+       return 0;
+}
+
+/**
+ * Show the data for a given node (and perhaps property) according to the
+ * display option provided.
+ *
+ * @param blob         FDT blob
+ * @param disp         Display information / options
+ * @param node         Node to display
+ * @param property     Name of property to display, or NULL if none
+ * @return 0 if ok, -ve on error
+ */
+static int show_data_for_item(const void *blob, struct display_info *disp,
+               int node, const char *property)
+{
+       const void *value = NULL;
+       int len, err = 0;
+
+       switch (disp->mode) {
+       case MODE_LIST_PROPS:
+               err = list_properties(blob, node);
+               break;
+
+       case MODE_LIST_SUBNODES:
+               err = list_subnodes(blob, node);
+               break;
+
+       default:
+               assert(property);
+               value = fdt_getprop(blob, node, property, &len);
+               if (value) {
+                       if (show_data(disp, value, len))
+                               err = -1;
+                       else
+                               printf("\n");
+               } else if (disp->default_val) {
+                       puts(disp->default_val);
+               } else {
+                       report_error(property, len);
+                       err = -1;
+               }
+               break;
+       }
+
+       return err;
+}
+
+/**
+ * Run the main fdtget operation, given a filename and valid arguments
+ *
+ * @param disp         Display information / options
+ * @param filename     Filename of blob file
+ * @param arg          List of arguments to process
+ * @param arg_count    Number of arguments
+ * @param return 0 if ok, -ve on error
+ */
+static int do_fdtget(struct display_info *disp, const char *filename,
+                    char **arg, int arg_count, int args_per_step)
+{
+       char *blob;
+       const char *prop;
+       int i, node;
+
+       blob = utilfdt_read(filename);
+       if (!blob)
+               return -1;
+
+       for (i = 0; i + args_per_step <= arg_count; i += args_per_step) {
+               node = fdt_path_offset(blob, arg[i]);
+               if (node < 0) {
+                       if (disp->default_val) {
+                               puts(disp->default_val);
+                               continue;
+                       } else {
+                               report_error(arg[i], node);
+                               return -1;
+                       }
+               }
+               prop = args_per_step == 1 ? NULL : arg[i + 1];
+
+               if (show_data_for_item(blob, disp, node, prop))
+                       return -1;
+       }
+       return 0;
+}
+
+static const char *usage_msg =
+       "fdtget - read values from device tree\n"
+       "\n"
+       "Each value is printed on a new line.\n\n"
+       "Usage:\n"
+       "       fdtget <options> <dt file> [<node> <property>]...\n"
+       "       fdtget -p <options> <dt file> [<node> ]...\n"
+       "Options:\n"
+       "\t-t <type>\tType of data\n"
+       "\t-p\t\tList properties for each node\n"
+       "\t-l\t\tList subnodes for each node\n"
+       "\t-d\t\tDefault value to display when the property is "
+                       "missing\n"
+       "\t-h\t\tPrint this help\n\n"
+       USAGE_TYPE_MSG;
+
+static void usage(const char *msg)
+{
+       if (msg)
+               fprintf(stderr, "Error: %s\n\n", msg);
+
+       fprintf(stderr, "%s", usage_msg);
+       exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+       char *filename = NULL;
+       struct display_info disp;
+       int args_per_step = 2;
+
+       /* set defaults */
+       memset(&disp, '\0', sizeof(disp));
+       disp.size = -1;
+       disp.mode = MODE_SHOW_VALUE;
+       for (;;) {
+               int c = getopt(argc, argv, "d:hlpt:");
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'h':
+               case '?':
+                       usage(NULL);
+
+               case 't':
+                       if (utilfdt_decode_type(optarg, &disp.type,
+                                       &disp.size))
+                               usage("Invalid type string");
+                       break;
+
+               case 'p':
+                       disp.mode = MODE_LIST_PROPS;
+                       args_per_step = 1;
+                       break;
+
+               case 'l':
+                       disp.mode = MODE_LIST_SUBNODES;
+                       args_per_step = 1;
+                       break;
+
+               case 'd':
+                       disp.default_val = optarg;
+                       break;
+               }
+       }
+
+       if (optind < argc)
+               filename = argv[optind++];
+       if (!filename)
+               usage("Missing filename");
+
+       argv += optind;
+       argc -= optind;
+
+       /* Allow no arguments, and silently succeed */
+       if (!argc)
+               return 0;
+
+       /* Check for node, property arguments */
+       if (args_per_step == 2 && (argc % 2))
+               usage("Must have an even number of arguments");
+
+       if (do_fdtget(&disp, filename, argv, argc, args_per_step))
+               return 1;
+       return 0;
+}

Added: vendor/dtc/dist/fdtput.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/fdtput.c    Tue Jul 24 04:12:44 2012        (r238737)
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libfdt.h>
+
+#include "util.h"
+
+/* These are the operations we support */
+enum oper_type {
+       OPER_WRITE_PROP,                /* Write a property in a node */
+       OPER_CREATE_NODE,               /* Create a new node */
+};
+
+struct display_info {
+       enum oper_type oper;    /* operation to perform */
+       int type;               /* data type (s/i/u/x or 0 for default) */
+       int size;               /* data size (1/2/4) */
+       int verbose;            /* verbose output */
+       int auto_path;          /* automatically create all path components */
+};
+
+
+/**
+ * Report an error with a particular node.
+ *
+ * @param name         Node name to report error on
+ * @param namelen      Length of node name, or -1 to use entire string
+ * @param err          Error number to report (-FDT_ERR_...)
+ */
+static void report_error(const char *name, int namelen, int err)
+{
+       if (namelen == -1)
+               namelen = strlen(name);
+       fprintf(stderr, "Error at '%1.*s': %s\n", namelen, name,
+               fdt_strerror(err));
+}
+
+/**
+ * Encode a series of arguments in a property value.
+ *
+ * @param disp         Display information / options
+ * @param arg          List of arguments from command line
+ * @param arg_count    Number of arguments (may be 0)
+ * @param valuep       Returns buffer containing value
+ * @param *value_len   Returns length of value encoded
+ */
+static int encode_value(struct display_info *disp, char **arg, int arg_count,
+                       char **valuep, int *value_len)
+{
+       char *value = NULL;     /* holding area for value */
+       int value_size = 0;     /* size of holding area */
+       char *ptr;              /* pointer to current value position */
+       int len;                /* length of this cell/string/byte */
+       int ival;
+       int upto;       /* the number of bytes we have written to buf */
+       char fmt[3];
+
+       upto = 0;
+
+       if (disp->verbose)
+               fprintf(stderr, "Decoding value:\n");
+
+       fmt[0] = '%';
+       fmt[1] = disp->type ? disp->type : 'd';
+       fmt[2] = '\0';
+       for (; arg_count > 0; arg++, arg_count--, upto += len) {
+               /* assume integer unless told otherwise */
+               if (disp->type == 's')
+                       len = strlen(*arg) + 1;
+               else
+                       len = disp->size == -1 ? 4 : disp->size;
+
+               /* enlarge our value buffer by a suitable margin if needed */
+               if (upto + len > value_size) {
+                       value_size = (upto + len) + 500;
+                       value = realloc(value, value_size);
+                       if (!value) {
+                               fprintf(stderr, "Out of mmory: cannot alloc "
+                                       "%d bytes\n", value_size);
+                               return -1;
+                       }
+               }
+
+               ptr = value + upto;
+               if (disp->type == 's') {
+                       memcpy(ptr, *arg, len);
+                       if (disp->verbose)
+                               fprintf(stderr, "\tstring: '%s'\n", ptr);
+               } else {
+                       int *iptr = (int *)ptr;
+                       sscanf(*arg, fmt, &ival);
+                       if (len == 4)
+                               *iptr = cpu_to_fdt32(ival);
+                       else
+                               *ptr = (uint8_t)ival;
+                       if (disp->verbose) {
+                               fprintf(stderr, "\t%s: %d\n",
+                                       disp->size == 1 ? "byte" :
+                                       disp->size == 2 ? "short" : "int",
+                                       ival);
+                       }
+               }
+       }
+       *value_len = upto;
+       *valuep = value;
+       if (disp->verbose)
+               fprintf(stderr, "Value size %d\n", upto);
+       return 0;
+}
+
+static int store_key_value(void *blob, const char *node_name,
+               const char *property, const char *buf, int len)
+{
+       int node;
+       int err;
+
+       node = fdt_path_offset(blob, node_name);
+       if (node < 0) {
+               report_error(node_name, -1, node);
+               return -1;
+       }
+
+       err = fdt_setprop(blob, node, property, buf, len);
+       if (err) {
+               report_error(property, -1, err);
+               return -1;
+       }
+       return 0;
+}
+
+/**
+ * Create paths as needed for all components of a path
+ *
+ * Any components of the path that do not exist are created. Errors are
+ * reported.
+ *
+ * @param blob         FDT blob to write into
+ * @param in_path      Path to process
+ * @return 0 if ok, -1 on error
+ */
+static int create_paths(void *blob, const char *in_path)
+{
+       const char *path = in_path;
+       const char *sep;
+       int node, offset = 0;
+
+       /* skip leading '/' */
+       while (*path == '/')
+               path++;
+
+       for (sep = path; *sep; path = sep + 1, offset = node) {
+               /* equivalent to strchrnul(), but it requires _GNU_SOURCE */
+               sep = strchr(path, '/');
+               if (!sep)
+                       sep = path + strlen(path);
+
+               node = fdt_subnode_offset_namelen(blob, offset, path,
+                               sep - path);
+               if (node == -FDT_ERR_NOTFOUND) {
+                       node = fdt_add_subnode_namelen(blob, offset, path,
+                                                      sep - path);
+               }
+               if (node < 0) {
+                       report_error(path, sep - path, node);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * Create a new node in the fdt.
+ *
+ * This will overwrite the node_name string. Any error is reported.
+ *
+ * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this.
+ *
+ * @param blob         FDT blob to write into
+ * @param node_name    Name of node to create
+ * @return new node offset if found, or -1 on failure
+ */
+static int create_node(void *blob, const char *node_name)
+{
+       int node = 0;
+       char *p;
+
+       p = strrchr(node_name, '/');
+       if (!p) {
+               report_error(node_name, -1, -FDT_ERR_BADPATH);
+               return -1;
+       }
+       *p = '\0';
+
+       if (p > node_name) {
+               node = fdt_path_offset(blob, node_name);
+               if (node < 0) {
+                       report_error(node_name, -1, node);
+                       return -1;
+               }
+       }
+
+       node = fdt_add_subnode(blob, node, p + 1);
+       if (node < 0) {
+               report_error(p + 1, -1, node);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int do_fdtput(struct display_info *disp, const char *filename,
+                   char **arg, int arg_count)
+{
+       char *value;
+       char *blob;
+       int len, ret = 0;
+
+       blob = utilfdt_read(filename);
+       if (!blob)
+               return -1;
+
+       switch (disp->oper) {
+       case OPER_WRITE_PROP:
+               /*
+                * Convert the arguments into a single binary value, then
+                * store them into the property.
+                */
+               assert(arg_count >= 2);
+               if (disp->auto_path && create_paths(blob, *arg))
+                       return -1;
+               if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) ||
+                       store_key_value(blob, *arg, arg[1], value, len))
+                       ret = -1;
+               break;
+       case OPER_CREATE_NODE:
+               for (; ret >= 0 && arg_count--; arg++) {
+                       if (disp->auto_path)
+                               ret = create_paths(blob, *arg);
+                       else
+                               ret = create_node(blob, *arg);
+               }
+               break;
+       }
+       if (ret >= 0)
+               ret = utilfdt_write(filename, blob);
+
+       free(blob);
+       return ret;
+}
+
+static const char *usage_msg =
+       "fdtput - write a property value to a device tree\n"
+       "\n"
+       "The command line arguments are joined together into a single value.\n"
+       "\n"
+       "Usage:\n"
+       "       fdtput <options> <dt file> <node> <property> [<value>...]\n"
+       "       fdtput -c <options> <dt file> [<node>...]\n"
+       "Options:\n"
+       "\t-c\t\tCreate nodes if they don't already exist\n"
+       "\t-p\t\tAutomatically create nodes as needed for the node path\n"
+       "\t-t <type>\tType of data\n"
+       "\t-v\t\tVerbose: display each value decoded from command line\n"
+       "\t-h\t\tPrint this help\n\n"
+       USAGE_TYPE_MSG;
+
+static void usage(const char *msg)
+{
+       if (msg)
+               fprintf(stderr, "Error: %s\n\n", msg);
+
+       fprintf(stderr, "%s", usage_msg);
+       exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+       struct display_info disp;
+       char *filename = NULL;
+
+       memset(&disp, '\0', sizeof(disp));
+       disp.size = -1;
+       disp.oper = OPER_WRITE_PROP;
+       for (;;) {
+               int c = getopt(argc, argv, "chpt:v");
+               if (c == -1)
+                       break;
+
+               /*
+                * TODO: add options to:
+                * - delete property
+                * - delete node (optionally recursively)
+                * - rename node
+                * - pack fdt before writing
+                * - set amount of free space when writing
+                * - expand fdt if value doesn't fit
+                */
+               switch (c) {
+               case 'c':
+                       disp.oper = OPER_CREATE_NODE;
+                       break;
+               case 'h':
+               case '?':
+                       usage(NULL);
+               case 'p':
+                       disp.auto_path = 1;
+                       break;
+               case 't':
+                       if (utilfdt_decode_type(optarg, &disp.type,
+                                       &disp.size))
+                               usage("Invalid type string");
+                       break;
+
+               case 'v':
+                       disp.verbose = 1;
+                       break;
+               }
+       }
+
+       if (optind < argc)
+               filename = argv[optind++];
+       if (!filename)
+               usage("Missing filename");
+
+       argv += optind;
+       argc -= optind;
+
+       if (disp.oper == OPER_WRITE_PROP) {
+               if (argc < 1)
+                       usage("Missing node");
+               if (argc < 2)
+                       usage("Missing property");
+       }
+
+       if (do_fdtput(&disp, filename, argv, argc))
+               return 1;
+       return 0;
+}

Added: vendor/dtc/dist/libfdt/fdt_empty_tree.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor/dtc/dist/libfdt/fdt_empty_tree.c     Tue Jul 24 04:12:44 2012        
(r238737)
@@ -0,0 +1,84 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to