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>