#!/usr/bin/python
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2017 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#

"""Device tree to platform data class

This supports converting device tree data to C structures definitions and
static data.

See doc/driver-model/of-plat.rst for more informaiton
"""

import collections
import copy
from enum import IntEnum
import os
import re
import sys

from dtoc import fdt
from dtoc import fdt_util
from dtoc import src_scan
from dtoc.src_scan import conv_name_to_c

# When we see these properties we ignore them - i.e. do not create a structure
# member
PROP_IGNORE_LIST = [
    '#address-cells',
    '#gpio-cells',
    '#size-cells',
    'compatible',
    'linux,phandle',
    "status",
    'phandle',
    'u-boot,dm-pre-reloc',
    'u-boot,dm-tpl',
    'u-boot,dm-spl',
]

# C type declarations for the types we support
TYPE_NAMES = {
    fdt.Type.INT: 'fdt32_t',
    fdt.Type.BYTE: 'unsigned char',
    fdt.Type.STRING: 'const char *',
    fdt.Type.BOOL: 'bool',
    fdt.Type.INT64: 'fdt64_t',
}

STRUCT_PREFIX = 'dtd_'
VAL_PREFIX = 'dtv_'

# Properties which are considered to be phandles
#    key: property name
#    value: name of associated #cells property in the target node
#
# New phandle properties must be added here; otherwise they will come through as
# simple integers and finding devices by phandle will not work.
# Any property that ends with one of these (e.g. 'cd-gpios') will be considered
# a phandle property.
PHANDLE_PROPS = {
    'clocks': '#clock-cells',
    'gpios': '#gpio-cells',
    'sandbox,emul': '#emul-cells',
    }

class Ftype(IntEnum):
    SOURCE, HEADER = range(2)


# This holds information about each type of output file dtoc can create
# type: Type of file (Ftype)
# fname: Filename excluding directory, e.g. 'dt-plat.c'
# hdr_comment: Comment explaining the purpose of the file
OutputFile = collections.namedtuple('OutputFile',
                                    ['ftype', 'fname', 'method', 'hdr_comment'])

# This holds information about a property which includes phandles.
#
# max_args: integer: Maximum number or arguments that any phandle uses (int).
# args: Number of args for each phandle in the property. The total number of
#     phandles is len(args). This is a list of integers.
PhandleInfo = collections.namedtuple('PhandleInfo', ['max_args', 'args'])

# Holds a single phandle link, allowing a C struct value to be assigned to point
# to a device
#
# var_node: C variable to assign (e.g. 'dtv_mmc.clocks[0].node')
# dev_name: Name of device to assign to (e.g. 'clock')
PhandleLink = collections.namedtuple('PhandleLink', ['var_node', 'dev_name'])


def tab_to(num_tabs, line):
    """Append tabs to a line of text to reach a tab stop.

    Args:
        num_tabs (int): Tab stop to obtain (0 = column 0, 1 = column 8, etc.)
        line (str): Line of text to append to

    Returns:
        str: line with the correct number of tabs appeneded. If the line already
        extends past that tab stop then a single space is appended.
    """
    if len(line) >= num_tabs * 8:
        return line + ' '
    return line + '\t' * (num_tabs - len(line) // 8)

def get_value(ftype, value):
    """Get a value as a C expression

    For integers this returns a byte-swapped (little-endian) hex string
    For bytes this returns a hex string, e.g. 0x12
    For strings this returns a literal string enclosed in quotes
    For booleans this return 'true'

    Args:
        ftype (fdt.Type): Data type (fdt_util)
        value (bytes): Data value, as a string of bytes

    Returns:
        str: String representation of the value
    """
    if ftype == fdt.Type.INT:
        val = '%#x' % fdt_util.fdt32_to_cpu(value)
    elif ftype == fdt.Type.BYTE:
        char = value[0]
        val = '%#x' % (ord(char) if isinstance(char, str) else char)
    elif ftype == fdt.Type.STRING:
        # Handle evil ACPI backslashes by adding another backslash before them.
        # So "\\_SB.GPO0" in the device tree effectively stays like that in C
        val = '"%s"' % value.replace('\\', '\\\\')
    elif ftype == fdt.Type.BOOL:
        val = 'true'
    else:  # ftype == fdt.Type.INT64:
        val = '%#x' % value
    return val


class DtbPlatdata():
    """Provide a means to convert device tree binary data to platform data

    The output of this process is C structures which can be used in space-
    constrained encvironments where the ~3KB code overhead of device tree
    code is not affordable.

    Properties:
        _scan: Scan object, for scanning and reporting on useful information
            from the U-Boot source code
        _fdt: Fdt object, referencing the device tree
        _dtb_fname: Filename of the input device tree binary file
        _valid_nodes_unsorted: A list of Node object with compatible strings,
            ordered by devicetree node order
        _valid_nodes: A list of Node object with compatible strings, ordered by
            conv_name_to_c(node.name)
        _include_disabled: true to include nodes marked status = "disabled"
        _outfile: The current output file (sys.stdout or a real file)
        _lines: Stashed list of output lines for outputting in the future
        _dirname: Directory to hold output files, or None for none (all files
            go to stdout)
        _struct_data (dict): OrderedDict of dtplat structures to output
            key (str): Node name, as a C identifier
                    value: dict containing structure fields:
                        key (str): Field name
                        value: Prop object with field information
        _basedir (str): Base directory of source tree
        _valid_uclasses (list of src_scan.Uclass): List of uclasses needed for
            the selected devices (see _valid_node), in alphabetical order
        _instantiate: Instantiate devices so they don't need to be bound at
            run-time
    """
    def __init__(self, scan, dtb_fname, include_disabled, instantiate=False):
        self._scan = scan
        self._fdt = None
        self._dtb_fname = dtb_fname
        self._valid_nodes = None
        self._valid_nodes_unsorted = None
        self._include_disabled = include_disabled
        self._outfile = None
        self._lines = []
        self._dirnames = [None] * len(Ftype)
        self._struct_data = collections.OrderedDict()
        self._basedir = None
        self._valid_uclasses = None
        self._instantiate = instantiate

    def setup_output_dirs(self, output_dirs):
        """Set up the output directories

        This should be done before setup_output() is called

        Args:
            output_dirs (tuple of str):
                Directory to use for C output files.
                    Use None to write files relative current directory
                Directory to use for H output files.
                    Defaults to the C output dir
        """
        def process_dir(ftype, dirname):
            if dirname:
                os.makedirs(dirname, exist_ok=True)
                self._dirnames[ftype] = dirname

        if output_dirs:
            c_dirname = output_dirs[0]
            h_dirname = output_dirs[1] if len(output_dirs) > 1 else c_dirname
            process_dir(Ftype.SOURCE, c_dirname)
            process_dir(Ftype.HEADER, h_dirname)

    def setup_output(self, ftype, fname):
        """Set up the output destination

        Once this is done, future calls to self.out() will output to this
        file. The file used is as follows:

        self._dirnames[ftype] is None: output to fname, or stdout if None
        self._dirnames[ftype] is not None: output to fname in that directory

        Calling this function multiple times will close the old file and open
        the new one. If they are the same file, nothing happens and output will
        continue to the same file.

        Args:
            ftype (str): Type of file to create ('c' or 'h')
            fname (str): Filename to send output to. If there is a directory in
                self._dirnames for this file type, it will be put in that
                directory
        """
        dirname = self._dirnames[ftype]
        if dirname:
            pathname = os.path.join(dirname, fname)
            if self._outfile:
                self._outfile.close()
            self._outfile = open(pathname, 'w')
        elif fname:
            if not self._outfile:
                self._outfile = open(fname, 'w')
        else:
            self._outfile = sys.stdout

    def finish_output(self):
        """Finish outputing to a file

        This closes the output file, if one is in use
        """
        if self._outfile != sys.stdout:
            self._outfile.close()
            self._outfile = None

    def out(self, line):
        """Output a string to the output file

        Args:
            line (str): String to output
        """
        self._outfile.write(line)

    def buf(self, line):
        """Buffer up a string to send later

        Args:
            line (str): String to add to our 'buffer' list
        """
        self._lines.append(line)

    def get_buf(self):
        """Get the contents of the output buffer, and clear it

        Returns:
            list(str): The output buffer, which is then cleared for future use
        """
        lines = self._lines
        self._lines = []
        return lines

    def out_header(self, outfile):
        """Output a message indicating that this is an auto-generated file

        Args:
            outfile: OutputFile describing the file being generated
        """
        self.out('''/*
 * DO NOT MODIFY
 *
 * %s.
 * This was generated by dtoc from a .dtb (device tree binary) file.
 */

''' % outfile.hdr_comment)

    def get_phandle_argc(self, prop, node_name):
        """Check if a node contains phandles

        We have no reliable way of detecting whether a node uses a phandle
        or not. As an interim measure, use a list of known property names.

        Args:
            prop (fdt.Prop): Prop object to check
            node_name (str): Node name, only used for raising an error
        Returns:
            int or None: Number of argument cells is this is a phandle,
                else None
        Raises:
            ValueError: if the phandle cannot be parsed or the required property
                is not present
        """
        cells_prop = None
        for name, cprop in PHANDLE_PROPS.items():
            if prop.name.endswith(name):
                cells_prop = cprop
        if cells_prop:
            if not isinstance(prop.value, list):
                prop.value = [prop.value]
            val = prop.value
            i = 0

            max_args = 0
            args = []
            while i < len(val):
                phandle = fdt_util.fdt32_to_cpu(val[i])
                # If we get to the end of the list, stop. This can happen
                # since some nodes have more phandles in the list than others,
                # but we allocate enough space for the largest list. So those
                # nodes with shorter lists end up with zeroes at the end.
                if not phandle:
                    break
                target = self._fdt.phandle_to_node.get(phandle)
                if not target:
                    raise ValueError("Cannot parse '%s' in node '%s'" %
                                     (prop.name, node_name))
                cells = target.props.get(cells_prop)
                if not cells:
                    raise ValueError("Node '%s' has no cells property" %
                                     target.name)
                num_args = fdt_util.fdt32_to_cpu(cells.value)
                max_args = max(max_args, num_args)
                args.append(num_args)
                i += 1 + num_args
            return PhandleInfo(max_args, args)
        return None

    def scan_dtb(self):
        """Scan the device tree to obtain a tree of nodes and properties

        Once this is done, self._fdt.GetRoot() can be called to obtain the
        device tree root node, and progress from there.
        """
        self._fdt = fdt.FdtScan(self._dtb_fname)

    def scan_node(self, node, valid_nodes):
        """Scan a node and subnodes to build a tree of node and phandle info

        This adds each subnode to self._valid_nodes if it is enabled and has a
        compatible string.

        Args:
            node (Node): Node for scan for subnodes
            valid_nodes (list of Node): List of Node objects to add to
        """
        for subnode in node.subnodes:
            if 'compatible' in subnode.props:
                status = subnode.props.get('status')
                if (not self._include_disabled and not status or
                        status.value != 'disabled'):
                    valid_nodes.append(subnode)

            # recurse to handle any subnodes
            self.scan_node(subnode, valid_nodes)

    def scan_tree(self, add_root):
        """Scan the device tree for useful information

        This fills in the following properties:
            _valid_nodes_unsorted: A list of nodes we wish to consider include
                in the platform data (in devicetree node order)
            _valid_nodes: Sorted version of _valid_nodes_unsorted

        Args:
            add_root: True to add the root node also (which wouldn't normally
                be added as it may not have a compatible string)
        """
        root = self._fdt.GetRoot()
        valid_nodes = []
        if add_root:
            valid_nodes.append(root)
        self.scan_node(root, valid_nodes)
        self._valid_nodes_unsorted = valid_nodes
        self._valid_nodes = sorted(valid_nodes,
                                   key=lambda x: conv_name_to_c(x.name))

    def prepare_nodes(self):
        """Add extra properties to the nodes we are using

        The following properties are added for use by dtoc:
            idx: Index number of this node (0=first, etc.)
            struct_name: Name of the struct dtd used by this node
            var_name: C name for this node
            child_devs: List of child devices for this node, each a None
            child_refs: Dict of references for each child:
                key: Position in child list (-1=head, 0=first, 1=second, ...
                                             n-1=last, n=head)
            seq: Sequence number of the device (unique within its uclass), or
                -1 not not known yet
            dev_ref: Reference to this device, e.g. 'DM_DEVICE_REF(serial)'
            driver: Driver record for this node, or None if not known
            uclass: Uclass record for this node, or None if not known
            uclass_seq: Position of this device within the uclass list (0=first,
                n-1=last)
            parent_seq: Position of this device within it siblings (0=first,
                n-1=last)
            parent_driver: Driver record of the node's parent, or None if none.
                We don't use node.parent.driver since node.parent may not be in
                the list of valid nodes
        """
        for idx, node in enumerate(self._valid_nodes):
            node.idx = idx
            node.struct_name, _ = self._scan.get_normalized_compat_name(node)
            node.var_name = conv_name_to_c(node.name)
            node.child_devs = []
            node.child_refs = {}
            node.seq = -1
            node.dev_ref = None
            node.driver = None
            node.uclass = None
            node.uclass_seq = None
            node.parent_seq = None
            node.parent_driver = None

    @staticmethod
    def get_num_cells(node):
        """Get the number of cells in addresses and sizes for this node

        Args:
            node (fdt.None): Node to check

        Returns:
            Tuple:
                Number of address cells for this node
                Number of size cells for this node
        """
        parent = node.parent
        if parent and not parent.props:
            raise ValueError("Parent node '%s' has no properties - do you need u-boot,dm-spl or similar?" %
                             parent.path)
        num_addr, num_size = 2, 2
        if parent:
            addr_prop = parent.props.get('#address-cells')
            size_prop = parent.props.get('#size-cells')
            if addr_prop:
                num_addr = fdt_util.fdt32_to_cpu(addr_prop.value)
            if size_prop:
                num_size = fdt_util.fdt32_to_cpu(size_prop.value)
        return num_addr, num_size

    def scan_reg_sizes(self):
        """Scan for 64-bit 'reg' properties and update the values

        This finds 'reg' properties with 64-bit data and converts the value to
        an array of 64-values. This allows it to be output in a way that the
        C code can read.
        """
        for node in self._valid_nodes:
            reg = node.props.get('reg')
            if not reg:
                continue
            num_addr, num_size = self.get_num_cells(node)
            total = num_addr + num_size

            if reg.type != fdt.Type.INT:
                raise ValueError("Node '%s' reg property is not an int" %
                                 node.name)
            if not isinstance(reg.value, list):
                reg.value = [reg.value]
            if len(reg.value) % total:
                raise ValueError(
                    "Node '%s' (parent '%s') reg property has %d cells "
                    'which is not a multiple of na + ns = %d + %d)' %
                    (node.name, node.parent.name, len(reg.value), num_addr,
                     num_size))
            reg.num_addr = num_addr
            reg.num_size = num_size
            if num_addr > 1 or num_size > 1:
                reg.type = fdt.Type.INT64
                i = 0
                new_value = []
                val = reg.value
                while i < len(val):
                    addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.num_addr)
                    i += num_addr
                    size = fdt_util.fdt_cells_to_cpu(val[i:], reg.num_size)
                    i += num_size
                    new_value += [addr, size]
                reg.value = new_value

    def scan_structs(self):
        """Scan the device tree building up the C structures we will use.

        Build a dict keyed by C struct name containing a dict of Prop
        object for each struct field (keyed by property name). Where the
        same struct appears multiple times, try to use the 'widest'
        property, i.e. the one with a type which can express all others.

        Once the widest property is determined, all other properties are
        updated to match that width.

        The results are written to self._struct_data
        """
        structs = self._struct_data
        for node in self._valid_nodes:
            fields = {}

            # Get a list of all the valid properties in this node.
            for name, prop in node.props.items():
                if name not in PROP_IGNORE_LIST and name[0] != '#':
                    fields[name] = copy.deepcopy(prop)

            # If we've seen this struct_name before, update the existing struct
            if node.struct_name in structs:
                struct = structs[node.struct_name]
                for name, prop in fields.items():
                    oldprop = struct.get(name)
                    if oldprop:
                        oldprop.Widen(prop)
                    else:
                        struct[name] = prop

            # Otherwise store this as a new struct.
            else:
                structs[node.struct_name] = fields

        for node in self._valid_nodes:
            struct = structs[node.struct_name]
            for name, prop in node.props.items():
                if name not in PROP_IGNORE_LIST and name[0] != '#':
                    prop.Widen(struct[name])

    def scan_phandles(self):
        """Figure out what phandles each node uses

        We need to be careful when outputing nodes that use phandles since
        they must come after the declaration of the phandles in the C file.
        Otherwise we get a compiler error since the phandle struct is not yet
        declared.

        This function adds to each node a list of phandle nodes that the node
        depends on. This allows us to output things in the right order.
        """
        for node in self._valid_nodes:
            node.phandles = set()
            for pname, prop in node.props.items():
                if pname in PROP_IGNORE_LIST or pname[0] == '#':
                    continue
                info = self.get_phandle_argc(prop, node.name)
                if info:
                    # Process the list as pairs of (phandle, id)
                    pos = 0
                    for args in info.args:
                        phandle_cell = prop.value[pos]
                        phandle = fdt_util.fdt32_to_cpu(phandle_cell)
                        target_node = self._fdt.phandle_to_node[phandle]
                        node.phandles.add(target_node)
                        pos += 1 + args


    def generate_structs(self):
        """Generate struct defintions for the platform data

        This writes out the body of a header file consisting of structure
        definitions for node in self._valid_nodes. See the documentation in
        doc/driver-model/of-plat.rst for more information.
        """
        structs = self._struct_data
        self.out('#include <stdbool.h>\n')
        self.out('#include <linux/libfdt.h>\n')

        # Output the struct definition
        for name in sorted(structs):
            self.out('struct %s%s {\n' % (STRUCT_PREFIX, name))
            for pname in sorted(structs[name]):
                prop = structs[name][pname]
                info = self.get_phandle_argc(prop, structs[name])
                if info:
                    # For phandles, include a reference to the target
                    struct_name = 'struct phandle_%d_arg' % info.max_args
                    self.out('\t%s%s[%d]' % (tab_to(2, struct_name),
                                             conv_name_to_c(prop.name),
                                             len(info.args)))
                else:
                    ptype = TYPE_NAMES[prop.type]
                    self.out('\t%s%s' % (tab_to(2, ptype),
                                         conv_name_to_c(prop.name)))
                    if isinstance(prop.value, list):
                        self.out('[%d]' % len(prop.value))
                self.out(';\n')
            self.out('};\n')

    def _output_list(self, node, prop):
        """Output the C code for a devicetree property that holds a list

        Args:
            node (fdt.Node): Node to output
            prop (fdt.Prop): Prop to output
        """
        self.buf('{')
        vals = []
        # For phandles, output a reference to the platform data
        # of the target node.
        info = self.get_phandle_argc(prop, node.name)
        if info:
            # Process the list as pairs of (phandle, id)
            pos = 0
            for args in info.args:
                phandle_cell = prop.value[pos]
                phandle = fdt_util.fdt32_to_cpu(phandle_cell)
                target_node = self._fdt.phandle_to_node[phandle]
                arg_values = []
                for i in range(args):
                    arg_values.append(
                        str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
                pos += 1 + args
                vals.append('\t{%d, {%s}}' % (target_node.idx,
                                              ', '.join(arg_values)))
            for val in vals:
                self.buf('\n\t\t%s,' % val)
        else:
            for val in prop.value:
                vals.append(get_value(prop.type, val))

            # Put 8 values per line to avoid very long lines.
            for i in range(0, len(vals), 8):
                if i:
                    self.buf(',\n\t\t')
                self.buf(', '.join(vals[i:i + 8]))
        self.buf('}')

    def _declare_device(self, node):
        """Add a device declaration to the output

        This declares a U_BOOT_DRVINFO() for the device being processed

        Args:
            node: Node to process
        """
        self.buf('U_BOOT_DRVINFO(%s) = {\n' % node.var_name)
        self.buf('\t.name\t\t= "%s",\n' % node.struct_name)
        self.buf('\t.plat\t\t= &%s%s,\n' % (VAL_PREFIX, node.var_name))
        self.buf('\t.plat_size\t= sizeof(%s%s),\n' %
                 (VAL_PREFIX, node.var_name))
        idx = -1
        if node.parent and node.parent in self._valid_nodes:
            idx = node.parent.idx
        self.buf('\t.parent_idx\t= %d,\n' % idx)
        self.buf('};\n')
        self.buf('\n')

    def prep_priv(self, struc, name, suffix, section='.priv_data'):
        if not struc:
            return None
        var_name = '_%s%s' % (name, suffix)
        hdr = self._scan._structs.get(struc)
        if hdr:
            self.buf('#include <%s>\n' % hdr.fname)
        else:
            print('Warning: Cannot find header file for struct %s' % struc)
        attr = '__attribute__ ((section ("%s")))' % section
        return var_name, struc, attr

    def alloc_priv(self, info, name, extra, suffix='_priv'):
        result = self.prep_priv(info, name, suffix)
        if not result:
            return None
        var_name, struc, section = result
        self.buf('u8 %s_%s[sizeof(struct %s)]\n\t%s;\n' %
                 (var_name, extra, struc.strip(), section))
        return '%s_%s' % (var_name, extra)

    def alloc_plat(self, info, name, extra, node):
        result = self.prep_priv(info, name, '_plat')
        if not result:
            return None
        var_name, struc, section = result
        self.buf('struct %s %s\n\t%s_%s = {\n' %
                 (struc.strip(), section, var_name, extra))
        self.buf('\t.dtplat = {\n')
        for pname in sorted(node.props):
            self._output_prop(node, node.props[pname], 2)
        self.buf('\t},\n')
        self.buf('};\n')
        return '&%s_%s' % (var_name, extra)

    def _declare_device_inst(self, node, parent_driver):
        """Add a device instance declaration to the output

        This declares a DM_DEVICE_INST() for the device being processed

        Args:
            node: Node to output
        """
        driver = node.driver
        uclass = node.uclass
        self.buf('\n')
        num_lines = len(self._lines)
        plat_name = self.alloc_plat(driver.plat, driver.name, node.var_name,
                                    node)
        priv_name = self.alloc_priv(driver.priv, driver.name, node.var_name)
        parent_plat_name = None
        parent_priv_name = None
        if parent_driver:
            # TODO: deal with uclass providing these values
            parent_plat_name = self.alloc_priv(
                parent_driver.child_plat, driver.name, node.var_name,
                '_parent_plat')
            parent_priv_name = self.alloc_priv(
                parent_driver.child_priv, driver.name, node.var_name,
                '_parent_priv')
        uclass_plat_name = self.alloc_priv(
            uclass.per_dev_plat, driver.name + '_uc', node.var_name, 'plat')
        uclass_priv_name = self.alloc_priv(uclass.per_dev_priv,
                                           driver.name + '_uc', node.var_name)
        for hdr in driver.headers:
            self.buf('#include %s\n' % hdr)

        # Add a blank line if we emitted any stuff above, for readability
        if num_lines != len(self._lines):
            self.buf('\n')

        self.buf('DM_DEVICE_INST(%s) = {\n' % node.var_name)
        self.buf('\t.driver\t\t= DM_DRIVER_REF(%s),\n' % node.struct_name)
        self.buf('\t.name\t\t= "%s",\n' % node.struct_name)
        if plat_name:
            self.buf('\t.plat_\t\t= %s,\n' % plat_name)
        else:
            self.buf('\t.plat_\t\t= &%s%s,\n' % (VAL_PREFIX, node.var_name))
        if parent_plat_name:
            self.buf('\t.parent_plat_\t= %s,\n' % parent_plat_name)
        if uclass_plat_name:
            self.buf('\t.uclass_plat_\t= %s,\n' % uclass_plat_name)
        driver_date = None

        if node != self._fdt.GetRoot():
            compat_list = node.props['compatible'].value
            if not isinstance(compat_list, list):
                compat_list = [compat_list]
            for compat in compat_list:
                driver_data = driver.compat.get(compat)
                if driver_data:
                    self.buf('\t.driver_data\t= %s,\n' % driver_data)
                    break

        if node.parent and node.parent.parent:
            self.buf('\t.parent\t\t= DM_DEVICE_REF(%s),\n' %
                     node.parent.var_name)
        if priv_name:
            self.buf('\t.priv_\t\t= %s,\n' % priv_name)
        self.buf('\t.uclass\t\t= DM_UCLASS_REF(%s),\n' % uclass.name)

        if uclass_priv_name:
            self.buf('\t.uclass_priv_ = %s,\n' % uclass_priv_name)
        if parent_priv_name:
            self.buf('\t.parent_priv_\t= %s,\n' % parent_priv_name)
        self.list_node('uclass_node', uclass.node_refs, node.uclass_seq)
        self.list_head('child_head', 'sibling_node', node.child_devs, node.var_name)
        if node.parent in self._valid_nodes:
            self.list_node('sibling_node', node.parent.child_refs,
                           node.parent_seq)
        # flags is left as 0

        self.buf('\t.seq_ = %d,\n' % node.seq)

        self.buf('};\n')
        self.buf('\n')
        return parent_plat_name

    def _output_prop(self, node, prop, tabs=1):
        """Output a line containing the value of a struct member

        Args:
            node (Node): Node being output
            prop (Prop): Prop object to output
        """
        if prop.name in PROP_IGNORE_LIST or prop.name[0] == '#':
            return
        member_name = conv_name_to_c(prop.name)
        self.buf('%s%s= ' % ('\t' * tabs, tab_to(3, '.' + member_name)))

        # Special handling for lists
        if isinstance(prop.value, list):
            self._output_list(node, prop)
        else:
            self.buf(get_value(prop.type, prop.value))
        self.buf(',\n')

    def _output_values(self, node):
        """Output the definition of a device's struct values

        Args:
            node (Node): Node to output
        """
        self.buf('static struct %s%s %s%s = {\n' %
                 (STRUCT_PREFIX, node.struct_name, VAL_PREFIX, node.var_name))
        for pname in sorted(node.props):
            self._output_prop(node, node.props[pname])
        self.buf('};\n')

    def list_head(self, head_member, node_member, node_refs, var_name):
        self.buf('\t.%s\t= {\n' % head_member)
        if node_refs:
            last = node_refs[-1].dev_ref
            first = node_refs[0].dev_ref
            member = node_member
        else:
            last = 'DM_DEVICE_REF(%s)' % var_name
            first = last
            member = head_member
        self.buf('\t\t.prev = &%s->%s,\n' % (last, member))
        self.buf('\t\t.next = &%s->%s,\n' % (first, member))
        self.buf('\t},\n')

    def list_node(self, member, node_refs, seq):
        self.buf('\t.%s\t= {\n' % member)
        self.buf('\t\t.prev = %s,\n' % node_refs[seq - 1])
        self.buf('\t\t.next = %s,\n' % node_refs[seq + 1])
        self.buf('\t},\n')

    def generate_uclasses(self):
        if not self.check_instantiate(True):
            return
        self.out('\n')
        self.out('#include <common.h>\n')
        self.out('#include <dm.h>\n')
        self.out('#include <dt-structs.h>\n')
        self.out('\n')
        self.buf('/*\n')
        self.buf(
            " * uclass declarations, ordered by 'struct uclass' linker_list idx:\n")
        uclass_list = self._valid_uclasses
        for seq, uclass in enumerate(uclass_list):
            self.buf(' * %3d: %s\n' % (seq, uclass.name))
        self.buf(' *\n')
        self.buf(' * Sequence numbers allocated in each uclass:\n')
        for uclass in uclass_list:
            if uclass.alias_num_to_node:
                self.buf(' * %s: %s\n' % (uclass.name, uclass.uclass_id))
                for seq, node in uclass.alias_num_to_node.items():
                    self.buf(' *    %d: %s\n' % (seq, node.path))
        self.buf(' */\n')

        uclass_node = {}
        for seq, uclass in enumerate(uclass_list):
            uclass_node[seq] = ('&DM_UCLASS_REF(%s)->sibling_node' %
                                uclass.name)
        uclass_node[-1] = '&uclass_head'
        uclass_node[len(uclass_list)] = '&uclass_head'
        self.buf('\n')
        self.buf('struct list_head %s = {\n' % 'uclass_head')
        self.buf('\t.prev = %s,\n' % uclass_node[len(uclass_list) -1])
        self.buf('\t.next = %s,\n' % uclass_node[0])
        self.buf('};\n')
        self.buf('\n')

        for seq, uclass in enumerate(uclass_list):
            uc_drv = self._scan._uclass.get(uclass.uclass_id)

            priv_name = self.alloc_priv(uc_drv.priv, uc_drv.name, '')

            self.buf('DM_UCLASS_INST(%s) = {\n' % uclass.name)
            if priv_name:
                self.buf('\t.priv_\t\t= %s,\n' % priv_name)
            self.buf('\t.uc_drv\t\t= DM_UCLASS_DRIVER_REF(%s),\n' % uclass.name)
            self.list_node('sibling_node', uclass_node, seq)
            self.list_head('dev_head', 'uclass_node', uc_drv.devs, None)
            self.buf('};\n')
            self.buf('\n')
        self.out(''.join(self.get_buf()))

    def read_aliases(self):
        """Read the aliases and attach the information to self._alias

        Raises:
            ValueError: The alias path is not found
        """
        alias_node = self._fdt.GetNode('/aliases')
        if not alias_node:
            return
        re_num = re.compile('(^[a-z0-9-]+[a-z]+)([0-9]+)$')
        for prop in alias_node.props.values():
            m_alias = re_num.match(prop.name)
            if not m_alias:
                raise ValueError("Cannot decode alias '%s'" % prop.name)
            name, num = m_alias.groups()
            node = self._fdt.GetNode(prop.value)
            result = self._scan.add_uclass_alias(name, num, node)
            if result is None:
                raise ValueError("Alias '%s' path '%s' not found" %
                                 (prop.name, prop.value))
            elif result is False:
                print("Could not find uclass for alias '%s'" % prop.name)

    def generate_decl(self):
        nodes_to_output = list(self._valid_nodes)

        self.buf('#include <dm/device-internal.h>\n')
        self.buf('#include <dm/uclass-internal.h>\n')
        self.buf('\n')
        self.buf(
            '/* driver declarations - these allow DM_DRIVER_GET() to be used */\n')
        for node in nodes_to_output:
            self.buf('extern U_BOOT_DRIVER(%s);\n' % node.struct_name);
        self.buf('\n')

        if self._instantiate:
            self.buf(
                '/* device declarations - these allow DM_DEVICE_REF() to be used */\n')
            for node in nodes_to_output:
                self.buf('extern DM_DEVICE_INST(%s);\n' % node.var_name)
            self.buf('\n')

        uclass_list = self._valid_uclasses

        self.buf(
            '/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */\n')
        for uclass in uclass_list:
            self.buf('extern UCLASS_DRIVER(%s);\n' % uclass.name)

        if self._instantiate:
            self.buf('\n')
            self.buf('/* uclass declarations - needed for DM_UCLASS_REF() */\n')
            for uclass in uclass_list:
                self.buf('extern DM_UCLASS_INST(%s);\n' % uclass.name)
        self.out(''.join(self.get_buf()))

    def assign_seqs(self):
        """Assign a sequence number to each node"""
        for node in self._valid_nodes_unsorted:
            seq = self._scan.assign_seq(node)
            if seq is not None:
                node.seq = seq

    def process_nodes(self, need_drivers):
        nodes_to_output = list(self._valid_nodes)

        # Figure out which drivers we actually use
        self._scan.mark_used(nodes_to_output)

        for node in nodes_to_output:
            node.dev_ref = 'DM_DEVICE_REF(%s)' % node.var_name
            driver = self._scan.get_driver(node.struct_name)
            if not driver:
                if not need_drivers:
                    continue
                raise ValueError("Cannot parse/find driver for '%s'" %
                                 node.struct_name)
            node.driver = driver
            uclass = self._scan._uclass.get(driver.uclass_id)
            if not uclass:
                raise ValueError("Cannot parse/find uclass '%s' for driver '%s'" %
                                (driver.uclass_id, node.struct_name))
            node.uclass = uclass
            node.uclass_seq = len(node.uclass.devs)
            node.uclass.devs.append(node)
            uclass.node_refs[node.uclass_seq] = \
                '&%s->uclass_node' % node.dev_ref

            parent_driver = None
            if node.parent in self._valid_nodes:
                parent_driver = self._scan.get_driver(node.parent.struct_name)
                if not parent_driver:
                    if not need_drivers:
                        continue
                    raise ValueError(
                        "Cannot parse/find parent driver '%s' for '%s'" %
                        (node.parent.struct_name, node.struct_name))
                node.parent_seq = len(node.parent.child_devs)
                node.parent.child_devs.append(node)
                node.parent.child_refs[node.parent_seq] = \
                    '&%s->sibling_node' % node.dev_ref
                node.parent_driver = parent_driver

        for node in nodes_to_output:
            ref = '&%s->child_head' % node.dev_ref
            node.child_refs[-1] = ref
            node.child_refs[len(node.child_devs)] = ref

        uclass_set = set()
        for driver in self._scan._drivers.values():
            if driver.used and driver.uclass:
                uclass_set.add(driver.uclass)
        self._valid_uclasses = sorted(list(uclass_set),
                                      key=lambda uc: uc.uclass_id)

        for seq, uclass in enumerate(uclass_set):
            ref = '&DM_UCLASS_REF(%s)->dev_head' % uclass.name
            uclass.node_refs[-1] = ref
            uclass.node_refs[len(uclass.devs)] = ref

    def output_node_plat(self, node):
        """Output the C code for a node

        Args:
            node (fdt.Node): node to output
        """
        driver = node.driver
        parent_driver = node.parent_driver

        line1 = 'Node %s index %d' % (node.path, node.idx)
        if driver:
            self.buf('/*\n')
            self.buf(' * %s\n' % line1)
            self.buf(' * driver %s parent %s\n' % (driver.name,
                parent_driver.name if parent_driver else 'None'))
            self.buf(' */\n')
        else:
            self.buf('/* %s */\n' % line1)

        self._output_values(node)
        self._declare_device(node)

        self.out(''.join(self.get_buf()))

    def output_node_instance(self, node):
        """Output the C code for a node

        Args:
            node (fdt.Node): node to output
        """
        parent_driver = node.parent_driver

        self.buf('/*\n')
        self.buf(' * Node %s index %d\n' % (node.path, node.idx))
        self.buf(' * driver %s parent %s\n' % (node.driver.name,
                 parent_driver.name if parent_driver else 'None'))
        self.buf('*/\n')

        if not node.driver.plat:
            self._output_values(node)
        self._declare_device_inst(node, parent_driver)

        self.out(''.join(self.get_buf()))

    def check_instantiate(self, require):
        """Check if self._instantiate is set to the required value

        If not, this outputs a message into the current file

        Args:
            require: True to require --instantiate, False to require that it not
                be enabled
        """
        if require != self._instantiate:
            self.out(
                '/* This file is not used: --instantiate was %senabled */\n' %
                ('not ' if require else ''))
            return False
        return True

    def generate_plat(self):
        """Generate device defintions for the platform data

        This writes out C platform data initialisation data and
        U_BOOT_DRVINFO() declarations for each valid node. Where a node has
        multiple compatible strings, a #define is used to make them equivalent.

        See the documentation in doc/driver-model/of-plat.rst for more
        information.
        """
        if not self.check_instantiate(False):
            return
        self.out('/* Allow use of U_BOOT_DRVINFO() in this file */\n')
        self.out('#define DT_PLAT_C\n')
        self.out('\n')
        self.out('#include <common.h>\n')
        self.out('#include <dm.h>\n')
        self.out('#include <dt-structs.h>\n')
        self.out('\n')

        if self._valid_nodes:
            self.out('/*\n')
            self.out(
                " * driver_info declarations, ordered by 'struct driver_info' linker_list idx:\n")
            self.out(' *\n')
            self.out(' * idx  %-20s %-s\n' % ('driver_info', 'driver'))
            self.out(' * ---  %-20s %-s\n' % ('-' * 20, '-' * 20))
            for node in self._valid_nodes:
                self.out(' * %3d: %-20s %-s\n' %
                        (node.idx, node.var_name, node.struct_name))
            self.out(' * ---  %-20s %-s\n' % ('-' * 20, '-' * 20))
            self.out(' */\n')
            self.out('\n')

            for node in self._valid_nodes:
                self.output_node_plat(node)

        self.out(''.join(self.get_buf()))

    def generate_device(self):
        """Generate device instances

        This writes out DM_DEVICE_INST() records for each device in the
        build.

        See the documentation in doc/driver-model/of-plat.rst for more
        information.
        """
        if not self.check_instantiate(True):
            return
        self.out('#include <common.h>\n')
        self.out('#include <dm.h>\n')
        self.out('#include <dt-structs.h>\n')
        self.out('\n')

        if self._valid_nodes:
            self.out('/*\n')
            self.out(
                " * udevice declarations, ordered by 'struct udevice' linker_list position:\n")
            self.out(' *\n')
            self.out(' * idx  %-20s %-s\n' % ('udevice', 'driver'))
            self.out(' * ---  %-20s %-s\n' % ('-' * 20, '-' * 20))
            for node in self._valid_nodes:
                self.out(' * %3d: %-20s %-s\n' %
                        (node.idx, node.var_name, node.struct_name))
            self.out(' * ---  %-20s %-s\n' % ('-' * 20, '-' * 20))
            self.out(' */\n')
            self.out('\n')

            for node in self._valid_nodes:
                self.output_node_instance(node)

        self.out(''.join(self.get_buf()))


# Types of output file we understand
# key: Command used to generate this file
# value: OutputFile for this command
OUTPUT_FILES_COMMON = {
    'decl':
        OutputFile(Ftype.HEADER, 'dt-decl.h', DtbPlatdata.generate_decl,
                   'Declares externs for all device/uclass instances'),
    'struct':
        OutputFile(Ftype.HEADER, 'dt-structs-gen.h',
                   DtbPlatdata.generate_structs,
                   'Defines the structs used to hold devicetree data'),
    }

# File generated without instantiate
OUTPUT_FILES_NOINST = {
    'platdata':
        OutputFile(Ftype.SOURCE, 'dt-plat.c', DtbPlatdata.generate_plat,
                   'Declares the U_BOOT_DRIVER() records and platform data'),
    }

# File generated with instantiate
OUTPUT_FILES_INST = {
    'device':
        OutputFile(Ftype.SOURCE, 'dt-device.c', DtbPlatdata.generate_device,
                   'Declares the DM_DEVICE_INST() records'),
    'uclass':
        OutputFile(Ftype.SOURCE, 'dt-uclass.c', DtbPlatdata.generate_uclasses,
                   'Declares the uclass instances (struct uclass)'),
    }


def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
              instantiate, warning_disabled=False, drivers_additional=None,
              basedir=None, scan=None):
    """Run all the steps of the dtoc tool

    Args:
        args (list): List of non-option arguments provided to the problem
        dtb_file (str): Filename of dtb file to process
        include_disabled (bool): True to include disabled nodes
        output (str): Name of output file (None for stdout)
        output_dirs (tuple of str):
            Directory to put C output files
            Directory to put H output files
        phase: The phase of U-Boot that we are generating data for, e.g. 'spl'
             or 'tpl'. None if not known
        instantiate: Instantiate devices so they don't need to be bound at
            run-time
        warning_disabled (bool): True to avoid showing warnings about missing
            drivers
        drivers_additional (list): List of additional drivers to use during
            scanning
        basedir (str): Base directory of U-Boot source code. Defaults to the
            grandparent of this file's directory
        scan (src_src.Scanner): Scanner from a previous run. This can help speed
            up tests. Use None for normal operation

    Returns:
        DtbPlatdata object

    Raises:
        ValueError: if args has no command, or an unknown command
    """
    if not args:
        raise ValueError('Please specify a command: struct, platdata, all')
    if output and output_dirs and any(output_dirs):
        raise ValueError('Must specify either output or output_dirs, not both')

    if not scan:
        scan = src_scan.Scanner(basedir, drivers_additional, phase)
        scan.scan_drivers()
        do_process = True
    else:
        do_process = False
    plat = DtbPlatdata(scan, dtb_file, include_disabled, instantiate)
    plat.scan_dtb()
    plat.scan_tree(add_root=instantiate)
    plat.prepare_nodes()
    plat.scan_reg_sizes()
    plat.setup_output_dirs(output_dirs)
    plat.scan_structs()
    plat.scan_phandles()
    plat.process_nodes(instantiate)
    plat.read_aliases()
    plat.assign_seqs()

    # Figure out what output files we plan to generate
    output_files = OUTPUT_FILES_COMMON
    if instantiate:
        output_files.update(OUTPUT_FILES_INST)
    else:
        output_files.update(OUTPUT_FILES_NOINST)

    cmds = args[0].split(',')
    if 'all' in cmds:
        cmds = sorted(output_files.keys())
    for cmd in cmds:
        outfile = output_files.get(cmd)
        if not outfile:
            raise ValueError("Unknown command '%s': (use: %s)" %
                             (cmd, ', '.join(sorted(output_files.keys()))))
        plat.setup_output(outfile.ftype,
                          outfile.fname if output_dirs else output)
        plat.out_header(outfile)
        outfile.method(plat)
    plat.finish_output()

    if not warning_disabled:
        scan.show_warnings()
    return plat
