All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests
@ 2017-06-19  4:08 Simon Glass
  2017-06-19  4:08 ` [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options Simon Glass
                   ` (10 more replies)
  0 siblings, 11 replies; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:08 UTC (permalink / raw)
  To: u-boot

When dtoc was originally written it was an idea without much expectation
(on my part at least) that it would be widely used. However there have
been several features requests and it is being relied on for several
rockchip boards.

At present dtoc has no tests of its own. It relies on sandbox_spl which
uses CONFIG_SPL_OF_PLATDATA to read the resulting C structures and output
their contents. This is a rather round-about way to test the tool. It is
better to have tests which specifically test dtoc's functionality.

In addition, before expanding the code it would be best to refactor it a
bit to make it easier to maintain.

This series:
- Tidies up and refactors dtoc (pylint, static functions, splitting code)
- Adds test for the main features it supports


Simon Glass (11):
  dtoc: Use self._options instead of the global options
  dtoc: Add a comment at the top
  dtoc: Split out the main class into its own file
  dtoc: Fix pylint warnings
  dtoc: Don't handle properties with / in them
  dtoc: Pass include_disabled explicitly
  dtoc: Move static functions out of the class
  dtoc: Move the main logic into the dtb_platdata file
  dtoc: Add a comment about string replace in conv_name_to_c()
  sandbox: Stop printing platdata at the start of SPL
  dtoc: Add tests

 arch/sandbox/cpu/spl.c           |  11 -
 test/py/tests/test_ofplatdata.py |  30 +--
 tools/dtoc/dtb_platdata.py       | 456 ++++++++++++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py               | 466 ++++-----------------------------------
 tools/dtoc/dtoc_test.dts         |  12 +
 tools/dtoc/dtoc_test_aliases.dts |  18 ++
 tools/dtoc/dtoc_test_empty.dts   |  12 +
 tools/dtoc/dtoc_test_phandle.dts |  23 ++
 tools/dtoc/dtoc_test_simple.dts  |  48 ++++
 tools/dtoc/test_dtoc.py          | 271 +++++++++++++++++++++++
 10 files changed, 887 insertions(+), 460 deletions(-)
 create mode 100644 tools/dtoc/dtb_platdata.py
 create mode 100644 tools/dtoc/dtoc_test.dts
 create mode 100644 tools/dtoc/dtoc_test_aliases.dts
 create mode 100644 tools/dtoc/dtoc_test_empty.dts
 create mode 100644 tools/dtoc/dtoc_test_phandle.dts
 create mode 100644 tools/dtoc/dtoc_test_simple.dts
 create mode 100644 tools/dtoc/test_dtoc.py

-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
@ 2017-06-19  4:08 ` Simon Glass
  2017-07-06 14:51   ` sjg at google.com
  2017-06-19  4:08 ` [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top Simon Glass
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:08 UTC (permalink / raw)
  To: u-boot

This class should use the options object passed to it rather than finding
the global one. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index c0ab13ad34..056f5157c9 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -177,7 +177,7 @@ class DtbPlatdata:
         for node in root.subnodes:
             if 'compatible' in node.props:
                 status = node.props.get('status')
-                if (not options.include_disabled and not status or
+                if (not self._options.include_disabled and not status or
                     status.value != 'disabled'):
                     self._valid_nodes.append(node)
                     phandle_prop = node.props.get('phandle')
@@ -203,7 +203,7 @@ class DtbPlatdata:
         for node in self.fdt.GetRoot().subnodes:
             if 'compatible' in node.props:
                 status = node.props.get('status')
-                if (not options.include_disabled and not status or
+                if (not self._options.include_disabled and not status or
                     status.value != 'disabled'):
                     node_list.append(node)
                     phandle_prop = node.props.get('phandle')
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
  2017-06-19  4:08 ` [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options Simon Glass
@ 2017-06-19  4:08 ` Simon Glass
  2017-07-06 14:51   ` sjg at google.com
  2017-06-19  4:08 ` [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file Simon Glass
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:08 UTC (permalink / raw)
  To: u-boot

Add a description of the dtoc tool at the top of the file.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 056f5157c9..79779477d9 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -6,6 +6,26 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+"""Device tree to C tool
+
+This tool converts a device tree binary file (.dtb) into two C files. The
+indent is to allow a C program to access data from the device tree without
+having to link against libfdt. By putting the data from the device tree into
+C structures, normal C code can be used. This helps to reduce the size of the
+compiled program.
+
+Dtoc produces two output files:
+
+   dt-structs.h  - contains struct definitions
+   dt-platdata.c - contains data from the device tree using the struct
+                      definitions, as well as U-Boot driver definitions.
+
+This tool is used in U-Boot to provide device tree data to SPL without
+increasing the code size of SPL. This supports the CONFIG_SPL_OF_PLATDATA
+options. For more information about the use of this options and tool please
+see doc/driver-model/of-plat.txt
+"""
+
 import copy
 from optparse import OptionError, OptionParser
 import os
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
  2017-06-19  4:08 ` [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options Simon Glass
  2017-06-19  4:08 ` [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top Simon Glass
@ 2017-06-19  4:08 ` Simon Glass
  2017-07-06 14:51   ` sjg at google.com
  2017-06-19  4:08 ` [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings Simon Glass
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:08 UTC (permalink / raw)
  To: u-boot

To simplify running tests we should move this class into its own file.
This allows the tests to import it without having to import dtoc.py, which
runs the tests.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 411 +++++++++++++++++++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py         | 408 +-------------------------------------------
 2 files changed, 414 insertions(+), 405 deletions(-)
 create mode 100644 tools/dtoc/dtb_platdata.py

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
new file mode 100644
index 0000000000..94db274c09
--- /dev/null
+++ b/tools/dtoc/dtb_platdata.py
@@ -0,0 +1,411 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2017 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+import copy
+
+import fdt
+import fdt_util
+
+# 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 tyues we support
+TYPE_NAMES = {
+    fdt.TYPE_INT: 'fdt32_t',
+    fdt.TYPE_BYTE: 'unsigned char',
+    fdt.TYPE_STRING: 'const char *',
+    fdt.TYPE_BOOL: 'bool',
+};
+
+STRUCT_PREFIX = 'dtd_'
+VAL_PREFIX = 'dtv_'
+
+def Conv_name_to_c(name):
+    """Convert a device-tree name to a C identifier
+
+    Args:
+        name:   Name to convert
+    Return:
+        String containing the C version of this name
+    """
+    str = name.replace('@', '_at_')
+    str = str.replace('-', '_')
+    str = str.replace(',', '_')
+    str = str.replace('.', '_')
+    str = str.replace('/', '__')
+    return str
+
+def TabTo(num_tabs, str):
+    if len(str) >= num_tabs * 8:
+        return str + ' '
+    return str + '\t' * (num_tabs - len(str) // 8)
+
+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:
+        fdt: Fdt object, referencing the device tree
+        _dtb_fname: Filename of the input device tree binary file
+        _valid_nodes: A list of Node object with compatible strings
+        _options: Command-line options
+        _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
+        _outfile: The current output file (sys.stdout or a real file)
+        _lines: Stashed list of output lines for outputting in the future
+        _phandle_node: A dict of Nodes indexed by phandle (an integer)
+    """
+    def __init__(self, dtb_fname, options):
+        self._dtb_fname = dtb_fname
+        self._valid_nodes = None
+        self._options = options
+        self._phandle_node = {}
+        self._outfile = None
+        self._lines = []
+        self._aliases = {}
+
+    def SetupOutput(self, fname):
+        """Set up the output destination
+
+        Once this is done, future calls to self.Out() will output to this
+        file.
+
+        Args:
+            fname: Filename to send output to, or '-' for stdout
+        """
+        if fname == '-':
+            self._outfile = sys.stdout
+        else:
+            self._outfile = open(fname, 'w')
+
+    def Out(self, str):
+        """Output a string to the output file
+
+        Args:
+            str: String to output
+        """
+        self._outfile.write(str)
+
+    def Buf(self, str):
+        """Buffer up a string to send later
+
+        Args:
+            str: String to add to our 'buffer' list
+        """
+        self._lines.append(str)
+
+    def GetBuf(self):
+        """Get the contents of the output buffer, and clear it
+
+        Returns:
+            The output buffer, which is then cleared for future use
+        """
+        lines = self._lines
+        self._lines = []
+        return lines
+
+    def GetValue(self, type, 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:
+            type: Data type (fdt_util)
+            value: Data value, as a string of bytes
+        """
+        if type == fdt.TYPE_INT:
+            return '%#x' % fdt_util.fdt32_to_cpu(value)
+        elif type == fdt.TYPE_BYTE:
+            return '%#x' % ord(value[0])
+        elif type == fdt.TYPE_STRING:
+            return '"%s"' % value
+        elif type == fdt.TYPE_BOOL:
+            return 'true'
+
+    def GetCompatName(self, node):
+        """Get a node's first compatible string as a C identifier
+
+        Args:
+            node: Node object to check
+        Return:
+            C identifier for the first compatible string
+        """
+        compat = node.props['compatible'].value
+        aliases = []
+        if type(compat) == list:
+            compat, aliases = compat[0], compat[1:]
+        return Conv_name_to_c(compat), [Conv_name_to_c(a) for a in aliases]
+
+    def ScanDtb(self):
+        """Scan the device tree to obtain a tree of notes 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 ScanNode(self, root):
+        for node in root.subnodes:
+            if 'compatible' in node.props:
+                status = node.props.get('status')
+                if (not self._options.include_disabled and not status or
+                    status.value != 'disabled'):
+                    self._valid_nodes.append(node)
+                    phandle_prop = node.props.get('phandle')
+                    if phandle_prop:
+                        phandle = phandle_prop.GetPhandle()
+                        self._phandle_node[phandle] = node
+
+            # recurse to handle any subnodes
+            self.ScanNode(node);
+
+    def ScanTree(self):
+        """Scan the device tree for useful information
+
+        This fills in the following properties:
+            _phandle_node: A dict of Nodes indexed by phandle (an integer)
+            _valid_nodes: A list of nodes we wish to consider include in the
+                platform data
+        """
+        self._phandle_node = {}
+        self._valid_nodes = []
+        return self.ScanNode(self.fdt.GetRoot());
+
+        for node in self.fdt.GetRoot().subnodes:
+            if 'compatible' in node.props:
+                status = node.props.get('status')
+                if (not self._options.include_disabled and not status or
+                    status.value != 'disabled'):
+                    node_list.append(node)
+                    phandle_prop = node.props.get('phandle')
+                    if phandle_prop:
+                        phandle = phandle_prop.GetPhandle()
+                        self._phandle_node[phandle] = node
+
+        self._valid_nodes = node_list
+
+    def IsPhandle(self, prop):
+        """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: Prop object to check
+        Return:
+            True if the object value contains phandles, else False
+        """
+        if prop.name in ['clocks']:
+            return True
+        return False
+
+    def ScanStructs(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.
+        """
+        structs = {}
+        for node in self._valid_nodes:
+            node_name, _ = self.GetCompatName(node)
+            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 node_name before, update the existing struct.
+            if node_name in structs:
+                struct = structs[node_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_name] = fields
+
+        upto = 0
+        for node in self._valid_nodes:
+            node_name, _ = self.GetCompatName(node)
+            struct = structs[node_name]
+            for name, prop in node.props.items():
+                if name not in PROP_IGNORE_LIST and name[0] != '#':
+                    prop.Widen(struct[name])
+            upto += 1
+
+            struct_name, aliases = self.GetCompatName(node)
+            for alias in aliases:
+                self._aliases[alias] = struct_name
+
+        return structs
+
+    def ScanPhandles(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
+                if type(prop.value) == list:
+                    if self.IsPhandle(prop):
+                        # Process the list as pairs of (phandle, id)
+                        it = iter(prop.value)
+                        for phandle_cell, id_cell in zip(it, it):
+                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                            id = fdt_util.fdt32_to_cpu(id_cell)
+                            target_node = self._phandle_node[phandle]
+                            node.phandles.add(target_node)
+
+
+    def GenerateStructs(self, structs):
+        """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
+        README.of-plat for more information.
+        """
+        self.Out('#include <stdbool.h>\n')
+        self.Out('#include <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]
+                if self.IsPhandle(prop):
+                    # For phandles, include a reference to the target
+                    self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
+                                             Conv_name_to_c(prop.name),
+                                             len(prop.value) / 2))
+                else:
+                    ptype = TYPE_NAMES[prop.type]
+                    self.Out('\t%s%s' % (TabTo(2, ptype),
+                                         Conv_name_to_c(prop.name)))
+                    if type(prop.value) == list:
+                        self.Out('[%d]' % len(prop.value))
+                self.Out(';\n')
+            self.Out('};\n')
+
+        for alias, struct_name in self._aliases.iteritems():
+            self.Out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
+                                             STRUCT_PREFIX, struct_name))
+
+    def OutputNode(self, node):
+        """Output the C code for a node
+
+        Args:
+            node: node to output
+        """
+        struct_name, _ = self.GetCompatName(node)
+        var_name = Conv_name_to_c(node.name)
+        self.Buf('static struct %s%s %s%s = {\n' %
+            (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+        for pname, prop in node.props.items():
+            if pname in PROP_IGNORE_LIST or pname[0] == '#':
+                continue
+            ptype = TYPE_NAMES[prop.type]
+            member_name = Conv_name_to_c(prop.name)
+            self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
+
+            # Special handling for lists
+            if type(prop.value) == list:
+                self.Buf('{')
+                vals = []
+                # For phandles, output a reference to the platform data
+                # of the target node.
+                if self.IsPhandle(prop):
+                    # Process the list as pairs of (phandle, id)
+                    it = iter(prop.value)
+                    for phandle_cell, id_cell in zip(it, it):
+                        phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                        id = fdt_util.fdt32_to_cpu(id_cell)
+                        target_node = self._phandle_node[phandle]
+                        name = Conv_name_to_c(target_node.name)
+                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
+                else:
+                    for val in prop.value:
+                        vals.append(self.GetValue(prop.type, val))
+                self.Buf(', '.join(vals))
+                self.Buf('}')
+            else:
+                self.Buf(self.GetValue(prop.type, prop.value))
+            self.Buf(',\n')
+        self.Buf('};\n')
+
+        # Add a device declaration
+        self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+        self.Buf('\t.name\t\t= "%s",\n' % struct_name)
+        self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+        self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
+                    (VAL_PREFIX, var_name))
+        self.Buf('};\n')
+        self.Buf('\n')
+
+        self.Out(''.join(self.GetBuf()))
+
+    def GenerateTables(self):
+        """Generate device defintions for the platform data
+
+        This writes out C platform data initialisation data and
+        U_BOOT_DEVICE() 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.txt for more
+        information.
+        """
+        self.Out('#include <common.h>\n')
+        self.Out('#include <dm.h>\n')
+        self.Out('#include <dt-structs.h>\n')
+        self.Out('\n')
+        nodes_to_output = list(self._valid_nodes)
+
+        # Keep outputing nodes until there is none left
+        while nodes_to_output:
+            node = nodes_to_output[0]
+            # Output all the node's dependencies first
+            for req_node in node.phandles:
+                if req_node in nodes_to_output:
+                    self.OutputNode(req_node)
+                    nodes_to_output.remove(req_node)
+            self.OutputNode(node)
+            nodes_to_output.remove(node)
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 79779477d9..8fc717a92d 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -26,417 +26,15 @@ options. For more information about the use of this options and tool please
 see doc/driver-model/of-plat.txt
 """
 
-import copy
-from optparse import OptionError, OptionParser
+from optparse import OptionParser
 import os
-import struct
 import sys
 
 # Bring in the patman libraries
 our_path = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.join(our_path, '../patman'))
 
-import fdt
-import fdt_util
-
-# 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 tyues we support
-TYPE_NAMES = {
-    fdt.TYPE_INT: 'fdt32_t',
-    fdt.TYPE_BYTE: 'unsigned char',
-    fdt.TYPE_STRING: 'const char *',
-    fdt.TYPE_BOOL: 'bool',
-};
-
-STRUCT_PREFIX = 'dtd_'
-VAL_PREFIX = 'dtv_'
-
-def Conv_name_to_c(name):
-    """Convert a device-tree name to a C identifier
-
-    Args:
-        name:   Name to convert
-    Return:
-        String containing the C version of this name
-    """
-    str = name.replace('@', '_at_')
-    str = str.replace('-', '_')
-    str = str.replace(',', '_')
-    str = str.replace('.', '_')
-    str = str.replace('/', '__')
-    return str
-
-def TabTo(num_tabs, str):
-    if len(str) >= num_tabs * 8:
-        return str + ' '
-    return str + '\t' * (num_tabs - len(str) // 8)
-
-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:
-        fdt: Fdt object, referencing the device tree
-        _dtb_fname: Filename of the input device tree binary file
-        _valid_nodes: A list of Node object with compatible strings
-        _options: Command-line options
-        _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
-        _outfile: The current output file (sys.stdout or a real file)
-        _lines: Stashed list of output lines for outputting in the future
-        _phandle_node: A dict of Nodes indexed by phandle (an integer)
-    """
-    def __init__(self, dtb_fname, options):
-        self._dtb_fname = dtb_fname
-        self._valid_nodes = None
-        self._options = options
-        self._phandle_node = {}
-        self._outfile = None
-        self._lines = []
-        self._aliases = {}
-
-    def SetupOutput(self, fname):
-        """Set up the output destination
-
-        Once this is done, future calls to self.Out() will output to this
-        file.
-
-        Args:
-            fname: Filename to send output to, or '-' for stdout
-        """
-        if fname == '-':
-            self._outfile = sys.stdout
-        else:
-            self._outfile = open(fname, 'w')
-
-    def Out(self, str):
-        """Output a string to the output file
-
-        Args:
-            str: String to output
-        """
-        self._outfile.write(str)
-
-    def Buf(self, str):
-        """Buffer up a string to send later
-
-        Args:
-            str: String to add to our 'buffer' list
-        """
-        self._lines.append(str)
-
-    def GetBuf(self):
-        """Get the contents of the output buffer, and clear it
-
-        Returns:
-            The output buffer, which is then cleared for future use
-        """
-        lines = self._lines
-        self._lines = []
-        return lines
-
-    def GetValue(self, type, 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:
-            type: Data type (fdt_util)
-            value: Data value, as a string of bytes
-        """
-        if type == fdt.TYPE_INT:
-            return '%#x' % fdt_util.fdt32_to_cpu(value)
-        elif type == fdt.TYPE_BYTE:
-            return '%#x' % ord(value[0])
-        elif type == fdt.TYPE_STRING:
-            return '"%s"' % value
-        elif type == fdt.TYPE_BOOL:
-            return 'true'
-
-    def GetCompatName(self, node):
-        """Get a node's first compatible string as a C identifier
-
-        Args:
-            node: Node object to check
-        Return:
-            C identifier for the first compatible string
-        """
-        compat = node.props['compatible'].value
-        aliases = []
-        if type(compat) == list:
-            compat, aliases = compat[0], compat[1:]
-        return Conv_name_to_c(compat), [Conv_name_to_c(a) for a in aliases]
-
-    def ScanDtb(self):
-        """Scan the device tree to obtain a tree of notes 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 ScanNode(self, root):
-        for node in root.subnodes:
-            if 'compatible' in node.props:
-                status = node.props.get('status')
-                if (not self._options.include_disabled and not status or
-                    status.value != 'disabled'):
-                    self._valid_nodes.append(node)
-                    phandle_prop = node.props.get('phandle')
-                    if phandle_prop:
-                        phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
-
-            # recurse to handle any subnodes
-            self.ScanNode(node);
-
-    def ScanTree(self):
-        """Scan the device tree for useful information
-
-        This fills in the following properties:
-            _phandle_node: A dict of Nodes indexed by phandle (an integer)
-            _valid_nodes: A list of nodes we wish to consider include in the
-                platform data
-        """
-        self._phandle_node = {}
-        self._valid_nodes = []
-        return self.ScanNode(self.fdt.GetRoot());
-
-        for node in self.fdt.GetRoot().subnodes:
-            if 'compatible' in node.props:
-                status = node.props.get('status')
-                if (not self._options.include_disabled and not status or
-                    status.value != 'disabled'):
-                    node_list.append(node)
-                    phandle_prop = node.props.get('phandle')
-                    if phandle_prop:
-                        phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
-
-        self._valid_nodes = node_list
-
-    def IsPhandle(self, prop):
-        """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: Prop object to check
-        Return:
-            True if the object value contains phandles, else False
-        """
-        if prop.name in ['clocks']:
-            return True
-        return False
-
-    def ScanStructs(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.
-        """
-        structs = {}
-        for node in self._valid_nodes:
-            node_name, _ = self.GetCompatName(node)
-            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 node_name before, update the existing struct.
-            if node_name in structs:
-                struct = structs[node_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_name] = fields
-
-        upto = 0
-        for node in self._valid_nodes:
-            node_name, _ = self.GetCompatName(node)
-            struct = structs[node_name]
-            for name, prop in node.props.items():
-                if name not in PROP_IGNORE_LIST and name[0] != '#':
-                    prop.Widen(struct[name])
-            upto += 1
-
-            struct_name, aliases = self.GetCompatName(node)
-            for alias in aliases:
-                self._aliases[alias] = struct_name
-
-        return structs
-
-    def ScanPhandles(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
-                if type(prop.value) == list:
-                    if self.IsPhandle(prop):
-                        # Process the list as pairs of (phandle, id)
-                        it = iter(prop.value)
-                        for phandle_cell, id_cell in zip(it, it):
-                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                            id = fdt_util.fdt32_to_cpu(id_cell)
-                            target_node = self._phandle_node[phandle]
-                            node.phandles.add(target_node)
-
-
-    def GenerateStructs(self, structs):
-        """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
-        README.of-plat for more information.
-        """
-        self.Out('#include <stdbool.h>\n')
-        self.Out('#include <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]
-                if self.IsPhandle(prop):
-                    # For phandles, include a reference to the target
-                    self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
-                                             Conv_name_to_c(prop.name),
-                                             len(prop.value) / 2))
-                else:
-                    ptype = TYPE_NAMES[prop.type]
-                    self.Out('\t%s%s' % (TabTo(2, ptype),
-                                         Conv_name_to_c(prop.name)))
-                    if type(prop.value) == list:
-                        self.Out('[%d]' % len(prop.value))
-                self.Out(';\n')
-            self.Out('};\n')
-
-        for alias, struct_name in self._aliases.iteritems():
-            self.Out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
-                                             STRUCT_PREFIX, struct_name))
-
-    def OutputNode(self, node):
-        """Output the C code for a node
-
-        Args:
-            node: node to output
-        """
-        struct_name, _ = self.GetCompatName(node)
-        var_name = Conv_name_to_c(node.name)
-        self.Buf('static struct %s%s %s%s = {\n' %
-            (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
-        for pname, prop in node.props.items():
-            if pname in PROP_IGNORE_LIST or pname[0] == '#':
-                continue
-            ptype = TYPE_NAMES[prop.type]
-            member_name = Conv_name_to_c(prop.name)
-            self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
-
-            # Special handling for lists
-            if type(prop.value) == list:
-                self.Buf('{')
-                vals = []
-                # For phandles, output a reference to the platform data
-                # of the target node.
-                if self.IsPhandle(prop):
-                    # Process the list as pairs of (phandle, id)
-                    it = iter(prop.value)
-                    for phandle_cell, id_cell in zip(it, it):
-                        phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                        id = fdt_util.fdt32_to_cpu(id_cell)
-                        target_node = self._phandle_node[phandle]
-                        name = Conv_name_to_c(target_node.name)
-                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
-                else:
-                    for val in prop.value:
-                        vals.append(self.GetValue(prop.type, val))
-                self.Buf(', '.join(vals))
-                self.Buf('}')
-            else:
-                self.Buf(self.GetValue(prop.type, prop.value))
-            self.Buf(',\n')
-        self.Buf('};\n')
-
-        # Add a device declaration
-        self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
-        self.Buf('\t.name\t\t= "%s",\n' % struct_name)
-        self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
-        self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
-                    (VAL_PREFIX, var_name))
-        self.Buf('};\n')
-        self.Buf('\n')
-
-        self.Out(''.join(self.GetBuf()))
-
-    def GenerateTables(self):
-        """Generate device defintions for the platform data
-
-        This writes out C platform data initialisation data and
-        U_BOOT_DEVICE() 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.txt for more
-        information.
-        """
-        self.Out('#include <common.h>\n')
-        self.Out('#include <dm.h>\n')
-        self.Out('#include <dt-structs.h>\n')
-        self.Out('\n')
-        nodes_to_output = list(self._valid_nodes)
-
-        # Keep outputing nodes until there is none left
-        while nodes_to_output:
-            node = nodes_to_output[0]
-            # Output all the node's dependencies first
-            for req_node in node.phandles:
-                if req_node in nodes_to_output:
-                    self.OutputNode(req_node)
-                    nodes_to_output.remove(req_node)
-            self.OutputNode(node)
-            nodes_to_output.remove(node)
+import dtb_platdata
 
 
 if __name__ != "__main__":
@@ -454,7 +52,7 @@ parser.add_option('-o', '--output', action='store', default='-',
 if not args:
     raise ValueError('Please specify a command: struct, platdata')
 
-plat = DtbPlatdata(options.dtb_file, options)
+plat = dtb_platdata.DtbPlatdata(options.dtb_file, options)
 plat.ScanDtb()
 plat.ScanTree()
 plat.SetupOutput(options.output)
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (2 preceding siblings ...)
  2017-06-19  4:08 ` [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file Simon Glass
@ 2017-06-19  4:08 ` Simon Glass
  2017-07-06 14:51   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them Simon Glass
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:08 UTC (permalink / raw)
  To: u-boot

Unfortunately I neglected to run pylint on this tool with its initial
submission. Fix the warnings.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 261 ++++++++++++++++++++++++---------------------
 tools/dtoc/dtoc.py         |  14 +--
 2 files changed, 144 insertions(+), 131 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 94db274c09..75adf48dea 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -6,7 +6,14 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+"""Device tree to platform data class
+
+This supports converting device tree data to C structures definitions and
+static data.
+"""
+
 import copy
+import sys
 
 import fdt
 import fdt_util
@@ -31,12 +38,12 @@ TYPE_NAMES = {
     fdt.TYPE_BYTE: 'unsigned char',
     fdt.TYPE_STRING: 'const char *',
     fdt.TYPE_BOOL: 'bool',
-};
+}
 
 STRUCT_PREFIX = 'dtd_'
 VAL_PREFIX = 'dtv_'
 
-def Conv_name_to_c(name):
+def conv_name_to_c(name):
     """Convert a device-tree name to a C identifier
 
     Args:
@@ -44,19 +51,29 @@ def Conv_name_to_c(name):
     Return:
         String containing the C version of this name
     """
-    str = name.replace('@', '_at_')
-    str = str.replace('-', '_')
-    str = str.replace(',', '_')
-    str = str.replace('.', '_')
-    str = str.replace('/', '__')
-    return str
-
-def TabTo(num_tabs, str):
-    if len(str) >= num_tabs * 8:
-        return str + ' '
-    return str + '\t' * (num_tabs - len(str) // 8)
-
-class DtbPlatdata:
+    new = name.replace('@', '_at_')
+    new = new.replace('-', '_')
+    new = new.replace(',', '_')
+    new = new.replace('.', '_')
+    new = new.replace('/', '__')
+    return new
+
+def tab_to(num_tabs, line):
+    """Append tabs to a line of text to reach a tab stop.
+
+    Args:
+        num_tabs: Tab stop to obtain (0 = column 0, 1 = column 8, etc.)
+        line: Line of text to append to
+
+    Returns:
+        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)
+
+class DtbPlatdata(object):
     """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-
@@ -64,28 +81,29 @@ class DtbPlatdata:
     code is not affordable.
 
     Properties:
-        fdt: Fdt object, referencing the device tree
+        _fdt: Fdt object, referencing the device tree
         _dtb_fname: Filename of the input device tree binary file
         _valid_nodes: A list of Node object with compatible strings
         _options: Command-line options
-        _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
+        _phandle_nodes: A dict of nodes indexed by phandle number (1, 2...)
         _outfile: The current output file (sys.stdout or a real file)
         _lines: Stashed list of output lines for outputting in the future
-        _phandle_node: A dict of Nodes indexed by phandle (an integer)
+        _phandle_nodes: A dict of Nodes indexed by phandle (an integer)
     """
     def __init__(self, dtb_fname, options):
+        self._fdt = None
         self._dtb_fname = dtb_fname
         self._valid_nodes = None
         self._options = options
-        self._phandle_node = {}
+        self._phandle_nodes = {}
         self._outfile = None
         self._lines = []
         self._aliases = {}
 
-    def SetupOutput(self, fname):
+    def setup_output(self, fname):
         """Set up the output destination
 
-        Once this is done, future calls to self.Out() will output to this
+        Once this is done, future calls to self.out() will output to this
         file.
 
         Args:
@@ -96,23 +114,23 @@ class DtbPlatdata:
         else:
             self._outfile = open(fname, 'w')
 
-    def Out(self, str):
+    def out(self, line):
         """Output a string to the output file
 
         Args:
-            str: String to output
+            line: String to output
         """
-        self._outfile.write(str)
+        self._outfile.write(line)
 
-    def Buf(self, str):
+    def buf(self, line):
         """Buffer up a string to send later
 
         Args:
-            str: String to add to our 'buffer' list
+            line: String to add to our 'buffer' list
         """
-        self._lines.append(str)
+        self._lines.append(line)
 
-    def GetBuf(self):
+    def get_buf(self):
         """Get the contents of the output buffer, and clear it
 
         Returns:
@@ -122,7 +140,8 @@ class DtbPlatdata:
         self._lines = []
         return lines
 
-    def GetValue(self, type, value):
+    @staticmethod
+    def get_value(ftype, value):
         """Get a value as a C expression
 
         For integers this returns a byte-swapped (little-endian) hex string
@@ -134,16 +153,17 @@ class DtbPlatdata:
             type: Data type (fdt_util)
             value: Data value, as a string of bytes
         """
-        if type == fdt.TYPE_INT:
+        if ftype == fdt.TYPE_INT:
             return '%#x' % fdt_util.fdt32_to_cpu(value)
-        elif type == fdt.TYPE_BYTE:
+        elif ftype == fdt.TYPE_BYTE:
             return '%#x' % ord(value[0])
-        elif type == fdt.TYPE_STRING:
+        elif ftype == fdt.TYPE_STRING:
             return '"%s"' % value
-        elif type == fdt.TYPE_BOOL:
+        elif ftype == fdt.TYPE_BOOL:
             return 'true'
 
-    def GetCompatName(self, node):
+    @staticmethod
+    def get_compat_name(node):
         """Get a node's first compatible string as a C identifier
 
         Args:
@@ -153,59 +173,55 @@ class DtbPlatdata:
         """
         compat = node.props['compatible'].value
         aliases = []
-        if type(compat) == list:
+        if isinstance(compat, list):
             compat, aliases = compat[0], compat[1:]
-        return Conv_name_to_c(compat), [Conv_name_to_c(a) for a in aliases]
+        return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases]
 
-    def ScanDtb(self):
+    def scan_dtb(self):
         """Scan the device tree to obtain a tree of notes and properties
 
-        Once this is done, self.fdt.GetRoot() can be called to obtain the
+        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)
+        self._fdt = fdt.FdtScan(self._dtb_fname)
+
+    def scan_node(self, root):
+        """Scan a node and subnodes to build a tree of node and phandle info
+
+        This adds each node to self._valid_nodes and each phandle to
+        self._phandle_nodes.
 
-    def ScanNode(self, root):
+        Args:
+            root: Root node for scan
+        """
         for node in root.subnodes:
             if 'compatible' in node.props:
                 status = node.props.get('status')
                 if (not self._options.include_disabled and not status or
-                    status.value != 'disabled'):
+                        status.value != 'disabled'):
                     self._valid_nodes.append(node)
                     phandle_prop = node.props.get('phandle')
                     if phandle_prop:
                         phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
+                        self._phandle_nodes[phandle] = node
 
             # recurse to handle any subnodes
-            self.ScanNode(node);
+            self.scan_node(node)
 
-    def ScanTree(self):
+    def scan_tree(self):
         """Scan the device tree for useful information
 
         This fills in the following properties:
-            _phandle_node: A dict of Nodes indexed by phandle (an integer)
+            _phandle_nodes: A dict of Nodes indexed by phandle (an integer)
             _valid_nodes: A list of nodes we wish to consider include in the
                 platform data
         """
-        self._phandle_node = {}
+        self._phandle_nodes = {}
         self._valid_nodes = []
-        return self.ScanNode(self.fdt.GetRoot());
-
-        for node in self.fdt.GetRoot().subnodes:
-            if 'compatible' in node.props:
-                status = node.props.get('status')
-                if (not self._options.include_disabled and not status or
-                    status.value != 'disabled'):
-                    node_list.append(node)
-                    phandle_prop = node.props.get('phandle')
-                    if phandle_prop:
-                        phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
-
-        self._valid_nodes = node_list
+        return self.scan_node(self._fdt.GetRoot())
 
-    def IsPhandle(self, prop):
+    @staticmethod
+    def is_phandle(prop):
         """Check if a node contains phandles
 
         We have no reliable way of detecting whether a node uses a phandle
@@ -220,7 +236,7 @@ class DtbPlatdata:
             return True
         return False
 
-    def ScanStructs(self):
+    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
@@ -233,7 +249,7 @@ class DtbPlatdata:
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = self.GetCompatName(node)
+            node_name, _ = self.get_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -257,20 +273,20 @@ class DtbPlatdata:
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = self.GetCompatName(node)
+            node_name, _ = self.get_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = self.GetCompatName(node)
+            struct_name, aliases = self.get_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
         return structs
 
-    def ScanPhandles(self):
+    def scan_phandles(self):
         """Figure out what phandles each node uses
 
         We need to be careful when outputing nodes that use phandles since
@@ -286,104 +302,101 @@ class DtbPlatdata:
             for pname, prop in node.props.items():
                 if pname in PROP_IGNORE_LIST or pname[0] == '#':
                     continue
-                if type(prop.value) == list:
-                    if self.IsPhandle(prop):
+                if isinstance(prop.value, list):
+                    if self.is_phandle(prop):
                         # Process the list as pairs of (phandle, id)
-                        it = iter(prop.value)
-                        for phandle_cell, id_cell in zip(it, it):
+                        value_it = iter(prop.value)
+                        for phandle_cell, _ in zip(value_it, value_it):
                             phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                            id = fdt_util.fdt32_to_cpu(id_cell)
-                            target_node = self._phandle_node[phandle]
+                            target_node = self._phandle_nodes[phandle]
                             node.phandles.add(target_node)
 
 
-    def GenerateStructs(self, structs):
+    def generate_structs(self, structs):
         """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
         README.of-plat for more information.
         """
-        self.Out('#include <stdbool.h>\n')
-        self.Out('#include <libfdt.h>\n')
+        self.out('#include <stdbool.h>\n')
+        self.out('#include <libfdt.h>\n')
 
         # Output the struct definition
         for name in sorted(structs):
-            self.Out('struct %s%s {\n' % (STRUCT_PREFIX, name));
+            self.out('struct %s%s {\n' % (STRUCT_PREFIX, name))
             for pname in sorted(structs[name]):
                 prop = structs[name][pname]
-                if self.IsPhandle(prop):
+                if self.is_phandle(prop):
                     # For phandles, include a reference to the target
-                    self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
-                                             Conv_name_to_c(prop.name),
+                    self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'),
+                                             conv_name_to_c(prop.name),
                                              len(prop.value) / 2))
                 else:
                     ptype = TYPE_NAMES[prop.type]
-                    self.Out('\t%s%s' % (TabTo(2, ptype),
-                                         Conv_name_to_c(prop.name)))
-                    if type(prop.value) == list:
-                        self.Out('[%d]' % len(prop.value))
-                self.Out(';\n')
-            self.Out('};\n')
+                    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')
 
         for alias, struct_name in self._aliases.iteritems():
-            self.Out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
+            self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
                                              STRUCT_PREFIX, struct_name))
 
-    def OutputNode(self, node):
+    def output_node(self, node):
         """Output the C code for a node
 
         Args:
             node: node to output
         """
-        struct_name, _ = self.GetCompatName(node)
-        var_name = Conv_name_to_c(node.name)
-        self.Buf('static struct %s%s %s%s = {\n' %
-            (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+        struct_name, _ = self.get_compat_name(node)
+        var_name = conv_name_to_c(node.name)
+        self.buf('static struct %s%s %s%s = {\n' %
+                 (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
         for pname, prop in node.props.items():
             if pname in PROP_IGNORE_LIST or pname[0] == '#':
                 continue
-            ptype = TYPE_NAMES[prop.type]
-            member_name = Conv_name_to_c(prop.name)
-            self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
+            member_name = conv_name_to_c(prop.name)
+            self.buf('\t%s= ' % tab_to(3, '.' + member_name))
 
             # Special handling for lists
-            if type(prop.value) == list:
-                self.Buf('{')
+            if isinstance(prop.value, list):
+                self.buf('{')
                 vals = []
                 # For phandles, output a reference to the platform data
                 # of the target node.
-                if self.IsPhandle(prop):
+                if self.is_phandle(prop):
                     # Process the list as pairs of (phandle, id)
-                    it = iter(prop.value)
-                    for phandle_cell, id_cell in zip(it, it):
+                    value_it = iter(prop.value)
+                    for phandle_cell, id_cell in zip(value_it, value_it):
                         phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                        id = fdt_util.fdt32_to_cpu(id_cell)
-                        target_node = self._phandle_node[phandle]
-                        name = Conv_name_to_c(target_node.name)
-                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
+                        id_num = fdt_util.fdt32_to_cpu(id_cell)
+                        target_node = self._phandle_nodes[phandle]
+                        name = conv_name_to_c(target_node.name)
+                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num))
                 else:
                     for val in prop.value:
-                        vals.append(self.GetValue(prop.type, val))
-                self.Buf(', '.join(vals))
-                self.Buf('}')
+                        vals.append(self.get_value(prop.type, val))
+                self.buf(', '.join(vals))
+                self.buf('}')
             else:
-                self.Buf(self.GetValue(prop.type, prop.value))
-            self.Buf(',\n')
-        self.Buf('};\n')
+                self.buf(self.get_value(prop.type, prop.value))
+            self.buf(',\n')
+        self.buf('};\n')
 
         # Add a device declaration
-        self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
-        self.Buf('\t.name\t\t= "%s",\n' % struct_name)
-        self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
-        self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
-                    (VAL_PREFIX, var_name))
-        self.Buf('};\n')
-        self.Buf('\n')
+        self.buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+        self.buf('\t.name\t\t= "%s",\n' % struct_name)
+        self.buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+        self.buf('\t.platdata_size\t= sizeof(%s%s),\n' % (VAL_PREFIX, var_name))
+        self.buf('};\n')
+        self.buf('\n')
 
-        self.Out(''.join(self.GetBuf()))
+        self.out(''.join(self.get_buf()))
 
-    def GenerateTables(self):
+    def generate_tables(self):
         """Generate device defintions for the platform data
 
         This writes out C platform data initialisation data and
@@ -393,10 +406,10 @@ class DtbPlatdata:
         See the documentation in doc/driver-model/of-plat.txt for more
         information.
         """
-        self.Out('#include <common.h>\n')
-        self.Out('#include <dm.h>\n')
-        self.Out('#include <dt-structs.h>\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')
         nodes_to_output = list(self._valid_nodes)
 
         # Keep outputing nodes until there is none left
@@ -405,7 +418,7 @@ class DtbPlatdata:
             # Output all the node's dependencies first
             for req_node in node.phandles:
                 if req_node in nodes_to_output:
-                    self.OutputNode(req_node)
+                    self.output_node(req_node)
                     nodes_to_output.remove(req_node)
-            self.OutputNode(node)
+            self.output_node(node)
             nodes_to_output.remove(node)
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 8fc717a92d..abda9191fa 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -53,16 +53,16 @@ if not args:
     raise ValueError('Please specify a command: struct, platdata')
 
 plat = dtb_platdata.DtbPlatdata(options.dtb_file, options)
-plat.ScanDtb()
-plat.ScanTree()
-plat.SetupOutput(options.output)
-structs = plat.ScanStructs()
-plat.ScanPhandles()
+plat.scan_dtb()
+plat.scan_tree()
+plat.setup_output(options.output)
+structs = plat.scan_structs()
+plat.scan_phandles()
 
 for cmd in args[0].split(','):
     if cmd == 'struct':
-        plat.GenerateStructs(structs)
+        plat.generate_structs(structs)
     elif cmd == 'platdata':
-        plat.GenerateTables()
+        plat.generate_tables()
     else:
         raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (3 preceding siblings ...)
  2017-06-19  4:08 ` [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:51   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly Simon Glass
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

This conversion appears to not be needed as it does not occur in practice.
Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 75adf48dea..d86651b9aa 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -55,7 +55,6 @@ def conv_name_to_c(name):
     new = new.replace('-', '_')
     new = new.replace(',', '_')
     new = new.replace('.', '_')
-    new = new.replace('/', '__')
     return new
 
 def tab_to(num_tabs, line):
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (4 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:49   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class Simon Glass
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

This option is the only one actually used by the dtb_platdata class. Pass
it explicitly to avoid needing to pass the whole option object to the
constructor.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 8 ++++----
 tools/dtoc/dtoc.py         | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index d86651b9aa..de4a88b5a9 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -83,17 +83,17 @@ class DtbPlatdata(object):
         _fdt: Fdt object, referencing the device tree
         _dtb_fname: Filename of the input device tree binary file
         _valid_nodes: A list of Node object with compatible strings
-        _options: Command-line options
+        _include_disabled: true to include nodes marked status = "disabled"
         _phandle_nodes: A dict of nodes indexed by phandle number (1, 2...)
         _outfile: The current output file (sys.stdout or a real file)
         _lines: Stashed list of output lines for outputting in the future
         _phandle_nodes: A dict of Nodes indexed by phandle (an integer)
     """
-    def __init__(self, dtb_fname, options):
+    def __init__(self, dtb_fname, include_disabled):
         self._fdt = None
         self._dtb_fname = dtb_fname
         self._valid_nodes = None
-        self._options = options
+        self._include_disabled = include_disabled
         self._phandle_nodes = {}
         self._outfile = None
         self._lines = []
@@ -196,7 +196,7 @@ class DtbPlatdata(object):
         for node in root.subnodes:
             if 'compatible' in node.props:
                 status = node.props.get('status')
-                if (not self._options.include_disabled and not status or
+                if (not self._include_disabled and not status or
                         status.value != 'disabled'):
                     self._valid_nodes.append(node)
                     phandle_prop = node.props.get('phandle')
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index abda9191fa..1f17ea47e0 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -52,7 +52,7 @@ parser.add_option('-o', '--output', action='store', default='-',
 if not args:
     raise ValueError('Please specify a command: struct, platdata')
 
-plat = dtb_platdata.DtbPlatdata(options.dtb_file, options)
+plat = dtb_platdata.DtbPlatdata(options.dtb_file, options.include_disabled)
 plat.scan_dtb()
 plat.scan_tree()
 plat.setup_output(options.output)
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (5 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:49   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file Simon Glass
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

Rather than using static functions within the class, move them out of the
class. This will make it slightly easier for tests to call them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 125 +++++++++++++++++++++++----------------------
 1 file changed, 63 insertions(+), 62 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index de4a88b5a9..a1f32e164a 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -72,6 +72,60 @@ def tab_to(num_tabs, line):
         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:
+        type: Data type (fdt_util)
+        value: Data value, as a string of bytes
+    """
+    if ftype == fdt.TYPE_INT:
+        return '%#x' % fdt_util.fdt32_to_cpu(value)
+    elif ftype == fdt.TYPE_BYTE:
+        return '%#x' % ord(value[0])
+    elif ftype == fdt.TYPE_STRING:
+        return '"%s"' % value
+    elif ftype == fdt.TYPE_BOOL:
+        return 'true'
+
+def get_compat_name(node):
+    """Get a node's first compatible string as a C identifier
+
+    Args:
+        node: Node object to check
+    Return:
+        Tuple:
+            C identifier for the first compatible string
+            List of C identifiers for all the other compatible strings
+                (possibly empty)
+    """
+    compat = node.props['compatible'].value
+    aliases = []
+    if isinstance(compat, list):
+        compat, aliases = compat[0], compat[1:]
+    return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases]
+
+def is_phandle(prop):
+    """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: Prop object to check
+    Return:
+        True if the object value contains phandles, else False
+    """
+    if prop.name in ['clocks']:
+        return True
+    return False
+
+
 class DtbPlatdata(object):
     """Provide a means to convert device tree binary data to platform data
 
@@ -139,43 +193,6 @@ class DtbPlatdata(object):
         self._lines = []
         return lines
 
-    @staticmethod
-    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:
-            type: Data type (fdt_util)
-            value: Data value, as a string of bytes
-        """
-        if ftype == fdt.TYPE_INT:
-            return '%#x' % fdt_util.fdt32_to_cpu(value)
-        elif ftype == fdt.TYPE_BYTE:
-            return '%#x' % ord(value[0])
-        elif ftype == fdt.TYPE_STRING:
-            return '"%s"' % value
-        elif ftype == fdt.TYPE_BOOL:
-            return 'true'
-
-    @staticmethod
-    def get_compat_name(node):
-        """Get a node's first compatible string as a C identifier
-
-        Args:
-            node: Node object to check
-        Return:
-            C identifier for the first compatible string
-        """
-        compat = node.props['compatible'].value
-        aliases = []
-        if isinstance(compat, list):
-            compat, aliases = compat[0], compat[1:]
-        return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases]
-
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of notes and properties
 
@@ -219,22 +236,6 @@ class DtbPlatdata(object):
         self._valid_nodes = []
         return self.scan_node(self._fdt.GetRoot())
 
-    @staticmethod
-    def is_phandle(prop):
-        """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: Prop object to check
-        Return:
-            True if the object value contains phandles, else False
-        """
-        if prop.name in ['clocks']:
-            return True
-        return False
-
     def scan_structs(self):
         """Scan the device tree building up the C structures we will use.
 
@@ -248,7 +249,7 @@ class DtbPlatdata(object):
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = self.get_compat_name(node)
+            node_name, _ = get_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -272,14 +273,14 @@ class DtbPlatdata(object):
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = self.get_compat_name(node)
+            node_name, _ = get_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = self.get_compat_name(node)
+            struct_name, aliases = get_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
@@ -302,7 +303,7 @@ class DtbPlatdata(object):
                 if pname in PROP_IGNORE_LIST or pname[0] == '#':
                     continue
                 if isinstance(prop.value, list):
-                    if self.is_phandle(prop):
+                    if is_phandle(prop):
                         # Process the list as pairs of (phandle, id)
                         value_it = iter(prop.value)
                         for phandle_cell, _ in zip(value_it, value_it):
@@ -326,7 +327,7 @@ class DtbPlatdata(object):
             self.out('struct %s%s {\n' % (STRUCT_PREFIX, name))
             for pname in sorted(structs[name]):
                 prop = structs[name][pname]
-                if self.is_phandle(prop):
+                if is_phandle(prop):
                     # For phandles, include a reference to the target
                     self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'),
                                              conv_name_to_c(prop.name),
@@ -350,7 +351,7 @@ class DtbPlatdata(object):
         Args:
             node: node to output
         """
-        struct_name, _ = self.get_compat_name(node)
+        struct_name, _ = get_compat_name(node)
         var_name = conv_name_to_c(node.name)
         self.buf('static struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
@@ -366,7 +367,7 @@ class DtbPlatdata(object):
                 vals = []
                 # For phandles, output a reference to the platform data
                 # of the target node.
-                if self.is_phandle(prop):
+                if is_phandle(prop):
                     # Process the list as pairs of (phandle, id)
                     value_it = iter(prop.value)
                     for phandle_cell, id_cell in zip(value_it, value_it):
@@ -377,11 +378,11 @@ class DtbPlatdata(object):
                         vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num))
                 else:
                     for val in prop.value:
-                        vals.append(self.get_value(prop.type, val))
+                        vals.append(get_value(prop.type, val))
                 self.buf(', '.join(vals))
                 self.buf('}')
             else:
-                self.buf(self.get_value(prop.type, prop.value))
+                self.buf(get_value(prop.type, prop.value))
             self.buf(',\n')
         self.buf('};\n')
 
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (6 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:49   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c() Simon Glass
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

Collect the main logic of dtoc into a function and put it into
dtb_platdata. This will allow tests to use this function instead of
duplicating the code themselves.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 29 +++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py         | 19 ++-----------------
 2 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index a1f32e164a..9923892dc3 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -422,3 +422,32 @@ class DtbPlatdata(object):
                     nodes_to_output.remove(req_node)
             self.output_node(node)
             nodes_to_output.remove(node)
+
+
+def run_steps(args, dtb_file, include_disabled, output):
+    """Run all the steps of the dtoc tool
+
+    Args:
+        args: List of non-option arguments provided to the problem
+        dtb_file: Filename of dtb file to process
+        include_disabled: True to include disabled nodes
+        output: Name of output file
+    """
+    if not args:
+        raise ValueError('Please specify a command: struct, platdata')
+
+    plat = DtbPlatdata(dtb_file, include_disabled)
+    plat.scan_dtb()
+    plat.scan_tree()
+    plat.setup_output(output)
+    structs = plat.scan_structs()
+    plat.scan_phandles()
+
+    for cmd in args[0].split(','):
+        if cmd == 'struct':
+            plat.generate_structs(structs)
+        elif cmd == 'platdata':
+            plat.generate_tables()
+        else:
+            raise ValueError("Unknown command '%s': (use: struct, platdata)" %
+                             cmd)
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 1f17ea47e0..140a19e9d4 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -49,20 +49,5 @@ parser.add_option('-o', '--output', action='store', default='-',
                   help='Select output filename')
 (options, args) = parser.parse_args()
 
-if not args:
-    raise ValueError('Please specify a command: struct, platdata')
-
-plat = dtb_platdata.DtbPlatdata(options.dtb_file, options.include_disabled)
-plat.scan_dtb()
-plat.scan_tree()
-plat.setup_output(options.output)
-structs = plat.scan_structs()
-plat.scan_phandles()
-
-for cmd in args[0].split(','):
-    if cmd == 'struct':
-        plat.generate_structs(structs)
-    elif cmd == 'platdata':
-        plat.generate_tables()
-    else:
-        raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)
+dtb_platdata.run_steps(args, options.dtb_file, options.include_disabled,
+                       options.output)
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c()
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (7 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:48   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL Simon Glass
  2017-06-19  4:09 ` [U-Boot] [PATCH 11/11] dtoc: Add tests Simon Glass
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

This function uses several separate string replaces where a regular
expression might seem more reasonable. Add a comment justifying the way it
is currently done.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 9923892dc3..1f85343a9f 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -46,6 +46,9 @@ VAL_PREFIX = 'dtv_'
 def conv_name_to_c(name):
     """Convert a device-tree name to a C identifier
 
+    This uses multiple replace() calls instead of re.sub() since it is faster
+    (400ms for 1m calls versus 1000ms for the 're' version).
+
     Args:
         name:   Name to convert
     Return:
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (8 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c() Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:48   ` sjg at google.com
  2017-06-19  4:09 ` [U-Boot] [PATCH 11/11] dtoc: Add tests Simon Glass
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

Currently we have code which prints out platform data at the start of SPL.
Now that we have tests for dtoc this is probably not necessary. Drop it.
Update test_ofplatdata to check for empty output since it is useful to
check that sandbox_spl works as expected.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 11 -----------
 test/py/tests/test_ofplatdata.py | 30 +-----------------------------
 2 files changed, 1 insertion(+), 40 deletions(-)

diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 7cc76d4cf1..2495fa9b08 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -44,16 +44,5 @@ SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
 
 void spl_board_init(void)
 {
-	struct udevice *dev;
-
 	preloader_console_init();
-
-	/*
-	* Scan all the devices so that we can output their platform data. See
-	* sandbox_spl_probe().
-	*/
-	for (uclass_first_device(UCLASS_MISC, &dev);
-	dev;
-	uclass_next_device(&dev))
-		;
 }
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 457c4055af..0660ce41d8 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -4,35 +4,7 @@
 
 import pytest
 
-OF_PLATDATA_OUTPUT = '''
-of-platdata probe:
-bool 1
-byte 05
-bytearray 06 00 00
-int 1
-intarray 2 3 4 0
-longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
-string message
-stringarray "multi-word" "message" ""
-of-platdata probe:
-bool 0
-byte 08
-bytearray 01 23 34
-int 3
-intarray 5 0 0 0
-longbytearray 09 00 00 00 00 00 00 00 00
-string message2
-stringarray "another" "multi-word" "message"
-of-platdata probe:
-bool 0
-byte 00
-bytearray 00 00 00
-int 0
-intarray 0 0 0 0
-longbytearray 00 00 00 00 00 00 00 00 00
-string <NULL>
-stringarray "one" "" ""
-'''
+OF_PLATDATA_OUTPUT = ''
 
 @pytest.mark.buildconfigspec('spl_of_platdata')
 def test_ofplatdata(u_boot_console):
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 11/11] dtoc: Add tests
  2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
                   ` (9 preceding siblings ...)
  2017-06-19  4:09 ` [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL Simon Glass
@ 2017-06-19  4:09 ` Simon Glass
  2017-07-06 14:48   ` sjg at google.com
  10 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2017-06-19  4:09 UTC (permalink / raw)
  To: u-boot

Add some tests of dtoc's functionality to make it easier to expand and
enhance the tool.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py               |  31 ++++-
 tools/dtoc/dtoc_test.dts         |  12 ++
 tools/dtoc/dtoc_test_aliases.dts |  18 +++
 tools/dtoc/dtoc_test_empty.dts   |  12 ++
 tools/dtoc/dtoc_test_phandle.dts |  23 ++++
 tools/dtoc/dtoc_test_simple.dts  |  48 +++++++
 tools/dtoc/test_dtoc.py          | 271 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 411 insertions(+), 4 deletions(-)
 create mode 100644 tools/dtoc/dtoc_test.dts
 create mode 100644 tools/dtoc/dtoc_test_aliases.dts
 create mode 100644 tools/dtoc/dtoc_test_empty.dts
 create mode 100644 tools/dtoc/dtoc_test_phandle.dts
 create mode 100644 tools/dtoc/dtoc_test_simple.dts
 create mode 100644 tools/dtoc/test_dtoc.py

diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 140a19e9d4..ce7bc054e5 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -29,6 +29,7 @@ see doc/driver-model/of-plat.txt
 from optparse import OptionParser
 import os
 import sys
+import unittest
 
 # Bring in the patman libraries
 our_path = os.path.dirname(os.path.realpath(__file__))
@@ -36,9 +37,24 @@ sys.path.append(os.path.join(our_path, '../patman'))
 
 import dtb_platdata
 
+def run_tests():
+    """Run all the test we have for dtoc"""
+    import test_dtoc
 
-if __name__ != "__main__":
-    pass
+    result = unittest.TestResult()
+    sys.argv = [sys.argv[0]]
+    for module in (test_dtoc.TestDtoc,):
+        suite = unittest.TestLoader().loadTestsFromTestCase(module)
+        suite.run(result)
+
+    print result
+    for _, err in result.errors:
+        print err
+    for _, err in result.failures:
+        print err
+
+if __name__ != '__main__':
+    sys.exit(1)
 
 parser = OptionParser()
 parser.add_option('-d', '--dtb-file', action='store',
@@ -47,7 +63,14 @@ parser.add_option('--include-disabled', action='store_true',
                   help='Include disabled nodes')
 parser.add_option('-o', '--output', action='store', default='-',
                   help='Select output filename')
+parser.add_option('-t', '--test', action='store_true', dest='test',
+                  default=False, help='run tests')
 (options, args) = parser.parse_args()
 
-dtb_platdata.run_steps(args, options.dtb_file, options.include_disabled,
-                       options.output)
+# Run our meagre tests
+if options.test:
+    run_tests()
+
+else:
+    dtb_platdata.run_steps(args, options.dtb_file, options.include_disabled,
+                           options.output)
diff --git a/tools/dtoc/dtoc_test.dts b/tools/dtoc/dtoc_test.dts
new file mode 100644
index 0000000000..1e86655975
--- /dev/null
+++ b/tools/dtoc/dtoc_test.dts
@@ -0,0 +1,12 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+};
diff --git a/tools/dtoc/dtoc_test_aliases.dts b/tools/dtoc/dtoc_test_aliases.dts
new file mode 100644
index 0000000000..c727f185af
--- /dev/null
+++ b/tools/dtoc/dtoc_test_aliases.dts
@@ -0,0 +1,18 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+	spl-test {
+		u-boot,dm-pre-reloc;
+		compatible = "compat1", "compat2.1-fred", "compat3";
+		intval = <1>;
+	};
+
+};
diff --git a/tools/dtoc/dtoc_test_empty.dts b/tools/dtoc/dtoc_test_empty.dts
new file mode 100644
index 0000000000..1e86655975
--- /dev/null
+++ b/tools/dtoc/dtoc_test_empty.dts
@@ -0,0 +1,12 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+};
diff --git a/tools/dtoc/dtoc_test_phandle.dts b/tools/dtoc/dtoc_test_phandle.dts
new file mode 100644
index 0000000000..e9828a695b
--- /dev/null
+++ b/tools/dtoc/dtoc_test_phandle.dts
@@ -0,0 +1,23 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+	phandle: phandle-target {
+		u-boot,dm-pre-reloc;
+		compatible = "target";
+		intval = <1>;
+	};
+
+	phandle-source {
+		u-boot,dm-pre-reloc;
+		compatible = "source";
+		clocks = <&phandle 1>;
+	};
+};
diff --git a/tools/dtoc/dtoc_test_simple.dts b/tools/dtoc/dtoc_test_simple.dts
new file mode 100644
index 0000000000..c736686263
--- /dev/null
+++ b/tools/dtoc/dtoc_test_simple.dts
@@ -0,0 +1,48 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+	spl-test {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,spl-test";
+		boolval;
+		intval = <1>;
+		intarray = <2 3 4>;
+		byteval = [05];
+		bytearray = [06];
+		longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+		stringval = "message";
+		stringarray = "multi-word", "message";
+	};
+
+	spl-test2 {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,spl-test";
+		intval = <3>;
+		intarray = <5>;
+		byteval = [08];
+		bytearray = [01 23 34];
+		longbytearray = [09 0a 0b 0c];
+		stringval = "message2";
+		stringarray = "another", "multi-word", "message";
+	};
+
+	spl-test3 {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,spl-test";
+		stringarray = "one";
+	};
+
+	spl-test4 {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,spl-test.2";
+	};
+
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
new file mode 100644
index 0000000000..8b95c4124f
--- /dev/null
+++ b/tools/dtoc/test_dtoc.py
@@ -0,0 +1,271 @@
+#
+# Copyright (c) 2012 The Chromium OS Authors.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+"""Tests for the dtb_platdata module
+
+This includes unit tests for some functions and functional tests for
+"""
+
+import collections
+import os
+import struct
+import unittest
+
+import dtb_platdata
+from dtb_platdata import conv_name_to_c
+from dtb_platdata import get_compat_name
+from dtb_platdata import get_value
+from dtb_platdata import tab_to
+import fdt
+import fdt_util
+import tools
+
+our_path = os.path.dirname(os.path.realpath(__file__))
+
+
+def get_dtb_file(dts_fname):
+    """Compile a .dts file to a .dtb
+
+    Args:
+        dts_fname: Filename of .dts file in the current directory
+
+    Returns:
+        Filename of compiled file in output directory
+    """
+    return fdt_util.EnsureCompiled(os.path.join(our_path, dts_fname))
+
+
+class TestDtoc(unittest.TestCase):
+    """Tests for dtoc"""
+    @classmethod
+    def setUpClass(cls):
+        tools.PrepareOutputDir(None)
+
+    @classmethod
+    def tearDownClass(cls):
+        tools._RemoveOutputDir()
+
+    def test_name(self):
+        """Test conversion of device tree names to C identifiers"""
+        self.assertEqual('serial_at_0x12', conv_name_to_c('serial at 0x12'))
+        self.assertEqual('vendor_clock_frequency',
+                         conv_name_to_c('vendor,clock-frequency'))
+        self.assertEqual('rockchip_rk3399_sdhci_5_1',
+                         conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
+
+    def test_tab_to(self):
+        """Test operation of tab_to() function"""
+        self.assertEqual('fred ', tab_to(0, 'fred'))
+        self.assertEqual('fred\t', tab_to(1, 'fred'))
+        self.assertEqual('fred was here ', tab_to(1, 'fred was here'))
+        self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here'))
+        self.assertEqual('exactly8 ', tab_to(1, 'exactly8'))
+        self.assertEqual('exactly8\t', tab_to(2, 'exactly8'))
+
+    def test_get_value(self):
+        """Test operation of get_value() function"""
+        self.assertEqual('0x45',
+                         get_value(fdt.TYPE_INT, struct.pack('>I', 0x45)))
+        self.assertEqual('0x45',
+                         get_value(fdt.TYPE_BYTE, struct.pack('<I', 0x45)))
+        self.assertEqual('0x0',
+                         get_value(fdt.TYPE_BYTE, struct.pack('>I', 0x45)))
+        self.assertEqual('"test"', get_value(fdt.TYPE_STRING, 'test'))
+        self.assertEqual('true', get_value(fdt.TYPE_BOOL, None))
+
+    def test_get_compat_name(self):
+        """Test operation of get_compat_name() function"""
+        Prop = collections.namedtuple('Prop', ['value'])
+        Node = collections.namedtuple('Node', ['props'])
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1', ['arasan_sdhci_5_1']),
+                         get_compat_name(node))
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1', []),
+                         get_compat_name(node))
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1',
+                          ['arasan_sdhci_5_1', 'third']),
+                         get_compat_name(node))
+
+    def test_empty_file(self):
+        """Test output from a device tree file with no nodes"""
+        dtb_file = get_dtb_file('dtoc_test_empty.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            lines = infile.read().splitlines()
+        self.assertEqual(['#include <stdbool.h>', '#include <libfdt.h>'], lines)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            lines = infile.read().splitlines()
+        self.assertEqual(['#include <common.h>', '#include <dm.h>',
+                          '#include <dt-structs.h>', ''], lines)
+
+    def test_simple(self):
+        """Test output from some simple nodes with various types of data"""
+        dtb_file = get_dtb_file('dtoc_test_simple.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_sandbox_spl_test {
+\tbool\t\tboolval;
+\tunsigned char\tbytearray[3];
+\tunsigned char\tbyteval;
+\tfdt32_t\t\tintarray[4];
+\tfdt32_t\t\tintval;
+\tunsigned char\tlongbytearray[9];
+\tconst char *\tstringarray[3];
+\tconst char *\tstringval;
+};
+struct dtd_sandbox_spl_test_2 {
+};
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_sandbox_spl_test dtv_spl_test = {
+\t.bytearray\t\t= {0x6, 0x0, 0x0},
+\t.byteval\t\t= 0x5,
+\t.intval\t\t\t= 0x1,
+\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11},
+\t.stringval\t\t= "message",
+\t.boolval\t\t= true,
+\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
+\t.stringarray\t\t= {"multi-word", "message", ""},
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
+\t.bytearray\t\t= {0x1, 0x23, 0x34},
+\t.byteval\t\t= 0x8,
+\t.intval\t\t\t= 0x3,
+\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+\t.stringval\t\t= "message2",
+\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
+\t.stringarray\t\t= {"another", "multi-word", "message"},
+};
+U_BOOT_DEVICE(spl_test2) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test2,
+\t.platdata_size\t= sizeof(dtv_spl_test2),
+};
+
+static struct dtd_sandbox_spl_test dtv_spl_test3 = {
+\t.stringarray\t\t= {"one", "", ""},
+};
+U_BOOT_DEVICE(spl_test3) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test3,
+\t.platdata_size\t= sizeof(dtv_spl_test3),
+};
+
+static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
+};
+U_BOOT_DEVICE(spl_test4) = {
+\t.name\t\t= "sandbox_spl_test_2",
+\t.platdata\t= &dtv_spl_test4,
+\t.platdata_size\t= sizeof(dtv_spl_test4),
+};
+
+''', data)
+
+    def test_phandle(self):
+        """Test output from a node containing a phandle reference"""
+        dtb_file = get_dtb_file('dtoc_test_phandle.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_source {
+\tstruct phandle_2_cell clocks[1];
+};
+struct dtd_target {
+\tfdt32_t\t\tintval;
+};
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+static struct dtd_source dtv_phandle_source = {
+\t.clocks\t\t\t= {{&dtv_phandle_target, 1}},
+};
+U_BOOT_DEVICE(phandle_source) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source,
+\t.platdata_size\t= sizeof(dtv_phandle_source),
+};
+
+''', data)
+
+    def test_aliases(self):
+        """Test output from a node with multiple compatible strings"""
+        dtb_file = get_dtb_file('dtoc_test_aliases.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_compat1 {
+\tfdt32_t\t\tintval;
+};
+#define dtd_compat2_1_fred dtd_compat1
+#define dtd_compat3 dtd_compat1
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_compat1 dtv_spl_test = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "compat1",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+''', data)
-- 
2.13.1.518.g3df882009-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 11/11] dtoc: Add tests
  2017-06-19  4:09 ` [U-Boot] [PATCH 11/11] dtoc: Add tests Simon Glass
@ 2017-07-06 14:48   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:48 UTC (permalink / raw)
  To: u-boot

Add some tests of dtoc's functionality to make it easier to expand and
enhance the tool.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py               |  31 ++++-
 tools/dtoc/dtoc_test.dts         |  12 ++
 tools/dtoc/dtoc_test_aliases.dts |  18 +++
 tools/dtoc/dtoc_test_empty.dts   |  12 ++
 tools/dtoc/dtoc_test_phandle.dts |  23 ++++
 tools/dtoc/dtoc_test_simple.dts  |  48 +++++++
 tools/dtoc/test_dtoc.py          | 271 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 411 insertions(+), 4 deletions(-)
 create mode 100644 tools/dtoc/dtoc_test.dts
 create mode 100644 tools/dtoc/dtoc_test_aliases.dts
 create mode 100644 tools/dtoc/dtoc_test_empty.dts
 create mode 100644 tools/dtoc/dtoc_test_phandle.dts
 create mode 100644 tools/dtoc/dtoc_test_simple.dts
 create mode 100644 tools/dtoc/test_dtoc.py

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL
  2017-06-19  4:09 ` [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL Simon Glass
@ 2017-07-06 14:48   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:48 UTC (permalink / raw)
  To: u-boot

Currently we have code which prints out platform data at the start of SPL.
Now that we have tests for dtoc this is probably not necessary. Drop it.
Update test_ofplatdata to check for empty output since it is useful to
check that sandbox_spl works as expected.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 11 -----------
 test/py/tests/test_ofplatdata.py | 30 +-----------------------------
 2 files changed, 1 insertion(+), 40 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c()
  2017-06-19  4:09 ` [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c() Simon Glass
@ 2017-07-06 14:48   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:48 UTC (permalink / raw)
  To: u-boot

This function uses several separate string replaces where a regular
expression might seem more reasonable. Add a comment justifying the way it
is currently done.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 3 +++
 1 file changed, 3 insertions(+)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file
  2017-06-19  4:09 ` [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file Simon Glass
@ 2017-07-06 14:49   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:49 UTC (permalink / raw)
  To: u-boot

Collect the main logic of dtoc into a function and put it into
dtb_platdata. This will allow tests to use this function instead of
duplicating the code themselves.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 29 +++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py         | 19 ++-----------------
 2 files changed, 31 insertions(+), 17 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class
  2017-06-19  4:09 ` [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class Simon Glass
@ 2017-07-06 14:49   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:49 UTC (permalink / raw)
  To: u-boot

Rather than using static functions within the class, move them out of the
class. This will make it slightly easier for tests to call them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 125 +++++++++++++++++++++++----------------------
 1 file changed, 63 insertions(+), 62 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly
  2017-06-19  4:09 ` [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly Simon Glass
@ 2017-07-06 14:49   ` sjg at google.com
  2017-07-06 14:51     ` sjg at google.com
  0 siblings, 1 reply; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:49 UTC (permalink / raw)
  To: u-boot

This option is the only one actually used by the dtb_platdata class. Pass
it explicitly to avoid needing to pass the whole option object to the
constructor.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 8 ++++----
 tools/dtoc/dtoc.py         | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 11/11] dtoc: Add tests
  2017-07-06 14:48   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Add some tests of dtoc's functionality to make it easier to expand and
enhance the tool.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py               |  31 ++++-
 tools/dtoc/dtoc_test.dts         |  12 ++
 tools/dtoc/dtoc_test_aliases.dts |  18 +++
 tools/dtoc/dtoc_test_empty.dts   |  12 ++
 tools/dtoc/dtoc_test_phandle.dts |  23 ++++
 tools/dtoc/dtoc_test_simple.dts  |  48 +++++++
 tools/dtoc/test_dtoc.py          | 271 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 411 insertions(+), 4 deletions(-)
 create mode 100644 tools/dtoc/dtoc_test.dts
 create mode 100644 tools/dtoc/dtoc_test_aliases.dts
 create mode 100644 tools/dtoc/dtoc_test_empty.dts
 create mode 100644 tools/dtoc/dtoc_test_phandle.dts
 create mode 100644 tools/dtoc/dtoc_test_simple.dts
 create mode 100644 tools/dtoc/test_dtoc.py

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL
  2017-07-06 14:48   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Currently we have code which prints out platform data at the start of SPL.
Now that we have tests for dtoc this is probably not necessary. Drop it.
Update test_ofplatdata to check for empty output since it is useful to
check that sandbox_spl works as expected.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 11 -----------
 test/py/tests/test_ofplatdata.py | 30 +-----------------------------
 2 files changed, 1 insertion(+), 40 deletions(-)

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c()
  2017-07-06 14:48   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

This function uses several separate string replaces where a regular
expression might seem more reasonable. Add a comment justifying the way it
is currently done.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 3 +++
 1 file changed, 3 insertions(+)

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file
  2017-07-06 14:49   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Collect the main logic of dtoc into a function and put it into
dtb_platdata. This will allow tests to use this function instead of
duplicating the code themselves.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 29 +++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py         | 19 ++-----------------
 2 files changed, 31 insertions(+), 17 deletions(-)

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class
  2017-07-06 14:49   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Rather than using static functions within the class, move them out of the
class. This will make it slightly easier for tests to call them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 125 +++++++++++++++++++++++----------------------
 1 file changed, 63 insertions(+), 62 deletions(-)

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly
  2017-07-06 14:49   ` sjg at google.com
@ 2017-07-06 14:51     ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

This option is the only one actually used by the dtb_platdata class. Pass
it explicitly to avoid needing to pass the whole option object to the
constructor.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 8 ++++----
 tools/dtoc/dtoc.py         | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

Applied to u-boot-dm, thanks!
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them
  2017-06-19  4:09 ` [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them Simon Glass
@ 2017-07-06 14:51   ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

This conversion appears to not be needed as it does not occur in practice.
Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 1 -
 1 file changed, 1 deletion(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file
  2017-06-19  4:08 ` [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file Simon Glass
@ 2017-07-06 14:51   ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

To simplify running tests we should move this class into its own file.
This allows the tests to import it without having to import dtoc.py, which
runs the tests.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 411 +++++++++++++++++++++++++++++++++++++++++++++
 tools/dtoc/dtoc.py         | 408 +-------------------------------------------
 2 files changed, 414 insertions(+), 405 deletions(-)
 create mode 100644 tools/dtoc/dtb_platdata.py

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings
  2017-06-19  4:08 ` [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings Simon Glass
@ 2017-07-06 14:51   ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Unfortunately I neglected to run pylint on this tool with its initial
submission. Fix the warnings.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 261 ++++++++++++++++++++++++---------------------
 tools/dtoc/dtoc.py         |  14 +--
 2 files changed, 144 insertions(+), 131 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top
  2017-06-19  4:08 ` [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top Simon Glass
@ 2017-07-06 14:51   ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

Add a description of the dtoc tool at the top of the file.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options
  2017-06-19  4:08 ` [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options Simon Glass
@ 2017-07-06 14:51   ` sjg at google.com
  0 siblings, 0 replies; 29+ messages in thread
From: sjg at google.com @ 2017-07-06 14:51 UTC (permalink / raw)
  To: u-boot

This class should use the options object passed to it rather than finding
the global one. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtoc.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2017-07-06 14:51 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-19  4:08 [U-Boot] [PATCH 00/11] dtoc: Tidy up and add tests Simon Glass
2017-06-19  4:08 ` [U-Boot] [PATCH 01/11] dtoc: Use self._options instead of the global options Simon Glass
2017-07-06 14:51   ` sjg at google.com
2017-06-19  4:08 ` [U-Boot] [PATCH 02/11] dtoc: Add a comment at the top Simon Glass
2017-07-06 14:51   ` sjg at google.com
2017-06-19  4:08 ` [U-Boot] [PATCH 03/11] dtoc: Split out the main class into its own file Simon Glass
2017-07-06 14:51   ` sjg at google.com
2017-06-19  4:08 ` [U-Boot] [PATCH 04/11] dtoc: Fix pylint warnings Simon Glass
2017-07-06 14:51   ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 05/11] dtoc: Don't handle properties with / in them Simon Glass
2017-07-06 14:51   ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 06/11] dtoc: Pass include_disabled explicitly Simon Glass
2017-07-06 14:49   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 07/11] dtoc: Move static functions out of the class Simon Glass
2017-07-06 14:49   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 08/11] dtoc: Move the main logic into the dtb_platdata file Simon Glass
2017-07-06 14:49   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 09/11] dtoc: Add a comment about string replace in conv_name_to_c() Simon Glass
2017-07-06 14:48   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 10/11] sandbox: Stop printing platdata at the start of SPL Simon Glass
2017-07-06 14:48   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com
2017-06-19  4:09 ` [U-Boot] [PATCH 11/11] dtoc: Add tests Simon Glass
2017-07-06 14:48   ` sjg at google.com
2017-07-06 14:51     ` sjg at google.com

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.