From owner-svn-src-head@freebsd.org Fri Apr 13 18:04:52 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 37D4DF9BB96; Fri, 13 Apr 2018 18:04:52 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E211B80064; Fri, 13 Apr 2018 18:04:51 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DD08C1D21E; Fri, 13 Apr 2018 18:04:51 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3DI4pjL079428; Fri, 13 Apr 2018 18:04:51 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3DI4pd6079424; Fri, 13 Apr 2018 18:04:51 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201804131804.w3DI4pd6079424@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Fri, 13 Apr 2018 18:04:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332483 - head/usr.bin/dtc X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: head/usr.bin/dtc X-SVN-Commit-Revision: 332483 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Apr 2018 18:04:52 -0000 Author: kevans Date: Fri Apr 13 18:04:51 2018 New Revision: 332483 URL: https://svnweb.freebsd.org/changeset/base/332483 Log: dtc(1): Update to upstream 006664a Highlights: - Passing "-" to -o will now cause output to go to stdout - Path-based syntactic sugar for overlays is now accepted. This looks like: /dts-v1/; /plugin/; &{/soc} { sid: eeprom@1c14000 { compatible = "allwinner,sun8i-h3-sid"; reg = <0x1c14000 0x400>; status = "okay"; }; }; MFC after: 3 days Modified: head/usr.bin/dtc/dtc.1 head/usr.bin/dtc/dtc.cc head/usr.bin/dtc/fdt.cc head/usr.bin/dtc/fdt.hh Modified: head/usr.bin/dtc/dtc.1 ============================================================================== --- head/usr.bin/dtc/dtc.1 Fri Apr 13 17:57:00 2018 (r332482) +++ head/usr.bin/dtc/dtc.1 Fri Apr 13 18:04:51 2018 (r332483) @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\"/ -.Dd January 17, 2018 +.Dd April 7, 2018 .Dt DTC 1 .Os .Sh NAME @@ -275,7 +275,7 @@ tree when the overlay is applied. .Pp Much simpler syntactic sugar was later invented to simplify generating overlays. Instead of creating targetted fragments manually, one can instead create a root -node that targets a label in the base node using the +node that targets a label in the base FDT using the .Va &label syntax supported in conventional DTS. This will indicate that a fragment should be generated for the node, with the @@ -283,6 +283,19 @@ given .Va label being the target, and the properties and child nodes will be used as the __overlay__. +.Pp +Additionally, a path-based version of this syntactic sugar is supported. +A root node may target a path in the base FDT using a name of the form +.Va &{/path} . +A fragment will be generated for the node as it is in the +.Va &label +case, except the +.Va target-path +property will be set to +.Va /path +and no +.Va target +will be set. .Pp Both conventional overlays and the later-added syntactic sugar are supported. .Pp Modified: head/usr.bin/dtc/dtc.cc ============================================================================== --- head/usr.bin/dtc/dtc.cc Fri Apr 13 17:57:00 2018 (r332482) +++ head/usr.bin/dtc/dtc.cc Fri Apr 13 18:04:51 2018 (r332483) @@ -171,11 +171,14 @@ main(int argc, char **argv) case 'o': { outfile_name = optarg; - outfile = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, 0666); - if (outfile == -1) + if (strcmp(outfile_name, "-") != 0) { - perror("Unable to open output file"); - return EXIT_FAILURE; + outfile = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (outfile == -1) + { + perror("Unable to open output file"); + return EXIT_FAILURE; + } } break; } Modified: head/usr.bin/dtc/fdt.cc ============================================================================== --- head/usr.bin/dtc/fdt.cc Fri Apr 13 17:57:00 2018 (r332482) +++ head/usr.bin/dtc/fdt.cc Fri Apr 13 18:04:51 2018 (r332483) @@ -727,14 +727,32 @@ node::parse_name(text_input_buffer &input, bool &is_pr return n; } -void -node::visit(std::function fn) +node::visit_behavior +node::visit(std::function fn, node *parent) { - fn(*this); - for (auto &&c : children) + visit_behavior behavior; + behavior = fn(*this, parent); + if (behavior == VISIT_BREAK) { - c->visit(fn); + return VISIT_BREAK; } + else if (behavior != VISIT_CONTINUE) + { + for (auto &&c : children) + { + behavior = c->visit(fn, this); + // Any status other than VISIT_RECURSE stops our execution and + // bubbles up to our caller. The caller may then either continue + // visiting nodes that are siblings to this one or completely halt + // visiting. + if (behavior != VISIT_RECURSE) + { + return behavior; + } + } + } + // Continue recursion by default + return VISIT_RECURSE; } node::node(input_buffer &structs, input_buffer &strings) : valid(true) @@ -1319,7 +1337,7 @@ device_tree::resolve_cross_references(uint32_t &phandl phandle_set.insert({&i.val, i}); } std::vector> sorted_phandles; - root->visit([&](node &n) { + root->visit([&](node &n, node *parent) { for (auto &p : n.properties()) { for (auto &v : *p) @@ -1331,7 +1349,9 @@ device_tree::resolve_cross_references(uint32_t &phandl } } } - }); + // Allow recursion + return node::VISIT_RECURSE; + }, nullptr); assert(sorted_phandles.size() == fixups.size()); for (auto &i : sorted_phandles) @@ -1471,9 +1491,24 @@ device_tree::parse_file(text_input_buffer &input, else if (input.consume('&')) { input.next_token(); - string name = input.parse_node_name(); + string name; + bool name_is_path_reference = false; + // This is to deal with names intended as path references, e.g. &{/path}. + // While it may make sense in a non-plugin context, we don't support such + // usage at this time. + if (input.consume('{') && is_plugin) + { + name = input.parse_to('}'); + input.consume('}'); + name_is_path_reference = true; + } + else + { + name = input.parse_node_name(); + } input.next_token(); n = node::parse(input, std::move(name), string_set(), string(), &defines); + n->name_is_path_reference = name_is_path_reference; } else { @@ -1702,11 +1737,21 @@ device_tree::create_fragment_wrapper(node_ptr &node, i node_ptr newroot = node::create_special_node("", symbols); node_ptr wrapper = node::create_special_node("__overlay__", symbols); - // Generate the fragment with target = <&name> + // Generate the fragment with $propname = <&name> property_value v; + std::string propname; v.string_data = node->name; - v.type = property_value::PHANDLE; - auto prop = std::make_shared(std::string("target")); + if (!node->name_is_path_reference) + { + propname = "target"; + v.type = property_value::PHANDLE; + } + else + { + propname = "target-path"; + v.type = property_value::STRING; + } + auto prop = std::make_shared(std::string(propname)); prop->add_value(v); symbols.push_back(prop); Modified: head/usr.bin/dtc/fdt.hh ============================================================================== --- head/usr.bin/dtc/fdt.hh Fri Apr 13 17:57:00 2018 (r332482) +++ head/usr.bin/dtc/fdt.hh Fri Apr 13 18:04:51 2018 (r332483) @@ -409,6 +409,10 @@ class node */ std::string name; /** + * The name of the node is a path reference. + */ + bool name_is_path_reference = false; + /** * The unit address of the node, which is optionally written after the * name followed by an at symbol. */ @@ -421,6 +425,25 @@ class node * Iterator type for child nodes. */ typedef std::vector::iterator child_iterator; + /** + * Recursion behavior to be observed for visiting + */ + enum visit_behavior + { + /** + * Recurse as normal through the rest of the tree. + */ + VISIT_RECURSE, + /** + * Continue recursing through the device tree, but do not + * recurse through this branch of the tree any further. + */ + VISIT_CONTINUE, + /** + * Immediately halt the visit. No further nodes will be visited. + */ + VISIT_BREAK + }; private: /** * Adaptor to use children in range-based for loops. @@ -635,9 +658,13 @@ class node */ void write_dts(FILE *file, int indent); /** - * Recursively visit this node and then its children. + * Recursively visit this node and then its children based on the + * callable's return value. The callable may return VISIT_BREAK + * immediately halt all recursion and end the visit, VISIT_CONTINUE to + * not recurse into the current node's children, or VISIT_RECURSE to recurse + * through children as expected. parent will be passed to the callable. */ - void visit(std::function); + visit_behavior visit(std::function, node *parent); }; /**