> On 20 Jun 2017, at 05:34, Simon Glass <s...@chromium.org> wrote: > > When using 32-bit addresses dtoc works correctly. For 64-bit addresses it > does not since it ignores the #address-cells and #size-cells properties. > > Update the tool to use fdt64_t as the element type for reg properties when > either the address or size is larger than one cell. Use the correct value > so that C code can obtain the information from the device tree easily.
This breaks ‘regmap_init_mem_platdata’, which assumes that it processes 32bit words (i.e. both addr and size are 32bit). Or did I just miss another changeset? > Add tests for the four combinations of address and size values (32/32, > 64/64, 32/64, 64/32). > > Signed-off-by: Simon Glass <s...@chromium.org> > Suggested-by: Heiko Stuebner <he...@sntech.de> > Reported-by: Kever Yang <kever.y...@rock-chips.com> > --- > > tools/dtoc/dtb_platdata.py | 59 +++++++++++ > tools/dtoc/dtoc_test_addr32.dts | 27 +++++ > tools/dtoc/dtoc_test_addr32_64.dts | 33 ++++++ > tools/dtoc/dtoc_test_addr64.dts | 33 ++++++ > tools/dtoc/dtoc_test_addr64_32.dts | 33 ++++++ > tools/dtoc/test_dtoc.py | 212 +++++++++++++++++++++++++++++++++++++ > 6 files changed, 397 insertions(+) > create mode 100644 tools/dtoc/dtoc_test_addr32.dts > create mode 100644 tools/dtoc/dtoc_test_addr32_64.dts > create mode 100644 tools/dtoc/dtoc_test_addr64.dts > create mode 100644 tools/dtoc/dtoc_test_addr64_32.dts > > diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py > index f5841cbb88..3de1a20dbd 100644 > --- a/tools/dtoc/dtb_platdata.py > +++ b/tools/dtoc/dtb_platdata.py > @@ -242,6 +242,64 @@ class DtbPlatdata(object): > self._valid_nodes = [] > return self.scan_node(self._fdt.GetRoot()) > > + @staticmethod > + def get_num_cells(node): > + """Get the number of cells in addresses and sizes for this node > + > + Args: > + node: Node to check > + > + Returns: > + Tuple: > + Number of address cells for this node > + Number of size cells for this node > + """ > + parent = node.parent > + na, ns = 2, 2 > + if parent: > + na_prop = parent.props.get('#address-cells') > + ns_prop = parent.props.get('#size-cells') > + if na_prop: > + na = fdt_util.fdt32_to_cpu(na_prop.value) > + if ns_prop: > + ns = fdt_util.fdt32_to_cpu(ns_prop.value) > + return na, ns > + > + def scan_reg_sizes(self): > + """Scan for 64-bit 'reg' properties and update the values > + > + This finds 'reg' properties with 64-bit data and converts the value > to > + an array of 64-values. This allows it to be output in a way that the > + C code can read. > + """ > + for node in self._valid_nodes: > + reg = node.props.get('reg') > + if not reg: > + continue > + na, ns = self.get_num_cells(node) > + total = na + ns > + > + if reg.type != fdt.TYPE_INT: > + raise ValueError("Node '%s' reg property is not an int") > + if len(reg.value) % total: > + raise ValueError("Node '%s' reg property has %d cells " > + 'which is not a multiple of na + ns = %d + %d)' % > + (node.name, len(reg.value), na, ns)) > + reg.na = na > + reg.ns = ns > + if na != 1 or ns != 1: > + reg.type = fdt.TYPE_INT64 > + i = 0 > + new_value = [] > + val = reg.value > + while i < len(val): > + addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.na) > + i += na > + size = fdt_util.fdt_cells_to_cpu(val[i:], reg.ns) > + i += ns > + new_value += [addr, size] > + reg.value = new_value > + > def scan_structs(self): > """Scan the device tree building up the C structures we will use. > > @@ -445,6 +503,7 @@ def run_steps(args, dtb_file, include_disabled, output): > plat = DtbPlatdata(dtb_file, include_disabled) > plat.scan_dtb() > plat.scan_tree() > + plat.scan_reg_sizes() > plat.setup_output(output) > structs = plat.scan_structs() > plat.scan_phandles() > diff --git a/tools/dtoc/dtoc_test_addr32.dts b/tools/dtoc/dtoc_test_addr32.dts > new file mode 100644 > index 0000000000..bcfdcae10b > --- /dev/null > +++ b/tools/dtoc/dtoc_test_addr32.dts > @@ -0,0 +1,27 @@ > +/* > + * Test device tree file for dtoc > + * > + * Copyright 2017 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > + /dts-v1/; > + > +/ { > + #address-cells = <1>; > + #size-cells = <1>; > + > + test1 { > + u-boot,dm-pre-reloc; > + compatible = "test1"; > + reg = <0x1234 0x5678>; > + }; > + > + test2 { > + u-boot,dm-pre-reloc; > + compatible = "test2"; > + reg = <0x12345678 0x98765432 2 3>; > + }; > + > +}; > diff --git a/tools/dtoc/dtoc_test_addr32_64.dts > b/tools/dtoc/dtoc_test_addr32_64.dts > new file mode 100644 > index 0000000000..1c96243310 > --- /dev/null > +++ b/tools/dtoc/dtoc_test_addr32_64.dts > @@ -0,0 +1,33 @@ > +/* > + * Test device tree file for dtoc > + * > + * Copyright 2017 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > + /dts-v1/; > + > +/ { > + #address-cells = <1>; > + #size-cells = <2>; > + > + test1 { > + u-boot,dm-pre-reloc; > + compatible = "test1"; > + reg = <0x1234 0x5678 0x0>; > + }; > + > + test2 { > + u-boot,dm-pre-reloc; > + compatible = "test2"; > + reg = <0x12345678 0x98765432 0x10987654>; > + }; > + > + test3 { > + u-boot,dm-pre-reloc; > + compatible = "test3"; > + reg = <0x12345678 0x98765432 0x10987654 2 0 3>; > + }; > + > +}; > diff --git a/tools/dtoc/dtoc_test_addr64.dts b/tools/dtoc/dtoc_test_addr64.dts > new file mode 100644 > index 0000000000..4c0ad0ec36 > --- /dev/null > +++ b/tools/dtoc/dtoc_test_addr64.dts > @@ -0,0 +1,33 @@ > +/* > + * Test device tree file for dtoc > + * > + * Copyright 2017 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > + /dts-v1/; > + > +/ { > + #address-cells = <2>; > + #size-cells = <2>; > + > + test1 { > + u-boot,dm-pre-reloc; > + compatible = "test1"; > + reg = /bits/ 64 <0x1234 0x5678>; > + }; > + > + test2 { > + u-boot,dm-pre-reloc; > + compatible = "test2"; > + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654>; > + }; > + > + test3 { > + u-boot,dm-pre-reloc; > + compatible = "test3"; > + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654 2 3>; > + }; > + > +}; > diff --git a/tools/dtoc/dtoc_test_addr64_32.dts > b/tools/dtoc/dtoc_test_addr64_32.dts > new file mode 100644 > index 0000000000..c36f6b726e > --- /dev/null > +++ b/tools/dtoc/dtoc_test_addr64_32.dts > @@ -0,0 +1,33 @@ > +/* > + * Test device tree file for dtoc > + * > + * Copyright 2017 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > + /dts-v1/; > + > +/ { > + #address-cells = <2>; > + #size-cells = <1>; > + > + test1 { > + u-boot,dm-pre-reloc; > + compatible = "test1"; > + reg = <0x1234 0x0 0x5678>; > + }; > + > + test2 { > + u-boot,dm-pre-reloc; > + compatible = "test2"; > + reg = <0x12345678 0x90123456 0x98765432>; > + }; > + > + test3 { > + u-boot,dm-pre-reloc; > + compatible = "test3"; > + reg = <0x12345678 0x90123456 0x98765432 0 2 3>; > + }; > + > +}; > diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py > index 35aa4c9817..d91ff88c85 100644 > --- a/tools/dtoc/test_dtoc.py > +++ b/tools/dtoc/test_dtoc.py > @@ -268,4 +268,216 @@ U_BOOT_DEVICE(spl_test) = { > \t.platdata_size\t= sizeof(dtv_spl_test), > }; > > +''', data) > + > + def test_addresses64(self): > + """Test output from a node with a 'reg' property with na=2, ns=2""" > + dtb_file = get_dtb_file('dtoc_test_addr64.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_test1 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test2 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test3 { > +\tfdt64_t\t\treg[4]; > +}; > +''', 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_test1 dtv_test1 = { > +\t.reg\t\t\t= {0x1234, 0x5678}, > +}; > +U_BOOT_DEVICE(test1) = { > +\t.name\t\t= "test1", > +\t.platdata\t= &dtv_test1, > +\t.platdata_size\t= sizeof(dtv_test1), > +}; > + > +static struct dtd_test2 dtv_test2 = { > +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654}, > +}; > +U_BOOT_DEVICE(test2) = { > +\t.name\t\t= "test2", > +\t.platdata\t= &dtv_test2, > +\t.platdata_size\t= sizeof(dtv_test2), > +}; > + > +static struct dtd_test3 dtv_test3 = { > +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3}, > +}; > +U_BOOT_DEVICE(test3) = { > +\t.name\t\t= "test3", > +\t.platdata\t= &dtv_test3, > +\t.platdata_size\t= sizeof(dtv_test3), > +}; > + > +''', data) > + > + def test_addresses32(self): > + """Test output from a node with a 'reg' property with na=1, ns=1""" > + dtb_file = get_dtb_file('dtoc_test_addr32.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_test1 { > +\tfdt32_t\t\treg[2]; > +}; > +struct dtd_test2 { > +\tfdt32_t\t\treg[4]; > +}; > +''', 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_test1 dtv_test1 = { > +\t.reg\t\t\t= {0x1234, 0x5678}, > +}; > +U_BOOT_DEVICE(test1) = { > +\t.name\t\t= "test1", > +\t.platdata\t= &dtv_test1, > +\t.platdata_size\t= sizeof(dtv_test1), > +}; > + > +static struct dtd_test2 dtv_test2 = { > +\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3}, > +}; > +U_BOOT_DEVICE(test2) = { > +\t.name\t\t= "test2", > +\t.platdata\t= &dtv_test2, > +\t.platdata_size\t= sizeof(dtv_test2), > +}; > + > +''', data) > + > + def test_addresses64_32(self): > + """Test output from a node with a 'reg' property with na=2, ns=1""" > + dtb_file = get_dtb_file('dtoc_test_addr64_32.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_test1 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test2 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test3 { > +\tfdt64_t\t\treg[4]; > +}; > +''', 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_test1 dtv_test1 = { > +\t.reg\t\t\t= {0x123400000000, 0x5678}, > +}; > +U_BOOT_DEVICE(test1) = { > +\t.name\t\t= "test1", > +\t.platdata\t= &dtv_test1, > +\t.platdata_size\t= sizeof(dtv_test1), > +}; > + > +static struct dtd_test2 dtv_test2 = { > +\t.reg\t\t\t= {0x1234567890123456, 0x98765432}, > +}; > +U_BOOT_DEVICE(test2) = { > +\t.name\t\t= "test2", > +\t.platdata\t= &dtv_test2, > +\t.platdata_size\t= sizeof(dtv_test2), > +}; > + > +static struct dtd_test3 dtv_test3 = { > +\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3}, > +}; > +U_BOOT_DEVICE(test3) = { > +\t.name\t\t= "test3", > +\t.platdata\t= &dtv_test3, > +\t.platdata_size\t= sizeof(dtv_test3), > +}; > + > +''', data) > + > + def test_addresses32_64(self): > + """Test output from a node with a 'reg' property with na=1, ns=2""" > + dtb_file = get_dtb_file('dtoc_test_addr32_64.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_test1 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test2 { > +\tfdt64_t\t\treg[2]; > +}; > +struct dtd_test3 { > +\tfdt64_t\t\treg[4]; > +}; > +''', 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_test1 dtv_test1 = { > +\t.reg\t\t\t= {0x1234, 0x567800000000}, > +}; > +U_BOOT_DEVICE(test1) = { > +\t.name\t\t= "test1", > +\t.platdata\t= &dtv_test1, > +\t.platdata_size\t= sizeof(dtv_test1), > +}; > + > +static struct dtd_test2 dtv_test2 = { > +\t.reg\t\t\t= {0x12345678, 0x9876543210987654}, > +}; > +U_BOOT_DEVICE(test2) = { > +\t.name\t\t= "test2", > +\t.platdata\t= &dtv_test2, > +\t.platdata_size\t= sizeof(dtv_test2), > +}; > + > +static struct dtd_test3 dtv_test3 = { > +\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3}, > +}; > +U_BOOT_DEVICE(test3) = { > +\t.name\t\t= "test3", > +\t.platdata\t= &dtv_test3, > +\t.platdata_size\t= sizeof(dtv_test3), > +}; > + > ''', data) > -- > 2.13.1.518.g3df882009-goog > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot