I'm finding it rather annoying that dtc isn't installed
on systems that use device trees.

Would there be any negative fallout from installing
/usr/bin/dtc as part of the regular world?

Tim

P.S. In particular, I'm moving away from compiled-in
device trees (in favor of having the loader read
it from a separate file) in part so that the device tree
file can be adjusted without having to recompile
the kernel.

On Jan 22, 2013, at 9:49 AM, David Chisnall wrote:

> Author: theraven
> Date: Tue Jan 22 17:49:51 2013
> New Revision: 245803
> URL: http://svnweb.freebsd.org/changeset/base/245803
> 
> Log:
>  Import new (BSDL) device tree compiler.  Now built by default, so that it 
> can't
>  be used on the host system (and not installed on the device, if required).  
> The
>  GPL'd one is still available if there are any devices that need it (make
>  universe passes with it, including kernels that use fdt, but there may be 
> some
>  out-of-tree ones).  WITH_GPL_DTC can be used to select the old one, for now.
> 
>  Probably won't be MFC'd, but we'll remove the GPL'd version in head after the
>  new one has had a lot more testing and ship it in 10.0.
> 
> Added:
>  head/usr.bin/dtc/
>  head/usr.bin/dtc/HACKING   (contents, props changed)
>  head/usr.bin/dtc/Makefile   (contents, props changed)
>  head/usr.bin/dtc/checking.cc   (contents, props changed)
>  head/usr.bin/dtc/checking.hh   (contents, props changed)
>  head/usr.bin/dtc/dtb.cc   (contents, props changed)
>  head/usr.bin/dtc/dtb.hh   (contents, props changed)
>  head/usr.bin/dtc/dtc.1   (contents, props changed)
>  head/usr.bin/dtc/dtc.cc   (contents, props changed)
>  head/usr.bin/dtc/fdt.cc   (contents, props changed)
>  head/usr.bin/dtc/fdt.hh   (contents, props changed)
>  head/usr.bin/dtc/input_buffer.cc   (contents, props changed)
>  head/usr.bin/dtc/input_buffer.hh   (contents, props changed)
>  head/usr.bin/dtc/string.cc   (contents, props changed)
>  head/usr.bin/dtc/string.hh   (contents, props changed)
>  head/usr.bin/dtc/util.hh   (contents, props changed)
> Modified:
>  head/Makefile.inc1
>  head/gnu/usr.bin/Makefile
>  head/share/man/man5/src.conf.5
>  head/share/mk/bsd.own.mk
> 
> Modified: head/Makefile.inc1
> ==============================================================================
> --- head/Makefile.inc1        Tue Jan 22 17:21:08 2013        (r245802)
> +++ head/Makefile.inc1        Tue Jan 22 17:49:51 2013        (r245803)
> @@ -1112,7 +1112,10 @@ _dtrace_tools= cddl/usr.bin/sgsmsg cddl/
>     lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge
> .endif
> 
> -.if ${MK_FDT} != "no"
> +# Default to building the BSDL DTC, but build the GPL one if users explicitly
> +# request it.
> +_dtc= /usr.bin/dtc
> +.if ${MK_GPL_DTC} != "no"
> _dtc= gnu/usr.bin/dtc
> .endif
> 
> 
> Modified: head/gnu/usr.bin/Makefile
> ==============================================================================
> --- head/gnu/usr.bin/Makefile Tue Jan 22 17:21:08 2013        (r245802)
> +++ head/gnu/usr.bin/Makefile Tue Jan 22 17:49:51 2013        (r245803)
> @@ -30,7 +30,7 @@ _groff=             groff
> _cvs=         cvs
> .endif
> 
> -.if ${MK_FDT}        != "no"
> +.if ${MK_GPL_DTC} != "no"
> _dtc=         dtc
> .endif
> 
> 
> Modified: head/share/man/man5/src.conf.5
> ==============================================================================
> --- head/share/man/man5/src.conf.5    Tue Jan 22 17:21:08 2013        
> (r245802)
> +++ head/share/man/man5/src.conf.5    Tue Jan 22 17:49:51 2013        
> (r245803)
> @@ -476,6 +476,9 @@ Set to not build GPIB bus support.
> Set to not build
> .Xr gpioctl 8
> as part of the base system.
> +.It Va WITH_GPL_DTC
> +Set to build the GPL'd version of the device tree compiler from elinux.org,
> +instead of the BSD licensed one.
> .It Va WITHOUT_GROFF
> .\" from FreeBSD: head/tools/build/options/WITHOUT_GROFF 218941 2011-02-22 
> 08:13:49Z uqs
> Set to not build
> 
> Modified: head/share/mk/bsd.own.mk
> ==============================================================================
> --- head/share/mk/bsd.own.mk  Tue Jan 22 17:21:08 2013        (r245802)
> +++ head/share/mk/bsd.own.mk  Tue Jan 22 17:49:51 2013        (r245803)
> @@ -364,6 +364,7 @@ __DEFAULT_NO_OPTIONS = \
>     BSD_GREP \
>     CLANG_EXTRAS \
>     CTF \
> +    GPL_DTC \
>     HESIOD \
>     ICONV \
>     IDEA \
> 
> Added: head/usr.bin/dtc/HACKING
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/HACKING  Tue Jan 22 17:49:51 2013        (r245803)
> @@ -0,0 +1,65 @@
> +$FreeBSD$
> +
> +Notes for people hacking on dtc
> +===============================
> +
> +This file contains some notes for people wishing to hack on dtc.
> +
> +Upstreaming
> +-----------
> +
> +This code is developed in the FreeBSD svn repository:
> +
> +https://svn.freebsd.org/base/head/usr.bin/dtc
> +
> +If you got the source from anywhere else and wish to make changes, please
> +ensure that you are working against the latest version, or you may end up
> +fixing bugs that are already fixed upstream.  Although the license makes no
> +requirement that you share any improvements that you make, patches are very
> +welcome.
> +
> +C++11
> +-----
> +
> +This project currently aims to compile with g++ 4.2.1 and so doesn't make any
> +use of C++11 features.  It would be a good idea to relax this restriction 
> once
> +clang is the default compiler for ARM, MIPS and PowerPC.
> +
> +This code makes use of a lot of iterator loops, which would be cleaner using
> +the new syntax in C++11.  It also explicitly deletes a lot of objects held in
> +collections in destructors that have these collections as their members.  
> This
> +could be simplified by using `shared_ptr`.
> +
> +The code does make use of `static_assert()`, but uses a macro in utility.hh 
> to
> +remove these if they are not supported.  The FreeBSD standard headers also
> +define a compatibility macro the implements static asserts in terms of an 
> array
> +with 1 element on success and -1 elements on failure.
> +
> +Adding New Checks
> +-----------------
> +
> +Currently, the biggest weakness of this version of the tool is that it lacks
> +most of the semantic checkers that can be implemented by simply reading the
> +ePAPR spec.  The `checker` class provides a simple superclass for 
> implementing
> +these quite easily.  There are also helper methods on `device_tree` for 
> finding
> +specific nodes, for checks that require some understanding of the structure 
> of
> +the tree.
> +
> +We should probably add a parent pointer to the `node` class for easily 
> walking
> +up the tree.
> +
> +Adding Direct C Output
> +----------------------
> +
> +The FreeBSD build system currently uses dtc to generate a blob and then
> +converts this to C source code.  A new `output_writer` subclass could easily
> +generate the C directly.
> +
> +Parser Improvements
> +-------------------
> +
> +There are a few FIXME lines in the parser for some corner cases that are not
> +currently used by FreeBSD.  These are mainly related to labels in the middle 
> of
> +values.  These can be fixed by creating a new `property_value` with the
> +specified label, starting at the location of the label.  Don't forget to 
> remove
> +the associated comments from the BUGS section of the man page if you fix 
> this.
> 
> Added: head/usr.bin/dtc/Makefile
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/Makefile Tue Jan 22 17:49:51 2013        (r245803)
> @@ -0,0 +1,11 @@
> +# $FreeBSD$
> +
> +PROG_CXX=dtc
> +SRCS=        dtc.cc input_buffer.cc string.cc dtb.cc fdt.cc checking.cc
> +MAN= dtc.1
> +
> +WARNS?=      3
> +
> +NO_SHARED?=NO
> +
> +.include <bsd.prog.mk>
> 
> Added: head/usr.bin/dtc/checking.cc
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/checking.cc      Tue Jan 22 17:49:51 2013        
> (r245803)
> @@ -0,0 +1,210 @@
> +/*-
> + * Copyright (c) 2013 David Chisnall
> + * All rights reserved.
> + *
> + * This software was developed by SRI International and the University of
> + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
> + * ("CTSRD"), as part of the DARPA CRASH research programme.
> + *
> + * 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 disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + * $FreeBSD$
> + */
> +
> +#include "checking.hh"
> +
> +namespace dtc
> +{
> +namespace fdt
> +{
> +namespace checking
> +{
> +
> +bool
> +checker::visit_node(device_tree *tree, node *n)
> +{
> +     path.push_back(std::make_pair(n->name, n->unit_address));
> +     // Check this node
> +     if (!check_node(tree, n))
> +     {
> +             return false;
> +     }
> +     // Now check its properties
> +     for (node::property_iterator i=n->property_begin(), e=n->property_end()
> +          ; i!=e ; ++i)
> +     {
> +             if (!check_property(tree, n, *i))
> +             {
> +                     return false;
> +             }
> +     }
> +     // And then recursively check the children
> +     for (node::child_iterator i=n->child_begin(), e=n->child_end() ; i!=e ;
> +          ++i)
> +     {
> +             if (!visit_node(tree, *i))
> +             {
> +                     return false;
> +             }
> +     }
> +     path.pop_back();
> +     return true;
> +}
> +
> +void
> +checker::report_error(const char *errmsg)
> +{
> +     fprintf(stderr, "Error: %s, while checking node: ", errmsg);
> +     for (device_tree::node_path::iterator p=path.begin()+1, pe=path.end() ;
> +          p!=pe ; ++p)
> +     {
> +             putc('/', stderr);
> +             p->first.dump();
> +             if (!(p->second.empty()))
> +             {
> +                     putc('@', stderr);
> +                     p->second.dump();
> +             }
> +     }
> +     fprintf(stderr, " [-W%s]\n", checker_name);
> +}
> +
> +bool
> +property_checker::check_property(device_tree *tree, node *n, property *p)
> +{
> +     if (p->get_key() == key)
> +     {
> +             if (!check(tree, n, p))
> +             {
> +                     report_error("property check failed");
> +                     return false;
> +             }
> +     }
> +     return true;
> +}
> +
> +bool
> +property_size_checker::check(device_tree *tree, node *n, property *p)
> +{
> +     uint32_t psize = 0;
> +     for (property::value_iterator i=p->begin(),e=p->end() ; i!=e ; ++i)
> +     {
> +             if (!i->is_binary())
> +             {
> +                     return false;
> +             }
> +             psize += i->byte_data.size();
> +     }
> +     return psize == size;
> +}
> +
> +template<property_value::value_type T>
> +void
> +check_manager::add_property_type_checker(const char *name, string prop)
> +{
> +     checkers.insert(std::make_pair(string(name),
> +             new property_type_checker<T>(name, prop)));
> +}
> +
> +void
> +check_manager::add_property_size_checker(const char *name,
> +                                         string prop,
> +                                         uint32_t size)
> +{
> +     checkers.insert(std::make_pair(string(name),
> +             new property_size_checker(name, prop, size)));
> +}
> +
> +check_manager::~check_manager()
> +{
> +     while (checkers.begin() != checkers.end())
> +     {
> +             delete checkers.begin()->second;
> +             checkers.erase(checkers.begin());
> +     }
> +     while (disabled_checkers.begin() != disabled_checkers.end())
> +     {
> +             delete disabled_checkers.begin()->second;
> +     }
> +}
> +
> +check_manager::check_manager()
> +{
> +     // NOTE: All checks listed here MUST have a corresponding line
> +     // in the man page!
> +     add_property_type_checker<property_value::STRING_LIST>(
> +                     "type-compatible", string("compatible"));
> +     add_property_type_checker<property_value::STRING>(
> +                     "type-model", string("model"));
> +     add_property_size_checker("type-phandle", string("phandle"), 4);
> +}
> +
> +bool
> +check_manager::run_checks(device_tree *tree, bool keep_going)
> +{
> +     bool success = true;
> +     for (std::map<string, checker*>::iterator i=checkers.begin(),
> +          e=checkers.end() ; i!=e ; ++i)
> +     {
> +             success &= i->second->check_tree(tree);
> +             if (!(success || keep_going))
> +             {
> +                     break;
> +             }
> +     }
> +     return success;
> +}
> +
> +bool
> +check_manager::disable_checker(string name)
> +{
> +     std::map<string, checker*>::iterator checker = checkers.find(name);
> +     if (checker != checkers.end())
> +     {
> +             disabled_checkers.insert(std::make_pair(name,
> +                                                     checker->second));
> +             checkers.erase(checker);
> +             return true;
> +     }
> +     return false;
> +}
> +
> +bool
> +check_manager::enable_checker(string name)
> +{
> +     std::map<string, checker*>::iterator checker =
> +             disabled_checkers.find(name);
> +     if (checker != disabled_checkers.end())
> +     {
> +             checkers.insert(std::make_pair(name, checker->second));
> +             disabled_checkers.erase(checker);
> +             return true;
> +     }
> +     return false;
> +}
> +
> +} // namespace checking
> +
> +} // namespace fdt
> +
> +} // namespace dtc
> +
> 
> Added: head/usr.bin/dtc/checking.hh
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/checking.hh      Tue Jan 22 17:49:51 2013        
> (r245803)
> @@ -0,0 +1,308 @@
> +/*-
> + * Copyright (c) 2013 David Chisnall
> + * All rights reserved.
> + *
> + * This software was developed by SRI International and the University of
> + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
> + * ("CTSRD"), as part of the DARPA CRASH research programme.
> + *
> + * 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 disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + * $FreeBSD$
> + */
> +
> +#ifndef _CHECKING_HH_
> +#define _CHECKING_HH_
> +#include "string.hh"
> +#include "fdt.hh"
> +
> +namespace dtc
> +{
> +namespace fdt
> +{
> +namespace checking
> +{
> +/**
> + * Base class for all checkers.  This will visit the entire tree and perform
> + * semantic checks defined in subclasses.  Note that device trees are 
> generally
> + * small (a few dozen nodes at most) and so we optimise for flexibility and
> + * extensibility here, not for performance.  Each checker will visit the 
> entire
> + * tree.
> + */
> +class checker
> +{
> +     /**
> +      * The path to the current node being checked.  This is used for
> +      * printing error messages.
> +      */
> +     device_tree::node_path path;
> +     /**
> +      * The name of the checker.  This is used for printing error messages
> +      * and for enabling / disabling specific checkers from the command
> +      * line. 
> +      */
> +     const char *checker_name;
> +     /**
> +      * Visits each node, calling the checker functions on properties and
> +      * nodes.
> +      */
> +     bool visit_node(device_tree *tree, node *n);
> +     protected:
> +     /**
> +      * Prints the error message, along with the path to the node that
> +      * caused the error and the name of the checker.
> +      */
> +     void report_error(const char *errmsg);
> +     public:
> +     /**
> +      * Constructor.  Takes the name of this checker, which is which is used
> +      * when reporting errors.
> +      */
> +     checker(const char *name) : checker_name(name) {}
> +     /**
> +      * Virtual destructor in case any subclasses need to do cleanup.
> +      */
> +     virtual ~checker() {}
> +     /**
> +      * Method for checking that a node is valid.  The root class version
> +      * does nothing, subclasses should override this.
> +      */
> +     virtual bool check_node(device_tree *tree, node *n)
> +     {
> +             return true;
> +     }
> +     /**
> +      * Method for checking that a property is valid.  The root class
> +      * version does nothing, subclasses should override this.
> +      */
> +     virtual bool check_property(device_tree *tree, node *n, property *p)
> +     {
> +             return true;
> +     }
> +     /**
> +      * Runs the checker on the specified device tree.
> +      */
> +     bool check_tree(fdt::device_tree *tree)
> +     {
> +             return visit_node(tree, tree->get_root());
> +     }
> +};
> +
> +/**
> + * Abstract base class for simple property checks.  This class defines a 
> check
> + * method for subclasses, which is invoked only when it finds a property with
> + * the matching name.  To define simple property checkers, just subclass this
> + * and override the check() method.
> + */
> +class property_checker : public checker
> +{
> +     /**
> +      * The name of the property that this checker is looking for.
> +      */
> +     string key;
> +     public:
> +     /**
> +      * Implementation of the generic property-checking method that checks
> +      * for a property with the name specified in the constructor 
> +      */
> +     virtual bool check_property(device_tree *tree, node *n, property *p);
> +     /**
> +      * Constructor.  Takes the name of the checker and the name of the
> +      * property to check.
> +      */
> +     property_checker(const char* name, string property_name)
> +             : checker(name), key(property_name) {}
> +     /**
> +      * The check method, which subclasses should implement.
> +      */
> +     virtual bool check(device_tree *tree, node *n, property *p) = 0;
> +};
> +
> +/**
> + * Property type checker.
> + */
> +template<property_value::value_type T>
> +struct property_type_checker : public property_checker
> +{
> +     /**
> +      * Constructor, takes the name of the checker and the name of the
> +      * property to check as arguments.
> +      */
> +     property_type_checker(const char* name, string property_name) : 
> +             property_checker(name, property_name) {}
> +     virtual bool check(device_tree *tree, node *n, property *p) = 0;
> +};
> +
> +/**
> + * Empty property checker.  This checks that the property has no value.
> + */
> +template<>
> +struct property_type_checker <property_value::EMPTY> : public 
> property_checker
> +{
> +     property_type_checker(const char* name, string property_name) : 
> +             property_checker(name, property_name) {}
> +     virtual bool check(device_tree *tree, node *n, property *p)
> +     {
> +             return p->begin() == p->end();
> +     }
> +};
> +
> +/**
> + * String property checker.  This checks that the property has exactly one
> + * value, which is a string.
> + */
> +template<>
> +struct property_type_checker <property_value::STRING> : public 
> property_checker
> +{
> +     property_type_checker(const char* name, string property_name) : 
> +             property_checker(name, property_name) {}
> +     virtual bool check(device_tree *tree, node *n, property *p)
> +     {
> +             return (p->begin() + 1 == p->end()) && p->begin()->is_string();
> +     }
> +};
> +/**
> + * String list property checker.  This checks that the property has at least
> + * one value, all of which are strings.
> + */
> +template<>
> +struct property_type_checker <property_value::STRING_LIST> :
> +     public property_checker
> +{
> +     property_type_checker(const char* name, string property_name) : 
> +             property_checker(name, property_name) {}
> +     virtual bool check(device_tree *tree, node *n, property *p)
> +     {
> +             for (property::value_iterator i=p->begin(),e=p->end() ; i!=e ;
> +                  ++i)
> +             {
> +                     if (!(i->is_string() || i->is_string_list()))
> +                     {
> +                             return false;
> +                     }
> +             }
> +             return p->begin() != p->end();
> +     }
> +};
> +
> +/**
> + * Phandle property checker.  This checks that the property has exactly one
> + * value, which is a valid phandle.
> + */
> +template<>
> +struct property_type_checker <property_value::PHANDLE> : public 
> property_checker
> +{
> +     property_type_checker(const char* name, string property_name) : 
> +             property_checker(name, property_name) {}
> +     virtual bool check(device_tree *tree, node *n, property *p)
> +     {
> +             return (p->begin() + 1 == p->end()) && 
> +                     (tree->referenced_node(*p->begin()) != 0);
> +     }
> +};
> +
> +/**
> + * Check that a property has the correct size.
> + */
> +struct property_size_checker : public property_checker
> +{
> +     /**
> +      * The expected size of the property.
> +      */
> +     uint32_t size;
> +     public:
> +     /**
> +      * Constructor, takes the name of the checker, the name of the property
> +      * to check, and its expected size as arguments.
> +      */
> +     property_size_checker(const char* name, string property_name, uint32_t 
> bytes)
> +             : property_checker(name, property_name), size(bytes) {}
> +     /**
> +      * Check, validates that the property has the correct size.
> +      */
> +     virtual bool check(device_tree *tree, node *n, property *p);
> +};
> +
> +
> +/**
> + * The check manager is the interface to running the checks.  This allows
> + * default checks to be enabled, non-default checks to be enabled, and so on.
> + */
> +class check_manager
> +{
> +     /**
> +      * The enabled checkers, indexed by their names.  The name is used when
> +      * disabling checkers from the command line.  When this manager runs,
> +      * it will only run the checkers from this map.
> +      */
> +     std::map<string, checker*> checkers;
> +     /**
> +      * The disabled checkers.  Moving checkers to this list disables them,
> +      * but allows them to be easily moved back.
> +      */
> +     std::map<string, checker*> disabled_checkers;
> +     /**
> +      * Helper function for adding a property value checker.
> +      */
> +     template<property_value::value_type T>
> +     void add_property_type_checker(const char *name, string prop);
> +     /**
> +      * Helper function for adding a simple type checker.
> +      */
> +     void add_property_type_checker(const char *name, string prop);
> +     /**
> +      * Helper function for adding a property value checker.
> +      */
> +     void add_property_size_checker(const char *name,
> +                                    string prop,
> +                                    uint32_t size);
> +     public:
> +     /**
> +      * Delete all of the checkers that are part of this checker manager.
> +      */
> +     ~check_manager();
> +     /**
> +      * Default constructor, creates check manager containing all of the
> +      * default checks.
> +      */
> +     check_manager();
> +     /**
> +      * Run all of the checks on the specified tree.
> +      */
> +     bool run_checks(device_tree *tree, bool keep_going);
> +     /**
> +      * Disables the named checker.
> +      */
> +     bool disable_checker(string name);
> +     /**
> +      * Enables the named checker.  
> +      */
> +     bool enable_checker(string name);
> +};
> +
> +} // namespace checking
> +
> +} // namespace fdt
> +
> +} // namespace dtc
> +
> +#endif // !_CHECKING_HH_
> 
> Added: head/usr.bin/dtc/dtb.cc
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/dtb.cc   Tue Jan 22 17:49:51 2013        (r245803)
> @@ -0,0 +1,308 @@
> +/*-
> + * Copyright (c) 2013 David Chisnall
> + * All rights reserved.
> + *
> + * This software was developed by SRI International and the University of
> + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
> + * ("CTSRD"), as part of the DARPA CRASH research programme.
> + *
> + * 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 disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + * $FreeBSD$
> + */
> +
> +#include "dtb.hh"
> +#include <inttypes.h>
> +
> +namespace dtc
> +{
> +namespace dtb
> +{
> +
> +void output_writer::write_data(byte_buffer b)
> +{
> +     for (byte_buffer::iterator i=b.begin(), e=b.end(); i!=e ; i++)
> +     {
> +             write_data(*i);
> +     }
> +}
> +
> +void
> +binary_writer::write_string(string name)
> +{
> +     name.push_to_buffer(buffer);
> +     // Trailing nul
> +     buffer.push_back(0);
> +}
> +
> +void
> +binary_writer::write_data(uint8_t v)
> +{
> +     buffer.push_back(v);
> +}
> +
> +void
> +binary_writer::write_data(uint32_t v)
> +{
> +     while (buffer.size() % 4 != 0)
> +     {
> +             buffer.push_back(0);
> +     }
> +     push_big_endian(buffer, v);
> +}
> +
> +void
> +binary_writer::write_data(uint64_t v)
> +{
> +     while (buffer.size() % 8 != 0)
> +     {
> +             buffer.push_back(0);
> +     }
> +     push_big_endian(buffer, v);
> +}
> +
> +void
> +binary_writer::write_to_file(int fd)
> +{
> +     // FIXME: Check return
> +     write(fd, buffer.data(), buffer.size());
> +}
> +
> +uint32_t
> +binary_writer::size()
> +{
> +     return buffer.size();
> +}
> +
> +void
> +asm_writer::write_string(const char *c)
> +{
> +     while (*c)
> +     {
> +             buffer.push_back((uint8_t)*(c++));
> +     }
> +}
> +
> +void
> +asm_writer::write_line(const char *c)
> +{
> +     if (byte_count != 0)
> +     {
> +             byte_count = 0;
> +             buffer.push_back('\n');
> +     }
> +     write_string(c);
> +}
> +
> +void
> +asm_writer::write_byte(uint8_t b)
> +{
> +     char out[3] = {0};
> +     if (byte_count++ == 0)
> +     {
> +             buffer.push_back('\t');
> +     }
> +     write_string(".byte 0x");
> +     snprintf(out, 3, "%.2hhx", b);
> +     buffer.push_back(out[0]);
> +     buffer.push_back(out[1]);
> +     if (byte_count == 4)
> +     {
> +             buffer.push_back('\n');
> +             byte_count = 0;
> +     }
> +     else
> +     {
> +             buffer.push_back(';');
> +             buffer.push_back(' ');
> +     }
> +}
> +
> +void
> +asm_writer::write_label(string name)
> +{
> +     write_line("\t.globl ");
> +     name.push_to_buffer(buffer);
> +     buffer.push_back('\n');
> +     name.push_to_buffer(buffer);
> +     buffer.push_back(':');
> +     buffer.push_back('\n');
> +     buffer.push_back('_');
> +     name.push_to_buffer(buffer);
> +     buffer.push_back(':');
> +     buffer.push_back('\n');
> +     
> +}
> +
> +void
> +asm_writer::write_comment(string name)
> +{
> +     write_line("\t/* ");
> +     name.push_to_buffer(buffer);
> +     write_string(" */\n");
> +}
> +
> +void
> +asm_writer::write_string(string name)
> +{
> +     write_line("\t.string \"");
> +     name.push_to_buffer(buffer);
> +     write_line("\"\n");
> +     bytes_written += name.size() + 1;
> +}
> +
> +void
> +asm_writer::write_data(uint8_t v)
> +{
> +     write_byte(v);
> +     bytes_written++;
> +}
> +
> +void
> +asm_writer::write_data(uint32_t v)
> +{
> +     if (bytes_written % 4 != 0)
> +     {
> +             write_line("\t.balign 4\n");
> +             bytes_written += (4 - (bytes_written % 4));
> +     }
> +     write_byte((v >> 24) & 0xff);
> +     write_byte((v >> 16) & 0xff);
> +     write_byte((v >> 8) & 0xff);
> +     write_byte((v >> 0) & 0xff);
> +     bytes_written += 4;
> +}
> +
> +void
> +asm_writer::write_data(uint64_t v)
> +{
> +     if (bytes_written % 8 != 0)
> +     {
> +             write_line("\t.balign 8\n");
> +             bytes_written += (8 - (bytes_written % 8));
> +     }
> +     write_byte((v >> 56) & 0xff);
> +     write_byte((v >> 48) & 0xff);
> +     write_byte((v >> 40) & 0xff);
> +     write_byte((v >> 32) & 0xff);
> +     write_byte((v >> 24) & 0xff);
> +     write_byte((v >> 16) & 0xff);
> +     write_byte((v >> 8) & 0xff);
> +     write_byte((v >> 0) & 0xff);
> +     bytes_written += 8;
> +}
> +
> +void
> +asm_writer::write_to_file(int fd)
> +{
> +     // FIXME: Check return
> +     write(fd, buffer.data(), buffer.size());
> +}
> +
> +uint32_t
> +asm_writer::size()
> +{
> +     return bytes_written;
> +}
> +
> +void
> +header::write(output_writer &out)
> +{
> +     out.write_label(string("dt_blob_start"));
> +     out.write_label(string("dt_header"));
> +     out.write_comment("magic");
> +     out.write_data(magic);
> +     out.write_comment("totalsize");
> +     out.write_data(totalsize);
> +     out.write_comment("off_dt_struct");
> +     out.write_data(off_dt_struct);
> +     out.write_comment("off_dt_strings");
> +     out.write_data(off_dt_strings);
> +     out.write_comment("off_mem_rsvmap");
> +     out.write_data(off_mem_rsvmap);
> +     out.write_comment("version");
> +     out.write_data(version);
> +     out.write_comment("last_comp_version");
> +     out.write_data(last_comp_version);
> +     out.write_comment("boot_cpuid_phys");
> +     out.write_data(boot_cpuid_phys);
> +     out.write_comment("size_dt_strings");
> +     out.write_data(size_dt_strings);
> +     out.write_comment("size_dt_struct");
> +     out.write_data(size_dt_struct);
> +}
> +
> +bool
> +header::read_dtb(input_buffer &input)
> +{
> +     if (!(input.consume_binary(magic) && magic == 0xd00dfeed))
> +     {
> +             fprintf(stderr, "Missing magic token in header.  Got %" PRIx32
> +                             " expected 0xd00dfeed\n", magic);
> +             return false;
> +     }
> +     return input.consume_binary(totalsize) &&
> +            input.consume_binary(off_dt_struct) &&
> +            input.consume_binary(off_dt_strings) &&
> +            input.consume_binary(off_mem_rsvmap) &&
> +            input.consume_binary(version) &&
> +            input.consume_binary(last_comp_version) &&
> +            input.consume_binary(boot_cpuid_phys) &&
> +            input.consume_binary(size_dt_strings) &&
> +            input.consume_binary(size_dt_struct);
> +}
> +uint32_t
> +string_table::add_string(string str)
> +{
> +     std::map<string, uint32_t>::iterator old = string_offsets.find(str);
> +     if (old == string_offsets.end())
> +     {
> +             uint32_t start = size;
> +             // Don't forget the trailing nul
> +             size += str.size() + 1;
> +             string_offsets.insert(std::make_pair(str, start));
> +             strings.push_back(str);
> +             return start;
> +     }
> +     else
> +     {
> +             return old->second;
> +     }
> +}
> +
> +void
> +string_table::write(dtb::output_writer &writer)
> +{
> +     writer.write_comment(string("Strings table."));
> +     writer.write_label(string("dt_strings_start"));
> +     for (std::vector<string>::iterator i=strings.begin(), e=strings.end() ;
> +          i!=e ; ++i)
> +     {
> +             writer.write_string(*i);
> +     }
> +     writer.write_label(string("dt_strings_end"));
> +}
> +
> +} // namespace dtb
> +
> +} // namespace dtc
> +
> 
> Added: head/usr.bin/dtc/dtb.hh
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/dtc/dtb.hh   Tue Jan 22 17:49:51 2013        (r245803)
> @@ -0,0 +1,365 @@
> +/*-
> + * Copyright (c) 2013 David Chisnall
> + * All rights reserved.
> + *
> + * This software was developed by SRI International and the University of
> + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
> + * ("CTSRD"), as part of the DARPA CRASH research programme.
> + *
> + * 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 disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *
> + * $FreeBSD$
> + */
> +
> +#ifndef _DTB_HH_
> 
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***

_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to