All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function
@ 2017-04-23  0:42 Simon Glass
  2017-04-23  0:42 ` [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same Simon Glass
  2017-04-24  2:13 ` [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Kever Yang
  0 siblings, 2 replies; 6+ messages in thread
From: Simon Glass @ 2017-04-23  0:42 UTC (permalink / raw)
  To: u-boot

The code to generate the tables is quite long. Move the node-output code
into its own function.

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

 tools/dtoc/dtoc.py | 96 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 52 insertions(+), 44 deletions(-)

diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index afc5171c2a..0a111eced6 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -301,6 +301,57 @@ class DtbPlatdata:
                 self.Out(';\n')
             self.Out('};\n')
 
+    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')
+
     def GenerateTables(self):
         """Generate device defintions for the platform data
 
@@ -314,50 +365,7 @@ class DtbPlatdata:
         self.Out('\n')
         node_txt_list = []
         for node in self._valid_nodes:
-            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.OutputNode(node)
 
             # Output phandle target nodes first, since they may be referenced
             # by others
-- 
2.12.2.816.g2cccc81164-goog

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

* [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same
  2017-04-23  0:42 [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Simon Glass
@ 2017-04-23  0:42 ` Simon Glass
  2017-04-24  2:14   ` Kever Yang
  2017-04-24  2:13 ` [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Kever Yang
  1 sibling, 1 reply; 6+ messages in thread
From: Simon Glass @ 2017-04-23  0:42 UTC (permalink / raw)
  To: u-boot

At present dtoc assumes that nodes which are phandles do not themselves
reference other phandle nodes. Unfortunately this is not necessarilly
true. As a result we can currently output C code which does not compile
because a node declaration can be referenced before it is declared.

Adjust the code to explicitly output all phandle nodes needed by node
before the node itself is output.

This fixes building with the latest rk3399-firefly.dts from Linux, which
has reordered the nodes.

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

 tools/dtoc/dtoc.py | 55 ++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 0a111eced6..2e0b9c04e2 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -272,6 +272,33 @@ class DtbPlatdata:
             upto += 1
         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
 
@@ -352,6 +379,8 @@ class DtbPlatdata:
         self.Buf('};\n')
         self.Buf('\n')
 
+        self.Out(''.join(self.GetBuf()))
+
     def GenerateTables(self):
         """Generate device defintions for the platform data
 
@@ -363,21 +392,18 @@ class DtbPlatdata:
         self.Out('#include <dm.h>\n')
         self.Out('#include <dt-structs.h>\n')
         self.Out('\n')
-        node_txt_list = []
-        for node in self._valid_nodes:
+        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)
-
-            # Output phandle target nodes first, since they may be referenced
-            # by others
-            if 'phandle' in node.props:
-                self.Out(''.join(self.GetBuf()))
-            else:
-                node_txt_list.append(self.GetBuf())
-
-        # Output all the nodes which are not phandle targets themselves, but
-        # may reference them. This avoids the need for forward declarations.
-        for node_txt in node_txt_list:
-            self.Out(''.join(node_txt))
+            nodes_to_output.remove(node)
 
 
 if __name__ != "__main__":
@@ -400,6 +426,7 @@ plat.ScanDtb()
 plat.ScanTree()
 plat.SetupOutput(options.output)
 structs = plat.ScanStructs()
+plat.ScanPhandles()
 
 for cmd in args[0].split(','):
     if cmd == 'struct':
-- 
2.12.2.816.g2cccc81164-goog

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

* [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function
  2017-04-23  0:42 [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Simon Glass
  2017-04-23  0:42 ` [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same Simon Glass
@ 2017-04-24  2:13 ` Kever Yang
  2017-05-02 11:12   ` sjg at google.com
  1 sibling, 1 reply; 6+ messages in thread
From: Kever Yang @ 2017-04-24  2:13 UTC (permalink / raw)
  To: u-boot

Hi Simon,


On 04/23/2017 08:42 AM, Simon Glass wrote:
> The code to generate the tables is quite long. Move the node-output code
> into its own function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   tools/dtoc/dtoc.py | 96 +++++++++++++++++++++++++++++-------------------------
>   1 file changed, 52 insertions(+), 44 deletions(-)
>
> diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
> index afc5171c2a..0a111eced6 100755
> --- a/tools/dtoc/dtoc.py
> +++ b/tools/dtoc/dtoc.py
> @@ -301,6 +301,57 @@ class DtbPlatdata:
>                   self.Out(';\n')
>               self.Out('};\n')
>   
> +    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')
> +
>       def GenerateTables(self):
>           """Generate device defintions for the platform data
>   
> @@ -314,50 +365,7 @@ class DtbPlatdata:
>           self.Out('\n')
>           node_txt_list = []
>           for node in self._valid_nodes:
> -            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.OutputNode(node)
>   
>               # Output phandle target nodes first, since they may be referenced
>               # by others

Tested-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever

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

* [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same
  2017-04-23  0:42 ` [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same Simon Glass
@ 2017-04-24  2:14   ` Kever Yang
  2017-05-02 11:12     ` sjg at google.com
  0 siblings, 1 reply; 6+ messages in thread
From: Kever Yang @ 2017-04-24  2:14 UTC (permalink / raw)
  To: u-boot

Hi Simon,


On 04/23/2017 08:42 AM, Simon Glass wrote:
> At present dtoc assumes that nodes which are phandles do not themselves
> reference other phandle nodes. Unfortunately this is not necessarilly
> true. As a result we can currently output C code which does not compile
> because a node declaration can be referenced before it is declared.
>
> Adjust the code to explicitly output all phandle nodes needed by node
> before the node itself is output.
>
> This fixes building with the latest rk3399-firefly.dts from Linux, which
> has reordered the nodes.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   tools/dtoc/dtoc.py | 55 ++++++++++++++++++++++++++++++++++++++++--------------
>   1 file changed, 41 insertions(+), 14 deletions(-)
>
> diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
> index 0a111eced6..2e0b9c04e2 100755
> --- a/tools/dtoc/dtoc.py
> +++ b/tools/dtoc/dtoc.py
> @@ -272,6 +272,33 @@ class DtbPlatdata:
>               upto += 1
>           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
>   
> @@ -352,6 +379,8 @@ class DtbPlatdata:
>           self.Buf('};\n')
>           self.Buf('\n')
>   
> +        self.Out(''.join(self.GetBuf()))
> +
>       def GenerateTables(self):
>           """Generate device defintions for the platform data
>   
> @@ -363,21 +392,18 @@ class DtbPlatdata:
>           self.Out('#include <dm.h>\n')
>           self.Out('#include <dt-structs.h>\n')
>           self.Out('\n')
> -        node_txt_list = []
> -        for node in self._valid_nodes:
> +        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)
> -
> -            # Output phandle target nodes first, since they may be referenced
> -            # by others
> -            if 'phandle' in node.props:
> -                self.Out(''.join(self.GetBuf()))
> -            else:
> -                node_txt_list.append(self.GetBuf())
> -
> -        # Output all the nodes which are not phandle targets themselves, but
> -        # may reference them. This avoids the need for forward declarations.
> -        for node_txt in node_txt_list:
> -            self.Out(''.join(node_txt))
> +            nodes_to_output.remove(node)
>   
>   
>   if __name__ != "__main__":
> @@ -400,6 +426,7 @@ plat.ScanDtb()
>   plat.ScanTree()
>   plat.SetupOutput(options.output)
>   structs = plat.ScanStructs()
> +plat.ScanPhandles()
>   
>   for cmd in args[0].split(','):
>       if cmd == 'struct':

Tested-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever

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

* [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same
  2017-04-24  2:14   ` Kever Yang
@ 2017-05-02 11:12     ` sjg at google.com
  0 siblings, 0 replies; 6+ messages in thread
From: sjg at google.com @ 2017-05-02 11:12 UTC (permalink / raw)
  To: u-boot

Hi Simon,


On 04/23/2017 08:42 AM, Simon Glass wrote:
> At present dtoc assumes that nodes which are phandles do not themselves
> reference other phandle nodes. Unfortunately this is not necessarilly
> true. As a result we can currently output C code which does not compile
> because a node declaration can be referenced before it is declared.
>
> Adjust the code to explicitly output all phandle nodes needed by node
> before the node itself is output.
>
> This fixes building with the latest rk3399-firefly.dts from Linux, which
> has reordered the nodes.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   tools/dtoc/dtoc.py | 55 ++++++++++++++++++++++++++++++++++++++++--------------
>   1 file changed, 41 insertions(+), 14 deletions(-)
>
Applied to u-boot-rockchip/next, thanks!

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

* [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function
  2017-04-24  2:13 ` [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Kever Yang
@ 2017-05-02 11:12   ` sjg at google.com
  0 siblings, 0 replies; 6+ messages in thread
From: sjg at google.com @ 2017-05-02 11:12 UTC (permalink / raw)
  To: u-boot

Hi Simon,


On 04/23/2017 08:42 AM, Simon Glass wrote:
> The code to generate the tables is quite long. Move the node-output code
> into its own function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   tools/dtoc/dtoc.py | 96 +++++++++++++++++++++++++++++-------------------------
>   1 file changed, 52 insertions(+), 44 deletions(-)
>
Applied to u-boot-rockchip/next, thanks!

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

end of thread, other threads:[~2017-05-02 11:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-23  0:42 [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Simon Glass
2017-04-23  0:42 ` [U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same Simon Glass
2017-04-24  2:14   ` Kever Yang
2017-05-02 11:12     ` sjg at google.com
2017-04-24  2:13 ` [U-Boot] [PATCH 1/2] dtoc: Move the output code into its own function Kever Yang
2017-05-02 11:12   ` 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.