svn commit: r245803 - in head: . gnu/usr.bin share/man/man5 share/mk usr.bin/dtc

Tim Kientzle tim at kientzle.com
Mon Feb 4 01:23:24 UTC 2013


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 ***



More information about the svn-src-head mailing list