[U-Boot] [PATCH 2/2] dtoc: Handle nodes with phandles that depend on the same

Kever Yang kever.yang at rock-chips.com
Mon Apr 24 02:14:15 UTC 2017


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 at 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 at rock-chips.com>

Thanks,
- Kever



More information about the U-Boot mailing list