# Copyright (c) 2019 Nordic Semiconductor ASA
# Copyright (c) 2019 Linaro Limited
# SPDX-License-Identifier: BSD-3-Clause

# Tip: You can view just the documentation with 'pydoc3 edtlib'

"""
Library for working with devicetrees at a higher level compared to dtlib. Like
dtlib, this library presents a tree of devicetree nodes, but the nodes are
augmented with information from bindings and include some interpretation of
properties.

Bindings are files that describe devicetree nodes. Devicetree nodes are usually
mapped to bindings via their 'compatible = "..."' property, but a binding can
also come from a 'child-binding:' key in the binding for the parent devicetree
node.

Each devicetree node (dtlib.Node) gets a corresponding edtlib.Node instance,
which has all the information related to the node.

The top-level entry point of the library is the EDT class. EDT.__init__() takes
a .dts file to parse and a list of paths to directories containing bindings.
"""

# NOTE: testedtlib.py is the test suite for this library. It can be run
# directly as a script:
#
#   ./testedtlib.py

# Implementation notes
# --------------------
#
# A '_' prefix on an identifier in Python is a convention for marking it private.
# Please do not access private things. Instead, think of what API you need, and
# add it.
#
# This module is not meant to have any global state. It should be possible to
# create several EDT objects with independent binding paths and flags. If you
# need to add a configuration parameter or the like, store it in the EDT
# instance, and initialize it e.g. with a constructor argument.
#
# This library is layered on top of dtlib, and is not meant to expose it to
# clients. This keeps the header generation script simple.
#
# General biased advice:
#
# - Consider using @property for APIs that don't need parameters. It makes
#   functions look like attributes, which is less awkward in clients, and makes
#   it easy to switch back and forth between variables and functions.
#
# - Think about the data type of the thing you're exposing. Exposing something
#   as e.g. a list or a dictionary is often nicer and more flexible than adding
#   a function.
#
# - Avoid get_*() prefixes on functions. Name them after the thing they return
#   instead. This often makes the code read more naturally in callers.
#
#   Also, consider using @property instead of get_*().
#
# - Don't expose dtlib stuff directly.
#
# - Add documentation for any new APIs you add.
#
#   The convention here is that docstrings (quoted strings) are used for public
#   APIs, and "doc comments" for internal functions.
#
#   @properties are documented in the class docstring, as if they were
#   variables. See the existing @properties for a template.
#
# - Please use ""-quoted strings instead of ''-quoted strings, just to make
#   things consistent (''-quoting is more common otherwise in Python)

from collections import OrderedDict, defaultdict
import os
import re
import sys

import yaml
try:
    # Use the C LibYAML parser if available, rather than the Python parser.
    # This makes e.g. gen_defines.py more than twice as fast.
    from yaml import CLoader as Loader
except ImportError:
    from yaml import Loader

from dtlib import DT, DTError, to_num, to_nums, TYPE_EMPTY, TYPE_NUMS, \
                  TYPE_PHANDLE, TYPE_PHANDLES_AND_NUMS
from grutils import Graph


#
# Public classes
#


class EDT:
    """
    Represents a devicetree augmented with information from bindings.

    These attributes are available on EDT objects:

    nodes:
      A list of Node objects for the nodes that appear in the devicetree

    compat2enabled:
      A collections.defaultdict that maps each 'compatible' string that appears
      on some enabled Node to a list of enabled Nodes.

      For example, edt.compat2enabled["bar"] would include the 'foo' and 'bar'
      nodes below.

        foo {
                compatible = "bar";
                status = "okay";
                ...
        };
        bar {
                compatible = "foo", "bar", "baz";
                status = "okay";
                ...
        };

      This exists only for the sake of gen_legacy_defines.py. It will probably
      be removed following the Zephyr 2.3 release.

    compat2nodes:
      A collections.defaultdict that maps each 'compatible' string that appears
      on some Node to a list of Nodes with that compatible.

    compat2okay:
      Like compat2nodes, but just for nodes with status 'okay'.

    label2node:
      A collections.OrderedDict that maps a node label to the node with
      that label.

    chosen_nodes:
      A collections.OrderedDict that maps the properties defined on the
      devicetree's /chosen node to their values. 'chosen' is indexed by
      property name (a string), and values are converted to Node objects.
      Note that properties of the /chosen node which can't be converted
      to a Node are not included in the value.

    dts_path:
      The .dts path passed to __init__()

    dts_source:
      The final DTS source code of the loaded devicetree after merging nodes
      and processing /delete-node/ and /delete-property/, as a string

    bindings_dirs:
      The bindings directory paths passed to __init__()

    The standard library's pickle module can be used to marshal and
    unmarshal EDT objects.
    """
    def __init__(self, dts, bindings_dirs, warn_file=None,
                 warn_reg_unit_address_mismatch=True,
                 default_prop_types=True,
                 support_fixed_partitions_on_any_bus=True):
        """
        EDT constructor. This is the top-level entry point to the library.

        dts:
          Path to devicetree .dts file

        bindings_dirs:
          List of paths to directories containing bindings, in YAML format.
          These directories are recursively searched for .yaml files.

        warn_file (default: None):
          'file' object to write warnings to. If None, sys.stderr is used.

        warn_reg_unit_address_mismatch (default: True):
          If True, a warning is printed if a node has a 'reg' property where
          the address of the first entry does not match the unit address of the
          node

        default_prop_types (default: True):
          If True, default property types will be used when a node has no
          bindings.

        support_fixed_partitions_on_any_bus (default True):
          If True, set the Node.bus for 'fixed-partitions' compatible nodes
          to None.  This allows 'fixed-partitions' binding to match regardless
          of the bus the 'fixed-partition' is under.
        """
        # Do this indirection with None in case sys.stderr is
        # deliberately overridden. We'll only hold on to this file
        # while we're initializing.
        self._warn_file = sys.stderr if warn_file is None else warn_file

        self._warn_reg_unit_address_mismatch = warn_reg_unit_address_mismatch
        self._default_prop_types = default_prop_types
        self._fixed_partitions_no_bus = support_fixed_partitions_on_any_bus

        self.dts_path = dts
        self.bindings_dirs = bindings_dirs

        self._dt = DT(dts)
        _check_dt(self._dt)

        self._init_compat2binding(bindings_dirs)
        self._init_nodes()
        self._init_luts()

        self._define_order()

        # Drop the reference to the open warn file. This is necessary
        # to make this object pickleable, but also allows it to get
        # garbage collected and closed if nobody else is using it.
        self._warn_file = None

    def get_node(self, path):
        """
        Returns the Node at the DT path or alias 'path'. Raises EDTError if the
        path or alias doesn't exist.
        """
        try:
            return self._node2enode[self._dt.get_node(path)]
        except DTError as e:
            _err(e)

    @property
    def chosen_nodes(self):
        ret = OrderedDict()

        try:
            chosen = self._dt.get_node("/chosen")
        except DTError:
            return ret

        for name, prop in chosen.props.items():
            try:
                node = prop.to_path()
            except DTError:
                # DTS value is not phandle or string, or path doesn't exist
                continue

            ret[name] = self._node2enode[node]

        return ret

    def chosen_node(self, name):
        """
        Returns the Node pointed at by the property named 'name' in /chosen, or
        None if the property is missing
        """
        return self.chosen_nodes.get(name)

    @property
    def dts_source(self):
        return f"{self._dt}"

    def __repr__(self):
        return "<EDT for '{}', binding directories '{}'>".format(
            self.dts_path, self.bindings_dirs)

    def scc_order(self):
        """
        Returns a list of lists of Nodes where all elements of each list
        depend on each other, and the Nodes in any list do not depend
        on any Node in a subsequent list.  Each list defines a Strongly
        Connected Component (SCC) of the graph.

        For an acyclic graph each list will be a singleton.  Cycles
        will be represented by lists with multiple nodes.  Cycles are
        not expected to be present in devicetree graphs.
        """
        try:
            return self._graph.scc_order()
        except Exception as e:
            raise EDTError(e)

    def _define_order(self):
        # Constructs a graph of dependencies between Node instances,
        # then calculates a partial order over the dependencies.  The
        # algorithm supports detecting dependency loops.

        self._graph = Graph()

        for node in self.nodes:
            # A Node always depends on its parent.
            for child in node.children.values():
                self._graph.add_edge(child, node)

            # A Node depends on any Nodes present in 'phandle',
            # 'phandles', or 'phandle-array' property values.
            for prop in node.props.values():
                if prop.type == 'phandle':
                    self._graph.add_edge(node, prop.val)
                elif prop.type == 'phandles':
                    for phandle_node in prop.val:
                        self._graph.add_edge(node, phandle_node)
                elif prop.type == 'phandle-array':
                    for cd in prop.val:
                        self._graph.add_edge(node, cd.controller)

            # A Node depends on whatever supports the interrupts it
            # generates.
            for intr in node.interrupts:
                self._graph.add_edge(node, intr.controller)

        # Calculate an order that ensures no node is before any node
        # it depends on.  This sets the dep_ordinal field in each
        # Node.
        self.scc_order()

    def _init_compat2binding(self, bindings_dirs):
        # Creates self._compat2binding. This is a dictionary that maps
        # (<compatible>, <bus>) tuples (both strings) to (<binding>, <path>)
        # tuples. <binding> is the binding in parsed PyYAML format, and <path>
        # the path to the binding (nice for binding-related error messages).
        #
        # For example, self._compat2binding["company,dev", "can"] contains the
        # binding/path for the 'company,dev' device, when it appears on the CAN
        # bus.
        #
        # For bindings that don't specify a bus, <bus> is None, so that e.g.
        # self._compat2binding["company,notonbus", None] contains the binding.
        #
        # Only bindings for 'compatible' strings that appear in the devicetree
        # are loaded.

        dt_compats = _dt_compats(self._dt)
        # Searches for any 'compatible' string mentioned in the devicetree
        # files, with a regex
        dt_compats_search = re.compile(
            "|".join(re.escape(compat) for compat in dt_compats)
        ).search

        self._binding_paths = _binding_paths(bindings_dirs)

        self._compat2binding = {}
        for binding_path in self._binding_paths:
            with open(binding_path, encoding="utf-8") as f:
                contents = f.read()

            # As an optimization, skip parsing files that don't contain any of
            # the .dts 'compatible' strings, which should be reasonably safe
            if not dt_compats_search(contents):
                continue

            # Load the binding and check that it actually matches one of the
            # compatibles. Might get false positives above due to comments and
            # stuff.

            try:
                # Parsed PyYAML output (Python lists/dictionaries/strings/etc.,
                # representing the file)
                binding = yaml.load(contents, Loader=_BindingLoader)
            except yaml.YAMLError as e:
                self._warn("'{}' appears in binding directories but isn't "
                           "valid YAML: {}".format(binding_path, e))
                continue


            # Returns the string listed in 'compatible:' in 'binding', or None if
            # no compatible is found.

            if binding is None or "compatible" not in binding:
                # Empty file, binding fragment, spurious file, or old-style
                # compat
                binding_compat = None
            else:
                binding_compat = binding["compatible"]
                if not isinstance(binding_compat, str):
                    _err("malformed 'compatible: {}' field in {} - "
                         "should be a string, not {}"
                         .format(binding_compat, binding_path,
                                 type(binding_compat).__name__))


            if binding_compat not in dt_compats:
                # Either not a binding (binding_compat is None -- might be a
                # binding fragment or a spurious file), or a binding whose
                # compatible does not appear in the devicetree (picked up via
                # some unrelated text in the binding file that happened to
                # match a compatible)
                continue

            # It's a match. Merge in the included bindings, do sanity checks,
            # and register the binding.

            binding = self._merge_included_bindings(binding, binding_path)
            self._check_binding(binding, binding_path)

            on_bus = _on_bus_from_binding(binding)

            # Do not allow two different bindings to have the same
            # 'compatible:'/'on-bus:' combo
            old_binding = self._compat2binding.get((binding_compat, on_bus))
            if old_binding:
                msg = "both {} and {} have 'compatible: {}'".format(
                    old_binding[1], binding_path, binding_compat)
                if on_bus is not None:
                    msg += " and 'on-bus: {}'".format(on_bus)
                _err(msg)

            self._compat2binding[binding_compat, on_bus] = (binding, binding_path)

    def _merge_included_bindings(self, binding, binding_path):
        # Merges any bindings listed in the 'include:' section of 'binding'
        # into the top level of 'binding'.
        #
        # Properties in 'binding' take precedence over properties from included
        # bindings.

        fnames = []

        if "include" in binding:
            include = binding.pop("include")
            if isinstance(include, str):
                fnames.append(include)
            elif isinstance(include, list):
                if not all(isinstance(elm, str) for elm in include):
                    _err("all elements in 'include:' in {} should be strings"
                         .format(binding_path))
                fnames += include
            else:
                _err("'include:' in {} should be a string or a list of strings"
                     .format(binding_path))

        if "child-binding" in binding and "include" in binding["child-binding"]:
            self._merge_included_bindings(binding["child-binding"], binding_path)

        if not fnames:
            return binding

        # Got a list of included files in 'fnames'. Now we need to merge them
        # together and then merge them into 'binding'.

        # First, merge the included files together. If more than one included
        # file has a 'required:' for a particular property, OR the values
        # together, so that 'required: true' wins.

        merged_included = self._load_binding(fnames[0])
        for fname in fnames[1:]:
            included = self._load_binding(fname)
            _merge_props(merged_included, included, None, binding_path,
                         check_required=False)

        # Next, merge the merged included files into 'binding'. Error out if
        # 'binding' has 'required: false' while the merged included files have
        # 'required: true'.

        _merge_props(binding, merged_included, None, binding_path,
                     check_required=True)

        return binding

    def _load_binding(self, fname):
        # Returns the contents of the binding given by 'fname' after merging
        # any bindings it lists in 'include:' into it. 'fname' is just the
        # basename of the file, so we check that there aren't multiple
        # candidates.

        paths = [path for path in self._binding_paths
                 if os.path.basename(path) == fname]

        if not paths:
            _err("'{}' not found".format(fname))

        if len(paths) > 1:
            _err("multiple candidates for included file '{}': {}"
                 .format(fname, ", ".join(paths)))

        with open(paths[0], encoding="utf-8") as f:
            return self._merge_included_bindings(
                yaml.load(f, Loader=_BindingLoader),
                paths[0])

    def _init_nodes(self):
        # Creates a list of edtlib.Node objects from the dtlib.Node objects, in
        # self.nodes

        # Maps each dtlib.Node to its corresponding edtlib.Node
        self._node2enode = {}

        self.nodes = []

        for dt_node in self._dt.node_iter():
            # Warning: We depend on parent Nodes being created before their
            # children. This is guaranteed by node_iter().
            node = Node()
            node.edt = self
            node._node = dt_node
            if "compatible" in node._node.props:
                node.compats = node._node.props["compatible"].to_strings()
            else:
                node.compats = []
            node.bus_node = node._bus_node(self._fixed_partitions_no_bus)
            node._init_binding()
            node._init_regs()

            self.nodes.append(node)
            self._node2enode[dt_node] = node

        for node in self.nodes:
            # These depend on all Node objects having been created, because
            # they (either always or sometimes) reference other nodes, so we
            # run them separately
            node._init_props(default_prop_types=self._default_prop_types)
            node._init_interrupts()
            node._init_pinctrls()

        if self._warn_reg_unit_address_mismatch:
            # This warning matches the simple_bus_reg warning in dtc
            for node in self.nodes:
                if node.regs and node.regs[0].addr != node.unit_addr:
                    self._warn("unit address and first address in 'reg' "
                               f"(0x{node.regs[0].addr:x}) don't match for "
                               f"{node.path}")

    def _init_luts(self):
        # Initialize node lookup tables (LUTs).

        self.label2node = OrderedDict()
        self.compat2enabled = defaultdict(list)
        self.compat2nodes = defaultdict(list)
        self.compat2okay = defaultdict(list)

        for node in self.nodes:
            for label in node.labels:
                self.label2node[label] = node

            for compat in node.compats:
                self.compat2nodes[compat].append(node)

                if node.enabled:
                    self.compat2enabled[compat].append(node)

                if node.status == "okay":
                    self.compat2okay[compat].append(node)

    def _check_binding(self, binding, binding_path):
        # Does sanity checking on 'binding'. Only takes 'self' for the sake of
        # self._warn().

        if "description" not in binding:
            _err("missing 'description' property in " + binding_path)

        for prop in "title", "description":
            if prop in binding and (not isinstance(binding[prop], str) or
                                    not binding[prop]):
                _err("malformed or empty '{}' in {}"
                     .format(prop, binding_path))

        ok_top = {"title", "description", "compatible", "properties", "#cells",
                  "bus", "on-bus", "parent-bus", "child-bus", "parent", "child",
                  "child-binding", "sub-node"}

        for prop in binding:
            if prop not in ok_top and not prop.endswith("-cells"):
                _err("unknown key '{}' in {}, expected one of {}, or *-cells"
                     .format(prop, binding_path, ", ".join(ok_top)))

        for bus_key in "bus", "on-bus":
            if bus_key in binding and \
               not isinstance(binding[bus_key], str):
                _err("malformed '{}:' value in {}, expected string"
                     .format(bus_key, binding_path))

        self._check_binding_properties(binding, binding_path)

        if "child-binding" in binding:
            if not isinstance(binding["child-binding"], dict):
                _err("malformed 'child-binding:' in {}, expected a binding "
                     "(dictionary with keys/values)".format(binding_path))

            self._check_binding(binding["child-binding"], binding_path)

        def ok_cells_val(val):
            # Returns True if 'val' is an okay value for '*-cells:' (or the
            # legacy '#cells:')

            return isinstance(val, list) and \
                   all(isinstance(elm, str) for elm in val)

        for key, val in binding.items():
            if key.endswith("-cells") or key == "#cells":
                if not ok_cells_val(val):
                    _err("malformed '{}:' in {}, expected a list of strings"
                         .format(key, binding_path))

    def _check_binding_properties(self, binding, binding_path):
        # _check_binding() helper for checking the contents of 'properties:'.
        # Only takes 'self' for the sake of self._warn().

        if "properties" not in binding:
            return

        ok_prop_keys = {"description", "type", "required", "category",
                        "enum", "const", "default"}

        for prop_name, options in binding["properties"].items():
            for key in options:
                if key == "category":
                    self._warn(
                        "please put 'required: {}' instead of 'category: {}' "
                        "in properties: {}: ...' in {} - 'category' will be "
                        "removed".format(
                            "true" if options["category"] == "required"
                                else "false",
                            options["category"], prop_name, binding_path))

                if key not in ok_prop_keys:
                    _err("unknown setting '{}' in 'properties: {}: ...' in {}, "
                         "expected one of {}".format(
                             key, prop_name, binding_path,
                             ", ".join(ok_prop_keys)))

            _check_prop_type_and_default(
                prop_name, options.get("type"),
                options.get("required") or options.get("category") == "required",
                options.get("default"), binding_path)

            if "required" in options and not isinstance(options["required"], bool):
                _err("malformed 'required:' setting '{}' for '{}' in 'properties' "
                     "in {}, expected true/false"
                     .format(options["required"], prop_name, binding_path))

            if "description" in options and \
               not isinstance(options["description"], str):
                _err("missing, malformed, or empty 'description' for '{}' in "
                     "'properties' in {}".format(prop_name, binding_path))

            if "enum" in options and not isinstance(options["enum"], list):
                _err("enum in {} for property '{}' is not a list"
                     .format(binding_path, prop_name))

            if "const" in options and not isinstance(options["const"], (int, str)):
                _err("const in {} for property '{}' is not a scalar"
                     .format(binding_path, prop_name))

    def _warn(self, msg):
        if self._warn_file is not None:
            print("warning: " + msg, file=self._warn_file)
        else:
            raise _err("can't _warn() outside of EDT.__init__")


class Node:
    """
    Represents a devicetree node, augmented with information from bindings, and
    with some interpretation of devicetree properties. There's a one-to-one
    correspondence between devicetree nodes and Nodes.

    These attributes are available on Node objects:

    edt:
      The EDT instance this node is from

    name:
      The name of the node

    unit_addr:
      An integer with the ...@<unit-address> portion of the node name,
      translated through any 'ranges' properties on parent nodes, or None if
      the node name has no unit-address portion

    description:
      The description string from the binding for the node, or None if the node
      has no binding. Leading and trailing whitespace (including newlines) is
      removed.

    path:
      The devicetree path of the node

    label:
      The text from the 'label' property on the node, or None if the node has
      no 'label'

    labels:
      A list of all of the devicetree labels for the node, in the same order
      as the labels appear, but with duplicates removed.

      This corresponds to the actual devicetree source labels, unlike the
      "label" attribute, which is the value of a devicetree property named
      "label".

    parent:
      The Node instance for the devicetree parent of the Node, or None if the
      node is the root node

    children:
      A dictionary with the Node instances for the devicetree children of the
      node, indexed by name

    dep_ordinal:
      A non-negative integer value such that the value for a Node is
      less than the value for all Nodes that depend on it.

      The ordinal is defined for all Nodes including those that are not
      'enabled', and is unique among nodes in its EDT 'nodes' list.

    required_by:
      A list with the nodes that directly depend on the node

    depends_on:
      A list with the nodes that the node directly depends on

    status:
      The node's status property value, as a string, or "okay" if the node
      has no status property set. If the node's status property is "ok",
      it is converted to "okay" for consistency.

    enabled:
      True unless the node has 'status = "disabled"'

      This exists only for the sake of gen_legacy_defines.py. It will probably
      be removed following the Zephyr 2.3 release.

    read_only:
      True if the node has a 'read-only' property, and False otherwise

    matching_compat:
      The 'compatible' string for the binding that matched the node, or None if
      the node has no binding

    binding_path:
      The path to the binding file for the node, or None if the node has no
      binding

    compats:
      A list of 'compatible' strings for the node, in the same order that
      they're listed in the .dts file

    regs:
      A list of Register objects for the node's registers

    props:
      A collections.OrderedDict that maps property names to Property objects.
      Property objects are created for all devicetree properties on the node
      that are mentioned in 'properties:' in the binding.

    aliases:
      A list of aliases for the node. This is fetched from the /aliases node.

    interrupts:
      A list of ControllerAndData objects for the interrupts generated by the
      node. The list is empty if the node does not generate interrupts.

    pinctrls:
      A list of PinCtrl objects for the pinctrl-<index> properties on the
      node, sorted by index. The list is empty if the node does not have any
      pinctrl-<index> properties.

    bus:
      If the node is a bus node (has a 'bus:' key in its binding), then this
      attribute holds the bus type, e.g. "i2c" or "spi". If the node is not a
      bus node, then this attribute is None.

    on_bus:
      The bus the node appears on, e.g. "i2c" or "spi". The bus is determined
      by searching upwards for a parent node whose binding has a 'bus:' key,
      returning the value of the first 'bus:' key found. If none of the node's
      parents has a 'bus:' key, this attribute is None.

    bus_node:
      Like on_bus, but contains the Node for the bus controller, or None if the
      node is not on a bus.

    flash_controller:
      The flash controller for the node. Only meaningful for nodes representing
      flash partitions.

    spi_cs_gpio:
      The device's SPI GPIO chip select as a ControllerAndData instance, if it
      exists, and None otherwise. See
      Documentation/devicetree/bindings/spi/spi-controller.yaml in the Linux kernel.
    """
    @property
    def name(self):
        "See the class docstring"
        return self._node.name

    @property
    def unit_addr(self):
        "See the class docstring"

        # TODO: Return a plain string here later, like dtlib.Node.unit_addr?

        if "@" not in self.name:
            return None

        try:
            addr = int(self.name.split("@", 1)[1], 16)
        except ValueError:
            _err("{!r} has non-hex unit address".format(self))

        return _translate(addr, self._node)

    @property
    def description(self):
        "See the class docstring."
        if self._binding and "description" in self._binding:
            return self._binding["description"].strip()
        return None

    @property
    def path(self):
        "See the class docstring"
        return self._node.path

    @property
    def label(self):
        "See the class docstring"
        if "label" in self._node.props:
            return self._node.props["label"].to_string()
        return None

    @property
    def labels(self):
        "See the class docstring"
        return self._node.labels

    @property
    def parent(self):
        "See the class docstring"
        return self.edt._node2enode.get(self._node.parent)

    @property
    def children(self):
        "See the class docstring"
        # Could be initialized statically too to preserve identity, but not
        # sure if needed. Parent nodes being initialized before their children
        # would need to be kept in mind.
        return OrderedDict((name, self.edt._node2enode[node])
                           for name, node in self._node.nodes.items())

    @property
    def required_by(self):
        "See the class docstring"
        return self.edt._graph.required_by(self)

    @property
    def depends_on(self):
        "See the class docstring"
        return self.edt._graph.depends_on(self)

    @property
    def status(self):
        "See the class docstring"
        status = self._node.props.get("status")

        if status is None:
            as_string = "okay"
        else:
            as_string = status.to_string()

        if as_string == "ok":
            as_string = "okay"

        return as_string

    @property
    def enabled(self):
        "See the class docstring"
        return "status" not in self._node.props or self.status != "disabled"

    @property
    def read_only(self):
        "See the class docstring"
        return "read-only" in self._node.props

    @property
    def aliases(self):
        "See the class docstring"
        return [alias for alias, node in self._node.dt.alias2node.items()
                if node is self._node]

    @property
    def bus(self):
        "See the class docstring"
        binding = self._binding
        if not binding:
            return None

        if "bus" in binding:
            return binding["bus"]

        # Legacy key
        if "child-bus" in binding:
            return binding["child-bus"]

        # Legacy key
        if "child" in binding:
            # _check_binding() has checked that the "bus" key exists
            return binding["child"]["bus"]

        return None

    @property
    def on_bus(self):
        "See the class docstring"
        bus_node = self.bus_node
        return bus_node.bus if bus_node else None

    @property
    def flash_controller(self):
        "See the class docstring"

        # The node path might be something like
        # /flash-controller@4001E000/flash@0/partitions/partition@fc000. We go
        # up two levels to get the flash and check its compat. The flash
        # controller might be the flash itself (for cases like NOR flashes).
        # For the case of 'soc-nv-flash', we assume the controller is the
        # parent of the flash node.

        if not self.parent or not self.parent.parent:
            _err("flash partition {!r} lacks parent or grandparent node"
                 .format(self))

        controller = self.parent.parent
        if controller.matching_compat == "soc-nv-flash":
            return controller.parent
        return controller

    @property
    def spi_cs_gpio(self):
        "See the class docstring"

        if not (self.on_bus == "spi" and "cs-gpios" in self.bus_node.props):
            return None

        if not self.regs:
            _err("{!r} needs a 'reg' property, to look up the chip select index "
                 "for SPI".format(self))

        parent_cs_lst = self.bus_node.props["cs-gpios"].val

        # cs-gpios is indexed by the unit address
        cs_index = self.regs[0].addr
        if cs_index >= len(parent_cs_lst):
            _err("index from 'regs' in {!r} ({}) is >= number of cs-gpios "
                 "in {!r} ({})".format(
                     self, cs_index, self.bus_node, len(parent_cs_lst)))

        return parent_cs_lst[cs_index]

    def __repr__(self):
        return "<Node {} in '{}', {}>".format(
            self.path, self.edt.dts_path,
            "binding " + self.binding_path if self.binding_path
                else "no binding")

    def _init_binding(self):
        # Initializes Node.matching_compat, Node._binding, and
        # Node.binding_path.
        #
        # Node._binding holds the data from the node's binding file, in the
        # format returned by PyYAML (plain Python lists, dicts, etc.), or None
        # if the node has no binding.

        # This relies on the parent of the node having already been
        # initialized, which is guaranteed by going through the nodes in
        # node_iter() order.

        if self.compats:
            on_bus = self.on_bus

            for compat in self.compats:
                if (compat, on_bus) in self.edt._compat2binding:
                    # Binding found
                    self.matching_compat = compat
                    self._binding, self.binding_path = \
                        self.edt._compat2binding[compat, on_bus]

                    return
        else:
            # No 'compatible' property. See if the parent binding has a
            # 'child-binding:' key that gives the binding (or a legacy
            # 'sub-node:' key).

            binding_from_parent = self._binding_from_parent()
            if binding_from_parent:
                self._binding = binding_from_parent
                self.binding_path = self.parent.binding_path
                self.matching_compat = self.parent.matching_compat

                return

        # No binding found
        self._binding = self.binding_path = self.matching_compat = None

    def _binding_from_parent(self):
        # Returns the binding from 'child-binding:' in the parent node's
        # binding (or from the legacy 'sub-node:' key), or None if missing

        if not self.parent:
            return None

        pbinding = self.parent._binding
        if not pbinding:
            return None

        if "child-binding" in pbinding:
            return pbinding["child-binding"]

        # Backwards compatibility
        if "sub-node" in pbinding:
            return {"title": pbinding["title"],
                    "description": pbinding["description"],
                    "properties": pbinding["sub-node"]["properties"]}

        return None

    def _bus_node(self, support_fixed_partitions_on_any_bus = True):
        # Returns the value for self.bus_node. Relies on parent nodes being
        # initialized before their children.

        if not self.parent:
            # This is the root node
            return None

        # Treat 'fixed-partitions' as if they are not on any bus.  The reason is
        # that flash nodes might be on a SPI or controller or SoC bus.  Having
        # bus be None means we'll always match the binding for fixed-partitions
        # also this means want processing the fixed-partitions node we wouldn't
        # try to do anything bus specific with it.
        if support_fixed_partitions_on_any_bus and "fixed-partitions" in self.compats:
            return None

        if self.parent.bus:
            # The parent node is a bus node
            return self.parent

        # Same bus node as parent (possibly None)
        return self.parent.bus_node

    def _init_props(self, default_prop_types=False):
        # Creates self.props. See the class docstring. Also checks that all
        # properties on the node are declared in its binding.

        self.props = OrderedDict()

        node = self._node
        if self._binding:
            binding_props = self._binding.get("properties")
        else:
            binding_props = None

        # Initialize self.props
        if binding_props:
            for name, options in binding_props.items():
                self._init_prop(name, options)
            self._check_undeclared_props()
        elif default_prop_types:
            for name in node.props:
                if name in _DEFAULT_PROP_TYPES:
                    prop_type = _DEFAULT_PROP_TYPES[name]
                    val = self._prop_val(name, prop_type, False, None)
                    prop = Property()
                    prop.node = self
                    prop.name = name
                    prop.description = None
                    prop.val = val
                    prop.type = prop_type
                    # We don't set enum_index for "compatible"
                    prop.enum_index = None
                    self.props[name] = prop

    def _init_prop(self, name, options):
        # _init_props() helper for initializing a single property

        prop_type = options.get("type")
        if not prop_type:
            _err("'{}' in {} lacks 'type'".format(name, self.binding_path))

        val = self._prop_val(
            name, prop_type,
            options.get("required") or options.get("category") == "required",
            options.get("default"))

        if val is None:
            # 'required: false' property that wasn't there, or a property type
            # for which we store no data.
            return

        enum = options.get("enum")
        if enum and val not in enum:
            _err("value of property '{}' on {} in {} ({!r}) is not in 'enum' "
                 "list in {} ({!r})"
                 .format(name, self.path, self.edt.dts_path, val,
                         self.binding_path, enum))

        const = options.get("const")
        if const is not None and val != const:
            _err("value of property '{}' on {} in {} ({!r}) is different from "
                 "the 'const' value specified in {} ({!r})"
                 .format(name, self.path, self.edt.dts_path, val,
                         self.binding_path, const))

        # Skip properties that start with '#', like '#size-cells', and mapping
        # properties like 'gpio-map'/'interrupt-map'
        if name[0] == "#" or name.endswith("-map"):
            return

        prop = Property()
        prop.node = self
        prop.name = name
        prop.description = options.get("description")
        if prop.description:
            prop.description = prop.description.strip()
        prop.val = val
        prop.type = prop_type
        prop.enum_index = None if enum is None else enum.index(val)

        self.props[name] = prop

    def _prop_val(self, name, prop_type, required, default):
        # _init_prop() helper for getting the property's value
        #
        # name:
        #   Property name from binding
        #
        # prop_type:
        #   Property type from binding (a string like "int")
        #
        # optional:
        #   True if the property isn't required to exist
        #
        # default:
        #   Default value to use when the property doesn't exist, or None if
        #   the binding doesn't give a default value

        node = self._node
        prop = node.props.get(name)

        if not prop:
            if required and self.enabled:
                _err("'{}' is marked as required in 'properties:' in {}, but "
                     "does not appear in {!r}".format(
                         name, self.binding_path, node))

            if default is not None:
                # YAML doesn't have a native format for byte arrays. We need to
                # convert those from an array like [0x12, 0x34, ...]. The
                # format has already been checked in
                # _check_prop_type_and_default().
                if prop_type == "uint8-array":
                    return bytes(default)
                return default

            return False if prop_type == "boolean" else None

        if prop_type == "boolean":
            if prop.type is not TYPE_EMPTY:
                _err("'{0}' in {1!r} is defined with 'type: boolean' in {2}, "
                     "but is assigned a value ('{3}') instead of being empty "
                     "('{0};')".format(name, node, self.binding_path, prop))
            return True

        if prop_type == "int":
            return prop.to_num()

        if prop_type == "array":
            return prop.to_nums()

        if prop_type == "uint8-array":
            return prop.to_bytes()

        if prop_type == "string":
            return prop.to_string()

        if prop_type == "string-array":
            return prop.to_strings()

        if prop_type == "phandle":
            return self.edt._node2enode[prop.to_node()]

        if prop_type == "phandles":
            return [self.edt._node2enode[node] for node in prop.to_nodes()]

        if prop_type == "phandle-array":
            # This type is a bit high-level for dtlib as it involves
            # information from bindings and *-names properties, so there's no
            # to_phandle_array() in dtlib. Do the type check ourselves.
            if prop.type not in (TYPE_PHANDLE, TYPE_PHANDLES_AND_NUMS):
                _err("expected property '{0}' in {1} in {2} to be assigned "
                     "with '{0} = < &foo 1 2 ... &bar 3 4 ... >' (a mix of "
                     "phandles and numbers), not '{3}'"
                     .format(name, node.path, node.dt.filename, prop))

            return self._standard_phandle_val_list(prop)

        if prop_type == "path":
            return self.edt._node2enode[prop.to_path()]

        # prop_type == "compound". We have already checked that the 'type:'
        # value is valid, in _check_binding().
        #
        # 'compound' is a dummy type for properties that don't fit any of the
        # patterns above, so that we can require all entries in 'properties:'
        # to have a 'type: ...'. No Property object is created for it.
        return None

    def _check_undeclared_props(self):
        # Checks that all properties are declared in the binding

        if "properties" in self._binding:
            declared_props = self._binding["properties"].keys()
        else:
            declared_props = set()

        for prop_name in self._node.props:
            # Allow a few special properties to not be declared in the binding
            if prop_name.endswith("-controller") or \
               prop_name.startswith("#") or \
               prop_name.startswith("pinctrl-") or \
               prop_name in {
                   "compatible", "status", "ranges", "phandle",
                   "interrupt-parent", "interrupts-extended", "device_type"}:
                continue

            if prop_name not in declared_props:
                _err("'{}' appears in {} in {}, but is not declared in "
                     "'properties:' in {}"
                     .format(prop_name, self._node.path, self.edt.dts_path,
                             self.binding_path))

    def _init_regs(self):
        # Initializes self.regs

        node = self._node

        self.regs = []

        if "reg" not in node.props:
            return

        address_cells = _address_cells(node)
        size_cells = _size_cells(node)

        for raw_reg in _slice(node, "reg", 4*(address_cells + size_cells),
                              "4*(<#address-cells> (= {}) + <#size-cells> (= {}))"
                              .format(address_cells, size_cells)):
            reg = Register()
            reg.node = self
            if address_cells == 0:
                reg.addr = None
            else:
                reg.addr = _translate(to_num(raw_reg[:4*address_cells]), node)
            if size_cells == 0:
                reg.size = None
            else:
                reg.size = to_num(raw_reg[4*address_cells:])
            if size_cells != 0 and reg.size == 0:
                _err("zero-sized 'reg' in {!r} seems meaningless (maybe you "
                     "want a size of one or #size-cells = 0 instead)"
                     .format(self._node))

            self.regs.append(reg)

        _add_names(node, "reg", self.regs)

    def _init_pinctrls(self):
        # Initializes self.pinctrls from any pinctrl-<index> properties

        node = self._node

        # pinctrl-<index> properties
        pinctrl_props = [prop for name, prop in node.props.items()
                         if re.match("pinctrl-[0-9]+", name)]
        # Sort by index
        pinctrl_props.sort(key=lambda prop: prop.name)

        # Check indices
        for i, prop in enumerate(pinctrl_props):
            if prop.name != "pinctrl-" + str(i):
                _err("missing 'pinctrl-{}' property on {!r} - indices should "
                     "be contiguous and start from zero".format(i, node))

        self.pinctrls = []
        for prop in pinctrl_props:
            pinctrl = PinCtrl()
            pinctrl.node = self
            pinctrl.conf_nodes = [
                self.edt._node2enode[node] for node in prop.to_nodes()
            ]
            self.pinctrls.append(pinctrl)

        _add_names(node, "pinctrl", self.pinctrls)

    def _init_interrupts(self):
        # Initializes self.interrupts

        node = self._node

        self.interrupts = []

        for controller_node, data in _interrupts(node):
            interrupt = ControllerAndData()
            interrupt.node = self
            interrupt.controller = self.edt._node2enode[controller_node]
            interrupt.data = self._named_cells(interrupt.controller, data,
                                               "interrupt")

            self.interrupts.append(interrupt)

        _add_names(node, "interrupt", self.interrupts)

    def _standard_phandle_val_list(self, prop):
        # Parses a property like
        #
        #     <name>s = <phandle value phandle value ...>
        #     (e.g., pwms = <&foo 1 2 &bar 3 4>)
        #
        # , where each phandle points to a node that has a
        #
        #     #<name>-cells = <size>
        #
        # property that gives the number of cells in the value after the
        # phandle. These values are given names in *-cells in the binding for
        # the controller.
        #
        # Also parses any
        #
        #     <name>-names = "...", "...", ...
        #
        # Returns a list of ControllerAndData instances.

        if prop.name.endswith("gpios"):
            # There's some slight special-casing for *-gpios properties in that
            # e.g. foo-gpios still maps to #gpio-cells rather than
            # #foo-gpio-cells
            basename = "gpio"
        else:
            # Strip -s. We've already checked that the property names end in -s
            # in _check_binding().
            basename = prop.name[:-1]

        res = []

        for controller_node, data in _phandle_val_list(prop, basename):
            mapped_controller, mapped_data = \
                _map_phandle_array_entry(prop.node, controller_node, data,
                                         basename)

            entry = ControllerAndData()
            entry.node = self
            entry.controller = self.edt._node2enode[mapped_controller]
            entry.data = self._named_cells(entry.controller, mapped_data,
                                           basename)

            res.append(entry)

        _add_names(self._node, basename, res)

        return res

    def _named_cells(self, controller, data, basename):
        # Returns a dictionary that maps <basename>-cells names given in the
        # binding for 'controller' to cell values. 'data' is the raw data, as a
        # byte array.

        if not controller._binding:
            _err("{} controller {!r} for {!r} lacks binding"
                 .format(basename, controller._node, self._node))

        if basename + "-cells" in controller._binding:
            cell_names = controller._binding[basename + "-cells"]
        elif "#cells" in controller._binding:
            # Backwards compatibility
            cell_names = controller._binding["#cells"]
        else:
            # Treat no *-cells in the binding the same as an empty *-cells, so
            # that bindings don't have to have e.g. an empty 'clock-cells:' for
            # '#clock-cells = <0>'.
            cell_names = []

        data_list = to_nums(data)
        if len(data_list) != len(cell_names):
            _err("unexpected '{}-cells:' length in binding for {!r} - {} "
                 "instead of {}"
                 .format(basename, controller._node, len(cell_names),
                         len(data_list)))

        return OrderedDict(zip(cell_names, data_list))


class Register:
    """
    Represents a register on a node.

    These attributes are available on Register objects:

    node:
      The Node instance this register is from

    name:
      The name of the register as given in the 'reg-names' property, or None if
      there is no 'reg-names' property

    addr:
      The starting address of the register, in the parent address space, or None
      if #address-cells is zero. Any 'ranges' properties are taken into account.

    size:
      The length of the register in bytes
    """
    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)
        if self.addr is not None:
            fields.append("addr: " + hex(self.addr))
        if self.size is not None:
            fields.append("size: " + hex(self.size))

        return "<Register, {}>".format(", ".join(fields))


class ControllerAndData:
    """
    Represents an entry in an 'interrupts' or 'type: phandle-array' property
    value, e.g. <&ctrl-1 4 0> in

        cs-gpios = <&ctrl-1 4 0 &ctrl-2 3 4>;

    These attributes are available on ControllerAndData objects:

    node:
      The Node instance the property appears on

    controller:
      The Node instance for the controller (e.g. the controller the interrupt
      gets sent to for interrupts)

    data:
      A dictionary that maps names from the *-cells key in the binding for the
      controller to data values, e.g. {"pin": 4, "flags": 0} for the example
      above.

      'interrupts = <1 2>' might give {"irq": 1, "level": 2}.

    name:
      The name of the entry as given in
      'interrupt-names'/'gpio-names'/'pwm-names'/etc., or None if there is no
      *-names property
    """
    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)

        fields.append("controller: {}".format(self.controller))
        fields.append("data: {}".format(self.data))

        return "<ControllerAndData, {}>".format(", ".join(fields))


class PinCtrl:
    """
    Represents a pin control configuration for a set of pins on a device,
    e.g. pinctrl-0 or pinctrl-1.

    These attributes are available on PinCtrl objects:

    node:
      The Node instance the pinctrl-* property is on

    name:
      The name of the configuration, as given in pinctrl-names, or None if
      there is no pinctrl-names property

    conf_nodes:
      A list of Node instances for the pin configuration nodes, e.g.
      the nodes pointed at by &state_1 and &state_2 in

          pinctrl-0 = <&state_1 &state_2>;
    """
    def __repr__(self):
        fields = []

        if self.name is not None:
            fields.append("name: " + self.name)

        fields.append("configuration nodes: " + str(self.conf_nodes))

        return "<PinCtrl, {}>".format(", ".join(fields))


class Property:
    """
    Represents a property on a Node, as set in its DT node and with
    additional info from the 'properties:' section of the binding.

    Only properties mentioned in 'properties:' get created. Properties of type
    'compound' currently do not get Property instances, as I'm not sure what
    information to store for them.

    These attributes are available on Property objects:

    node:
      The Node instance the property is on

    name:
      The name of the property

    description:
      The description string from the property as given in the binding, or None
      if missing. Leading and trailing whitespace (including newlines) is
      removed.

    type:
      A string with the type of the property, as given in the binding.

    val:
      The value of the property, with the format determined by the 'type:' key
      from the binding.

        - For 'type: int/array/string/string-array', 'val' is what you'd expect
          (a Python integer or string, or a list of them)

        - For 'type: phandle' and 'type: path', 'val' is the pointed-to Node
          instance

        - For 'type: phandles', 'val' is a list of the pointed-to Node
          instances

        - For 'type: phandle-array', 'val' is a list of ControllerAndData
          instances. See the documentation for that class.

    enum_index:
      The index of the property's value in the 'enum:' list in the binding, or
      None if the binding has no 'enum:'
    """
    def __repr__(self):
        fields = ["name: " + self.name,
                  # repr() to deal with lists
                  "type: " + self.type,
                  "value: " + repr(self.val)]

        if self.enum_index is not None:
            fields.append("enum index: {}".format(self.enum_index))

        return "<Property, {}>".format(", ".join(fields))


class EDTError(Exception):
    "Exception raised for devicetree- and binding-related errors"


#
# Private global functions
#


def _dt_compats(dt):
    # Returns a set() with all 'compatible' strings in the devicetree
    # represented by dt (a dtlib.DT instance)

    return {compat
            for node in dt.node_iter()
                if "compatible" in node.props
                    for compat in node.props["compatible"].to_strings()}


def _binding_paths(bindings_dirs):
    # Returns a list with the paths to all bindings (.yaml files) in
    # 'bindings_dirs'

    binding_paths = []

    for bindings_dir in bindings_dirs:
        for root, _, filenames in os.walk(bindings_dir):
            for filename in filenames:
                if filename.endswith(".yaml"):
                    binding_paths.append(os.path.join(root, filename))

    return binding_paths


def _on_bus_from_binding(binding):
    # Returns the bus specified by 'on-bus:' in the binding (or the
    # legacy 'parent-bus:' and 'parent: bus:'), or None if missing

    if not binding:
        return None

    if "on-bus" in binding:
        return binding["on-bus"]

    # Legacy key
    if "parent-bus" in binding:
        return binding["parent-bus"]

    # Legacy key
    if "parent" in binding:
        # _check_binding() has checked that the "bus" key exists
        return binding["parent"]["bus"]

    return None


def _binding_inc_error(msg):
    # Helper for reporting errors in the !include implementation

    raise yaml.constructor.ConstructorError(None, None, "error: " + msg)


def _merge_props(to_dict, from_dict, parent, binding_path, check_required):
    # Recursively merges 'from_dict' into 'to_dict', to implement 'include:'.
    #
    # If 'from_dict' and 'to_dict' contain a 'required:' key for the same
    # property, then the values are ORed together.
    #
    # If 'check_required' is True, then an error is raised if 'from_dict' has
    # 'required: true' while 'to_dict' has 'required: false'. This prevents
    # bindings from "downgrading" requirements from bindings they include,
    # which might help keep bindings well-organized.
    #
    # It's an error for most other keys to appear in both 'from_dict' and
    # 'to_dict'. When it's not an error, the value in 'to_dict' takes
    # precedence.
    #
    # 'parent' is the name of the parent key containing 'to_dict' and
    # 'from_dict', and 'binding_path' is the path to the top-level binding.
    # These are used to generate errors for sketchy property overwrites.

    for prop in from_dict:
        if isinstance(to_dict.get(prop), dict) and \
           isinstance(from_dict[prop], dict):
            _merge_props(to_dict[prop], from_dict[prop], prop, binding_path,
                         check_required)
        elif prop not in to_dict:
            to_dict[prop] = from_dict[prop]
        elif _bad_overwrite(to_dict, from_dict, prop, check_required):
            _err("{} (in '{}'): '{}' from included file overwritten "
                 "('{}' replaced with '{}')".format(
                     binding_path, parent, prop, from_dict[prop],
                     to_dict[prop]))
        elif prop == "required":
            # Need a separate check here, because this code runs before
            # _check_binding()
            if not (isinstance(from_dict["required"], bool) and
                    isinstance(to_dict["required"], bool)):
                _err("malformed 'required:' setting for '{}' in 'properties' "
                     "in {}, expected true/false".format(parent, binding_path))

            # 'required: true' takes precedence
            to_dict["required"] = to_dict["required"] or from_dict["required"]
        elif prop == "category":
            # Legacy property key. 'category: required' takes precedence.
            if "required" in (to_dict["category"], from_dict["category"]):
                to_dict["category"] = "required"


def _bad_overwrite(to_dict, from_dict, prop, check_required):
    # _merge_props() helper. Returns True in cases where it's bad that
    # to_dict[prop] takes precedence over from_dict[prop].

    if to_dict[prop] == from_dict[prop]:
        return False

    # These are overridden deliberately
    if prop in {"title", "description", "compatible"}:
        return False

    if prop == "required":
        if not check_required:
            return False
        return from_dict[prop] and not to_dict[prop]

    # Legacy property key
    if prop == "category":
        if not check_required:
            return False
        return from_dict[prop] == "required" and to_dict[prop] == "optional"

    return True


def _binding_include(loader, node):
    # Implements !include, for backwards compatibility. '!include [foo, bar]'
    # just becomes [foo, bar].

    if isinstance(node, yaml.ScalarNode):
        # !include foo.yaml
        return [loader.construct_scalar(node)]

    if isinstance(node, yaml.SequenceNode):
        # !include [foo.yaml, bar.yaml]
        return loader.construct_sequence(node)

    _binding_inc_error("unrecognised node type in !include statement")


def _check_prop_type_and_default(prop_name, prop_type, required, default,
                                 binding_path):
    # _check_binding() helper. Checks 'type:' and 'default:' for the property
    # named 'prop_name'

    if prop_type is None:
        _err("missing 'type:' for '{}' in 'properties' in {}"
             .format(prop_name, binding_path))

    ok_types = {"boolean", "int", "array", "uint8-array", "string",
                "string-array", "phandle", "phandles", "phandle-array",
                "path", "compound"}

    if prop_type not in ok_types:
        _err("'{}' in 'properties:' in {} has unknown type '{}', expected one "
             "of {}".format(prop_name, binding_path, prop_type,
                            ", ".join(ok_types)))

    if prop_type == "phandle-array" and not prop_name.endswith("s"):
        _err("'{}' in 'properties:' in {} is 'type: phandle-array', but its "
             "name does not end in -s. This is required since property names "
             "like '#pwm-cells' and 'pwm-names' get derived from 'pwms', for "
             "example.".format(prop_name, binding_path))

    # Check default

    if default is None:
        return

    if prop_type in {"boolean", "compound", "phandle", "phandles",
                     "phandle-array", "path"}:
        _err("'default:' can't be combined with 'type: {}' for '{}' in "
             "'properties:' in {}".format(prop_type, prop_name, binding_path))

    def ok_default():
        # Returns True if 'default' is an okay default for the property's type

        if prop_type == "int" and isinstance(default, int) or \
           prop_type == "string" and isinstance(default, str):
            return True

        # array, uint8-array, or string-array

        if not isinstance(default, list):
            return False

        if prop_type == "array" and \
           all(isinstance(val, int) for val in default):
            return True

        if prop_type == "uint8-array" and \
           all(isinstance(val, int) and 0 <= val <= 255 for val in default):
            return True

        # string-array
        return all(isinstance(val, str) for val in default)

    if not ok_default():
        _err("'default: {}' is invalid for '{}' in 'properties:' in {}, which "
             "has type {}".format(default, prop_name, binding_path, prop_type))


def _translate(addr, node):
    # Recursively translates 'addr' on 'node' to the address space(s) of its
    # parent(s), by looking at 'ranges' properties. Returns the translated
    # address.
    #
    # node:
    #   dtlib.Node instance

    if not node.parent or "ranges" not in node.parent.props:
        # No translation
        return addr

    if not node.parent.props["ranges"].value:
        # DT spec.: "If the property is defined with an <empty> value, it
        # specifies that the parent and child address space is identical, and
        # no address translation is required."
        #
        # Treat this the same as a 'range' that explicitly does a one-to-one
        # mapping, as opposed to there not being any translation.
        return _translate(addr, node.parent)

    # Gives the size of each component in a translation 3-tuple in 'ranges'
    child_address_cells = _address_cells(node)
    parent_address_cells = _address_cells(node.parent)
    child_size_cells = _size_cells(node)

    # Number of cells for one translation 3-tuple in 'ranges'
    entry_cells = child_address_cells + parent_address_cells + child_size_cells

    for raw_range in _slice(node.parent, "ranges", 4*entry_cells,
                            "4*(<#address-cells> (= {}) + "
                            "<#address-cells for parent> (= {}) + "
                            "<#size-cells> (= {}))"
                            .format(child_address_cells, parent_address_cells,
                                    child_size_cells)):
        child_addr = to_num(raw_range[:4*child_address_cells])
        raw_range = raw_range[4*child_address_cells:]

        parent_addr = to_num(raw_range[:4*parent_address_cells])
        raw_range = raw_range[4*parent_address_cells:]

        child_len = to_num(raw_range)

        if child_addr <= addr < child_addr + child_len:
            # 'addr' is within range of a translation in 'ranges'. Recursively
            # translate it and return the result.
            return _translate(parent_addr + addr - child_addr, node.parent)

    # 'addr' is not within range of any translation in 'ranges'
    return addr


def _add_names(node, names_ident, objs):
    # Helper for registering names from <foo>-names properties.
    #
    # node:
    #   edtlib.Node instance
    #
    # names-ident:
    #   The <foo> part of <foo>-names, e.g. "reg" for "reg-names"
    #
    # objs:
    #   list of objects whose .name field should be set

    full_names_ident = names_ident + "-names"

    if full_names_ident in node.props:
        names = node.props[full_names_ident].to_strings()
        if len(names) != len(objs):
            _err("{} property in {} in {} has {} strings, expected {} strings"
                 .format(full_names_ident, node.path, node.dt.filename,
                         len(names), len(objs)))

        for obj, name in zip(objs, names):
            obj.name = name
    else:
        for obj in objs:
            obj.name = None


def _interrupt_parent(node):
    # Returns the node pointed at by the closest 'interrupt-parent', searching
    # the parents of 'node'. As of writing, this behavior isn't specified in
    # the DT spec., but seems to match what some .dts files except.

    while node:
        if "interrupt-parent" in node.props:
            return node.props["interrupt-parent"].to_node()
        node = node.parent

    _err("{!r} has an 'interrupts' property, but neither the node nor any "
         "of its parents has an 'interrupt-parent' property".format(node))


def _interrupts(node):
    # Returns a list of (<controller>, <data>) tuples, with one tuple per
    # interrupt generated by 'node'. <controller> is the destination of the
    # interrupt (possibly after mapping through an 'interrupt-map'), and <data>
    # the data associated with the interrupt (as a 'bytes' object).

    # Takes precedence over 'interrupts' if both are present
    if "interrupts-extended" in node.props:
        prop = node.props["interrupts-extended"]
        return [_map_interrupt(node, iparent, spec)
                for iparent, spec in _phandle_val_list(prop, "interrupt")]

    if "interrupts" in node.props:
        # Treat 'interrupts' as a special case of 'interrupts-extended', with
        # the same interrupt parent for all interrupts

        iparent = _interrupt_parent(node)
        interrupt_cells = _interrupt_cells(iparent)

        return [_map_interrupt(node, iparent, raw)
                for raw in _slice(node, "interrupts", 4*interrupt_cells,
                                  "4*<#interrupt-cells>")]

    return []


def _map_interrupt(child, parent, child_spec):
    # Translates an interrupt headed from 'child' to 'parent' with data
    # 'child_spec' through any 'interrupt-map' properties. Returns a
    # (<controller>, <data>) tuple with the final destination after mapping.

    if "interrupt-controller" in parent.props:
        return (parent, child_spec)

    def own_address_cells(node):
        # Used for parents pointed at by 'interrupt-map'. We can't use
        # _address_cells(), because it's the #address-cells property on 'node'
        # itself that matters.

        address_cells = node.props.get("#address-cells")
        if not address_cells:
            _err("missing #address-cells on {!r} (while handling interrupt-map)"
                 .format(node))
        return address_cells.to_num()

    def spec_len_fn(node):
        # Can't use _address_cells() here, because it's the #address-cells
        # property on 'node' itself that matters
        return own_address_cells(node) + _interrupt_cells(node)

    parent, raw_spec = _map(
        "interrupt", child, parent, _raw_unit_addr(child) + child_spec,
        spec_len_fn, require_controller=True)

    # Strip the parent unit address part, if any
    return (parent, raw_spec[4*own_address_cells(parent):])


def _map_phandle_array_entry(child, parent, child_spec, basename):
    # Returns a (<controller>, <data>) tuple with the final destination after
    # mapping through any '<basename>-map' (e.g. gpio-map) properties. See
    # _map_interrupt().

    def spec_len_fn(node):
        prop_name = "#{}-cells".format(basename)
        if prop_name not in node.props:
            _err("expected '{}' property on {!r} (referenced by {!r})"
                 .format(prop_name, node, child))
        return node.props[prop_name].to_num()

    # Do not require <prefix>-controller for anything but interrupts for now
    return _map(basename, child, parent, child_spec, spec_len_fn,
                require_controller=False)


def _map(prefix, child, parent, child_spec, spec_len_fn, require_controller):
    # Common code for mapping through <prefix>-map properties, e.g.
    # interrupt-map and gpio-map.
    #
    # prefix:
    #   The prefix, e.g. "interrupt" or "gpio"
    #
    # child:
    #   The "sender", e.g. the node with 'interrupts = <...>'
    #
    # parent:
    #   The "receiver", e.g. a node with 'interrupt-map = <...>' or
    #   'interrupt-controller' (no mapping)
    #
    # child_spec:
    #   The data associated with the interrupt/GPIO/etc., as a 'bytes' object,
    #   e.g. <1 2> for 'foo-gpios = <&gpio1 1 2>'.
    #
    # spec_len_fn:
    #   Function called on a parent specified in a *-map property to get the
    #   length of the parent specifier (data after phandle in *-map), in cells
    #
    # require_controller:
    #   If True, the final controller node after mapping is required to have
    #   to have a <prefix>-controller property.

    map_prop = parent.props.get(prefix + "-map")
    if not map_prop:
        if require_controller and prefix + "-controller" not in parent.props:
            _err("expected '{}-controller' property on {!r} "
                 "(referenced by {!r})".format(prefix, parent, child))

        # No mapping
        return (parent, child_spec)

    masked_child_spec = _mask(prefix, child, parent, child_spec)

    raw = map_prop.value
    while raw:
        if len(raw) < len(child_spec):
            _err("bad value for {!r}, missing/truncated child data"
                 .format(map_prop))
        child_spec_entry = raw[:len(child_spec)]
        raw = raw[len(child_spec):]

        if len(raw) < 4:
            _err("bad value for {!r}, missing/truncated phandle"
                 .format(map_prop))
        phandle = to_num(raw[:4])
        raw = raw[4:]

        # Parent specified in *-map
        map_parent = parent.dt.phandle2node.get(phandle)
        if not map_parent:
            _err("bad phandle ({}) in {!r}".format(phandle, map_prop))

        map_parent_spec_len = 4*spec_len_fn(map_parent)
        if len(raw) < map_parent_spec_len:
            _err("bad value for {!r}, missing/truncated parent data"
                 .format(map_prop))
        parent_spec = raw[:map_parent_spec_len]
        raw = raw[map_parent_spec_len:]

        # Got one *-map row. Check if it matches the child data.
        if child_spec_entry == masked_child_spec:
            # Handle *-map-pass-thru
            parent_spec = _pass_thru(
                prefix, child, parent, child_spec, parent_spec)

            # Found match. Recursively map and return it.
            return _map(prefix, parent, map_parent, parent_spec, spec_len_fn,
                        require_controller)

    _err("child specifier for {!r} ({}) does not appear in {!r}"
         .format(child, child_spec, map_prop))


def _mask(prefix, child, parent, child_spec):
    # Common code for handling <prefix>-mask properties, e.g. interrupt-mask.
    # See _map() for the parameters.

    mask_prop = parent.props.get(prefix + "-map-mask")
    if not mask_prop:
        # No mask
        return child_spec

    mask = mask_prop.value
    if len(mask) != len(child_spec):
        _err("{!r}: expected '{}-mask' in {!r} to be {} bytes, is {} bytes"
             .format(child, prefix, parent, len(child_spec), len(mask)))

    return _and(child_spec, mask)


def _pass_thru(prefix, child, parent, child_spec, parent_spec):
    # Common code for handling <prefix>-map-thru properties, e.g.
    # interrupt-pass-thru.
    #
    # parent_spec:
    #   The parent data from the matched entry in the <prefix>-map property
    #
    # See _map() for the other parameters.

    pass_thru_prop = parent.props.get(prefix + "-map-pass-thru")
    if not pass_thru_prop:
        # No pass-thru
        return parent_spec

    pass_thru = pass_thru_prop.value
    if len(pass_thru) != len(child_spec):
        _err("{!r}: expected '{}-map-pass-thru' in {!r} to be {} bytes, is {} bytes"
             .format(child, prefix, parent, len(child_spec), len(pass_thru)))

    res = _or(_and(child_spec, pass_thru),
              _and(parent_spec, _not(pass_thru)))

    # Truncate to length of parent spec.
    return res[-len(parent_spec):]


def _raw_unit_addr(node):
    # _map_interrupt() helper. Returns the unit address (derived from 'reg' and
    # #address-cells) as a raw 'bytes'

    if 'reg' not in node.props:
        _err("{!r} lacks 'reg' property (needed for 'interrupt-map' unit "
             "address lookup)".format(node))

    addr_len = 4*_address_cells(node)

    if len(node.props['reg'].value) < addr_len:
        _err("{!r} has too short 'reg' property (while doing 'interrupt-map' "
             "unit address lookup)".format(node))

    return node.props['reg'].value[:addr_len]


def _and(b1, b2):
    # Returns the bitwise AND of the two 'bytes' objects b1 and b2. Pads
    # with ones on the left if the lengths are not equal.

    # Pad on the left, to equal length
    maxlen = max(len(b1), len(b2))
    return bytes(x & y for x, y in zip(b1.rjust(maxlen, b'\xff'),
                                       b2.rjust(maxlen, b'\xff')))


def _or(b1, b2):
    # Returns the bitwise OR of the two 'bytes' objects b1 and b2. Pads with
    # zeros on the left if the lengths are not equal.

    # Pad on the left, to equal length
    maxlen = max(len(b1), len(b2))
    return bytes(x | y for x, y in zip(b1.rjust(maxlen, b'\x00'),
                                       b2.rjust(maxlen, b'\x00')))


def _not(b):
    # Returns the bitwise not of the 'bytes' object 'b'

    # ANDing with 0xFF avoids negative numbers
    return bytes(~x & 0xFF for x in b)


def _phandle_val_list(prop, n_cells_name):
    # Parses a '<phandle> <value> <phandle> <value> ...' value. The number of
    # cells that make up each <value> is derived from the node pointed at by
    # the preceding <phandle>.
    #
    # prop:
    #   dtlib.Property with value to parse
    #
    # n_cells_name:
    #   The <name> part of the #<name>-cells property to look for on the nodes
    #   the phandles point to, e.g. "gpio" for #gpio-cells.
    #
    # Returns a list of (<node>, <value>) tuples, where <node> is the node
    # pointed at by <phandle>.

    full_n_cells_name = "#{}-cells".format(n_cells_name)

    res = []

    raw = prop.value
    while raw:
        if len(raw) < 4:
            # Not enough room for phandle
            _err("bad value for " + repr(prop))
        phandle = to_num(raw[:4])
        raw = raw[4:]

        node = prop.node.dt.phandle2node.get(phandle)
        if not node:
            _err("bad phandle in " + repr(prop))

        if full_n_cells_name not in node.props:
            _err("{!r} lacks {}".format(node, full_n_cells_name))

        n_cells = node.props[full_n_cells_name].to_num()
        if len(raw) < 4*n_cells:
            _err("missing data after phandle in " + repr(prop))

        res.append((node, raw[:4*n_cells]))
        raw = raw[4*n_cells:]

    return res


def _address_cells(node):
    # Returns the #address-cells setting for 'node', giving the number of <u32>
    # cells used to encode the address in the 'reg' property

    if "#address-cells" in node.parent.props:
        return node.parent.props["#address-cells"].to_num()
    return 2  # Default value per DT spec.


def _size_cells(node):
    # Returns the #size-cells setting for 'node', giving the number of <u32>
    # cells used to encode the size in the 'reg' property

    if "#size-cells" in node.parent.props:
        return node.parent.props["#size-cells"].to_num()
    return 1  # Default value per DT spec.


def _interrupt_cells(node):
    # Returns the #interrupt-cells property value on 'node', erroring out if
    # 'node' has no #interrupt-cells property

    if "#interrupt-cells" not in node.props:
        _err("{!r} lacks #interrupt-cells".format(node))
    return node.props["#interrupt-cells"].to_num()


def _slice(node, prop_name, size, size_hint):
    # Splits node.props[prop_name].value into 'size'-sized chunks, returning a
    # list of chunks. Raises EDTError if the length of the property is not
    # evenly divisible by 'size'. 'size_hint' is a string shown on errors that
    # gives a hint on how 'size' was calculated.

    raw = node.props[prop_name].value
    if len(raw) % size:
        _err("'{}' property in {!r} has length {}, which is not evenly "
             "divisible by {} (= {}). Note that #*-cells "
             "properties come either from the parent node or from the "
             "controller (in the case of 'interrupts')."
             .format(prop_name, node, len(raw), size, size_hint))

    return [raw[i:i + size] for i in range(0, len(raw), size)]


def _check_dt(dt):
    # Does devicetree sanity checks. dtlib is meant to be general and
    # anything-goes except for very special properties like phandle, but in
    # edtlib we can be pickier.

    # Check that 'status' has one of the values given in the devicetree spec.

    # Accept "ok" for backwards compatibility
    ok_status = {"ok", "okay", "disabled", "reserved", "fail", "fail-sss"}

    for node in dt.node_iter():
        if "status" in node.props:
            try:
                status_val = node.props["status"].to_string()
            except DTError as e:
                # The error message gives the path
                _err(str(e))

            if status_val not in ok_status:
                _err("unknown 'status' value \"{}\" in {} in {}, expected one "
                     "of {} (see the devicetree specification)"
                     .format(status_val, node.path, node.dt.filename,
                             ", ".join(ok_status)))

        ranges_prop = node.props.get("ranges")
        if ranges_prop:
            if ranges_prop.type not in (TYPE_EMPTY, TYPE_NUMS):
                _err("expected 'ranges = < ... >;' in {} in {}, not '{}' "
                     "(see the devicetree specification)"
                     .format(node.path, node.dt.filename, ranges_prop))


def _err(msg):
    raise EDTError(msg)


# Custom PyYAML binding loader class to avoid modifying yaml.Loader directly,
# which could interfere with YAML loading in clients
class _BindingLoader(Loader):
    pass


# Add legacy '!include foo.yaml' handling
_BindingLoader.add_constructor("!include", _binding_include)

# Use OrderedDict instead of plain dict for YAML mappings, to preserve
# insertion order on Python 3.5 and earlier (plain dicts only preserve
# insertion order on Python 3.6+). This makes testing easier and avoids
# surprises.
#
# Adapted from
# https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts.
# Hopefully this API stays stable.
_BindingLoader.add_constructor(
    yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
    lambda loader, node: OrderedDict(loader.construct_pairs(node)))

# Zephyr: do not change this list without updating the documentation
# for the DT_PROP() macro in include/devicetree.h.
_DEFAULT_PROP_TYPES = {
    "compatible": "string-array",
    "status": "string",
    "reg": "array",
    "reg-names": "string-array",
    "label": "string",
    "interrupts": "array",
    "interrupts-extended": "compound",
    "interrupt-names": "string-array",
    "interrupt-controller": "boolean",
}
