Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Feb 2013 17:23:23 -0800
From:      Tim Kientzle <tim@kientzle.com>
To:        David Chisnall <theraven@FreeBSD.org>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org
Subject:   Re: svn commit: r245803 - in head: . gnu/usr.bin share/man/man5 share/mk usr.bin/dtc
Message-ID:  <10F3BA43-0299-4492-8064-EBFAD7AC5AC7@kientzle.com>
In-Reply-To: <201301221749.r0MHnpbC053016@svn.freebsd.org>
References:  <201301221749.r0MHnpbC053016@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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
>=20
> 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.
>=20
>  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.
>=20
> 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
>=20
> Modified: head/Makefile.inc1
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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=3D cddl/usr.bin/sgsmsg cddl/
>     lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge
> .endif
>=20
> -.if ${MK_FDT} !=3D "no"
> +# Default to building the BSDL DTC, but build the GPL one if users =
explicitly
> +# request it.
> +_dtc=3D /usr.bin/dtc
> +.if ${MK_GPL_DTC} !=3D "no"
> _dtc=3D gnu/usr.bin/dtc
> .endif
>=20
>=20
> Modified: head/gnu/usr.bin/Makefile
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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=3D		groff
> _cvs=3D		cvs
> .endif
>=20
> -.if ${MK_FDT}	!=3D "no"
> +.if ${MK_GPL_DTC} !=3D "no"
> _dtc=3D		dtc
> .endif
>=20
>=20
> Modified: head/share/man/man5/src.conf.5
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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
>=20
> Modified: head/share/mk/bsd.own.mk
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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 =3D \
>     BSD_GREP \
>     CLANG_EXTRAS \
>     CTF \
> +    GPL_DTC \
>     HESIOD \
>     ICONV \
>     IDEA \
>=20
> Added: head/usr.bin/dtc/HACKING
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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
> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D
> +
> +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.
>=20
> Added: head/usr.bin/dtc/Makefile
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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=3Ddtc
> +SRCS=3D	dtc.cc input_buffer.cc string.cc dtb.cc fdt.cc =
checking.cc
> +MAN=3D	dtc.1
> +
> +WARNS?=3D	3
> +
> +NO_SHARED?=3DNO
> +
> +.include <bsd.prog.mk>
>=20
> Added: head/usr.bin/dtc/checking.cc
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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=3Dn->property_begin(), =
e=3Dn->property_end()
> +	     ; i!=3De ; ++i)
> +	{
> +		if (!check_property(tree, n, *i))
> +		{
> +			return false;
> +		}
> +	}
> +	// And then recursively check the children
> +	for (node::child_iterator i=3Dn->child_begin(), e=3Dn->child_end()=
 ; i!=3De ;
> +	     ++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=3Dpath.begin()+1, =
pe=3Dpath.end() ;
> +	     p!=3Dpe ; ++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() =3D=3D 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 =3D 0;
> +	for (property::value_iterator i=3Dp->begin(),e=3Dp->end() ; i!=3De=
 ; ++i)
> +	{
> +		if (!i->is_binary())
> +		{
> +			return false;
> +		}
> +		psize +=3D i->byte_data.size();
> +	}
> +	return psize =3D=3D 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() !=3D checkers.end())
> +	{
> +		delete checkers.begin()->second;
> +		checkers.erase(checkers.begin());
> +	}
> +	while (disabled_checkers.begin() !=3D 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 =3D true;
> +	for (std::map<string, checker*>::iterator i=3Dcheckers.begin(),
> +	     e=3Dcheckers.end() ; i!=3De ; ++i)
> +	{
> +		success &=3D 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 =3D =
checkers.find(name);
> +	if (checker !=3D 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 =3D
> +		disabled_checkers.find(name);
> +	if (checker !=3D 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
> +
>=20
> Added: head/usr.bin/dtc/checking.hh
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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.=20
> +	 */
> +	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=20
> +	 */
> +	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) =3D =
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) :=20=

> +		property_checker(name, property_name) {}
> +	virtual bool check(device_tree *tree, node *n, property *p) =3D =
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) :=20=

> +		property_checker(name, property_name) {}
> +	virtual bool check(device_tree *tree, node *n, property *p)
> +	{
> +		return p->begin() =3D=3D 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) :=20=

> +		property_checker(name, property_name) {}
> +	virtual bool check(device_tree *tree, node *n, property *p)
> +	{
> +		return (p->begin() + 1 =3D=3D 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) :=20=

> +		property_checker(name, property_name) {}
> +	virtual bool check(device_tree *tree, node *n, property *p)
> +	{
> +		for (property::value_iterator i=3Dp->begin(),e=3Dp->end() =
; i!=3De ;
> +		     ++i)
> +		{
> +			if (!(i->is_string() || i->is_string_list()))
> +			{
> +				return false;
> +			}
> +		}
> +		return p->begin() !=3D 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) :=20=

> +		property_checker(name, property_name) {}
> +	virtual bool check(device_tree *tree, node *n, property *p)
> +	{
> +		return (p->begin() + 1 =3D=3D p->end()) &&=20
> +			(tree->referenced_node(*p->begin()) !=3D 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. =20
> +	 */
> +	bool enable_checker(string name);
> +};
> +
> +} // namespace checking
> +
> +} // namespace fdt
> +
> +} // namespace dtc
> +
> +#endif // !_CHECKING_HH_
>=20
> Added: head/usr.bin/dtc/dtb.cc
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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=3Db.begin(), e=3Db.end(); i!=3De ; =
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 !=3D 0)
> +	{
> +		buffer.push_back(0);
> +	}
> +	push_big_endian(buffer, v);
> +}
> +
> +void
> +binary_writer::write_data(uint64_t v)
> +{
> +	while (buffer.size() % 8 !=3D 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 !=3D 0)
> +	{
> +		byte_count =3D 0;
> +		buffer.push_back('\n');
> +	}
> +	write_string(c);
> +}
> +
> +void
> +asm_writer::write_byte(uint8_t b)
> +{
> +	char out[3] =3D {0};
> +	if (byte_count++ =3D=3D 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 =3D=3D 4)
> +	{
> +		buffer.push_back('\n');
> +		byte_count =3D 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');
> +=09
> +}
> +
> +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 +=3D 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 !=3D 0)
> +	{
> +		write_line("\t.balign 4\n");
> +		bytes_written +=3D (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 +=3D 4;
> +}
> +
> +void
> +asm_writer::write_data(uint64_t v)
> +{
> +	if (bytes_written % 8 !=3D 0)
> +	{
> +		write_line("\t.balign 8\n");
> +		bytes_written +=3D (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 +=3D 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 =3D=3D 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 =3D =
string_offsets.find(str);
> +	if (old =3D=3D string_offsets.end())
> +	{
> +		uint32_t start =3D size;
> +		// Don't forget the trailing nul
> +		size +=3D 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=3Dstrings.begin(), =
e=3Dstrings.end() ;
> +	     i!=3De ; ++i)
> +	{
> +		writer.write_string(*i);
> +	}
> +	writer.write_label(string("dt_strings_end"));
> +}
> +
> +} // namespace dtb
> +
> +} // namespace dtc
> +
>=20
> Added: head/usr.bin/dtc/dtb.hh
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- /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_
>=20
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?10F3BA43-0299-4492-8064-EBFAD7AC5AC7>