[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