All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses
@ 2017-06-20  3:34 Simon Glass
  2017-06-20  3:34 ` [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent Simon Glass
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Simon Glass @ 2017-06-20  3:34 UTC (permalink / raw)
  To: u-boot

This series updates dtoc to support 64-bit addresses automatically. These
appear in C code as fdt64_t arrays:

struct dtd_test1 {
	fdt64_t		reg[2];

};

static struct dtd_test1 dtv_test1 = {
	.reg		= {0x123400000000, 0x5678},
};

C code can then process these address and size parents easily. This
feature is controlled by the #address-cells and #size-cells values of the
parent.


Simon Glass (3):
  dtoc: Adjust Node to record its parent
  dtoc: Add a 64-bit type and a way to convert cells into 64 bits
  dtoc: Add support for 32 or 64-bit addresses

 tools/dtoc/dtb_platdata.py         |  62 +++++++++++
 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/fdt.py                  |  14 +--
 tools/dtoc/fdt_util.py             |  14 +++
 tools/dtoc/test_dtoc.py            | 212 +++++++++++++++++++++++++++++++++++++
 8 files changed, 422 insertions(+), 6 deletions(-)
 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

-- 
2.13.1.518.g3df882009-goog

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

* [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent
  2017-06-20  3:34 [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses Simon Glass
@ 2017-06-20  3:34 ` Simon Glass
  2017-08-14 17:13   ` [U-Boot] [U-Boot,1/3] " Philipp Tomsich
  2017-06-20  3:34 ` [U-Boot] [PATCH 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits Simon Glass
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2017-06-20  3:34 UTC (permalink / raw)
  To: u-boot

We need to be able to search back up the tree for #address-cells and
 #size-cells. Record the parent of each node to make this easier.

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

 tools/dtoc/fdt.py | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 63a32ea2d7..49409a62ec 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -174,8 +174,9 @@ class Node:
         props: A dict of properties for this node, each a Prop object.
             Keyed by property name
     """
-    def __init__(self, fdt, offset, name, path):
+    def __init__(self, fdt, parent, offset, name, path):
         self._fdt = fdt
+        self.parent = parent
         self._offset = offset
         self.name = name
         self.path = path
@@ -217,7 +218,7 @@ class Node:
             sep = '' if self.path[-1] == '/' else '/'
             name = self._fdt._fdt_obj.get_name(offset)
             path = self.path + sep + name
-            node = Node(self._fdt, offset, name, path)
+            node = Node(self._fdt, self, offset, name, path)
             self.subnodes.append(node)
 
             node.Scan()
@@ -279,7 +280,7 @@ class Fdt:
 
         TODO(sjg at chromium.org): Implement the 'root' parameter
         """
-        self._root = self.Node(self, 0, '/', '/')
+        self._root = self.Node(self, None, 0, '/', '/')
         self._root.Scan()
 
     def GetRoot(self):
@@ -386,7 +387,7 @@ class Fdt:
         return libfdt.fdt_off_dt_struct(self._fdt) + offset
 
     @classmethod
-    def Node(self, fdt, offset, name, path):
+    def Node(self, fdt, parent, offset, name, path):
         """Create a new node
 
         This is used by Fdt.Scan() to create a new node using the correct
@@ -394,11 +395,12 @@ class Fdt:
 
         Args:
             fdt: Fdt object
+            parent: Parent node, or None if this is the root node
             offset: Offset of node
             name: Node name
             path: Full path to node
         """
-        node = Node(fdt, offset, name, path)
+        node = Node(fdt, parent, offset, name, path)
         return node
 
 def FdtScan(fname):
-- 
2.13.1.518.g3df882009-goog

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

* [U-Boot] [PATCH 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits
  2017-06-20  3:34 [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses Simon Glass
  2017-06-20  3:34 ` [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent Simon Glass
@ 2017-06-20  3:34 ` Simon Glass
  2017-08-14 17:14   ` [U-Boot] [U-Boot, " Philipp Tomsich
  2017-06-20  3:34 ` [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses Simon Glass
  2017-08-14 14:36 ` [U-Boot] [PATCH 0/3] dtoc: Add support for " Dr. Philipp Tomsich
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2017-06-20  3:34 UTC (permalink / raw)
  To: u-boot

When dealing with multi-cell values we need a type that can hold this
value. Add this and a function to process it from a list of cell values.

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

 tools/dtoc/dtb_platdata.py |  3 +++
 tools/dtoc/fdt.py          |  2 +-
 tools/dtoc/fdt_util.py     | 14 ++++++++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 1f85343a9f..f5841cbb88 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -38,6 +38,7 @@ TYPE_NAMES = {
     fdt.TYPE_BYTE: 'unsigned char',
     fdt.TYPE_STRING: 'const char *',
     fdt.TYPE_BOOL: 'bool',
+    fdt.TYPE_INT64: 'fdt64_t',
 }
 
 STRUCT_PREFIX = 'dtd_'
@@ -95,6 +96,8 @@ def get_value(ftype, value):
         return '"%s"' % value
     elif ftype == fdt.TYPE_BOOL:
         return 'true'
+    elif ftype == fdt.TYPE_INT64:
+        return '%#x' % value
 
 def get_compat_name(node):
     """Get a node's first compatible string as a C identifier
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 49409a62ec..ffd42ce541 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -21,7 +21,7 @@ import libfdt
 # so it is fairly efficient.
 
 # A list of types we support
-(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
+(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5)
 
 def CheckErr(errnum, msg):
     if errnum:
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
index b9dfae8d0e..bec6ee947a 100644
--- a/tools/dtoc/fdt_util.py
+++ b/tools/dtoc/fdt_util.py
@@ -29,6 +29,20 @@ def fdt32_to_cpu(val):
         val = val.encode('raw_unicode_escape')
     return struct.unpack('>I', val)[0]
 
+def fdt_cells_to_cpu(val, cells):
+    """Convert one or two cells to a long integer
+
+    Args:
+        Value to convert (array of one or more 4-character strings)
+
+    Return:
+        A native-endian long value
+    """
+    out = long(fdt32_to_cpu(val[0]))
+    if cells == 2:
+        out = out << 32 | fdt32_to_cpu(val[1])
+    return out
+
 def EnsureCompiled(fname):
     """Compile an fdt .dts source file into a .dtb binary blob if needed.
 
-- 
2.13.1.518.g3df882009-goog

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

* [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses
  2017-06-20  3:34 [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses Simon Glass
  2017-06-20  3:34 ` [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent Simon Glass
  2017-06-20  3:34 ` [U-Boot] [PATCH 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits Simon Glass
@ 2017-06-20  3:34 ` Simon Glass
  2017-08-14 14:53   ` Dr. Philipp Tomsich
  2017-08-14 17:26   ` [U-Boot] [U-Boot, " Philipp Tomsich
  2017-08-14 14:36 ` [U-Boot] [PATCH 0/3] dtoc: Add support for " Dr. Philipp Tomsich
  3 siblings, 2 replies; 9+ messages in thread
From: Simon Glass @ 2017-06-20  3:34 UTC (permalink / raw)
  To: u-boot

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.

Add tests for the four combinations of address and size values (32/32,
64/64, 32/64, 64/32).

Signed-off-by: Simon Glass <sjg@chromium.org>
Suggested-by: Heiko Stuebner <heiko@sntech.de>
Reported-by: Kever Yang <kever.yang@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

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

* [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses
  2017-06-20  3:34 [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses Simon Glass
                   ` (2 preceding siblings ...)
  2017-06-20  3:34 ` [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses Simon Glass
@ 2017-08-14 14:36 ` Dr. Philipp Tomsich
  3 siblings, 0 replies; 9+ messages in thread
From: Dr. Philipp Tomsich @ 2017-08-14 14:36 UTC (permalink / raw)
  To: u-boot

Simon,

> On 20 Jun 2017, at 05:34, Simon Glass <sjg@chromium.org> wrote:
> 
> This series updates dtoc to support 64-bit addresses automatically. These
> appear in C code as fdt64_t arrays:
> 
> struct dtd_test1 {
> 	fdt64_t		reg[2];
> 
> };
> 
> static struct dtd_test1 dtv_test1 = {
> 	.reg		= {0x123400000000, 0x5678},
> };
> 
> C code can then process these address and size parents easily. This
> feature is controlled by the #address-cells and #size-cells values of the
> parent.
> 
> 
> Simon Glass (3):
>  dtoc: Adjust Node to record its parent
>  dtoc: Add a 64-bit type and a way to convert cells into 64 bits
>  dtoc: Add support for 32 or 64-bit addresses
> 
> tools/dtoc/dtb_platdata.py         |  62 +++++++++++
> 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/fdt.py                  |  14 +--
> tools/dtoc/fdt_util.py             |  14 +++
> tools/dtoc/test_dtoc.py            | 212 +++++++++++++++++++++++++++++++++++++
> 8 files changed, 422 insertions(+), 6 deletions(-)
> 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
> 
> — 

While testing this for the TPL stage of the RK3368, I triggered an error:
> Traceback (most recent call last):
>   File "./tools/dtoc/dtoc", line 76, in <module>
>     options.output)
>   File "/hgst-3tb/home/ptomsich/rk3399-spl/u-boot/tools/dtoc/dtb_platdata.py", line 510, in run_steps
>     plat.scan_reg_sizes()
>   File "/hgst-3tb/home/ptomsich/rk3399-spl/u-boot/tools/dtoc/dtb_platdata.py", line 297, in scan_reg_sizes
>     addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.na)
>   File "/hgst-3tb/home/ptomsich/rk3399-spl/u-boot/tools/dtoc/fdt_util.py", line 41, in fdt_cells_to_cpu
>     out = long(fdt32_to_cpu(val[0]))
>   File "/hgst-3tb/home/ptomsich/rk3399-spl/u-boot/tools/dtoc/fdt_util.py", line 30, in fdt32_to_cpu
>     return struct.unpack('>I', val)[0]
> struct.error: unpack requires a string argument of length 4
with the following DTS snippet:
> 	spi at ff120000 {
> 		compatible = "rockchip,rk3368-spi", "rockchip,rk3066-spi";
> 		reg = <0x0 0xff120000 0x0 0x1000>;
> 		clocks = <0xb 0x42 0xb 0x153>;
> 		clock-names = "spiclk", "apb_pclk";
> 		interrupts = <0x0 0x2d 0x4>;
> 		#address-cells = <0x1>;
> 		#size-cells = <0x0>;
> 		status = "okay";
> 		u-boot,dm-pre-reloc;
> 
> 		w25q32dw at 0 {
> 			u-boot,dm-pre-reloc;
> 			compatible = "spi-flash";
> 			reg = <0x0>;
> 			spi-max-frequency = <0x2f34f60>;
> 			spi-cpol;
> 			spi-cpha;
> 		};
> 	};

A bit of debug code shows that the error occurs during the processing of the 'w25q32dw at 0’ node.

Note that this is not a showstopper for the RK3368, as OF_PLATDATA is only used for TPL, which
performs a return-to-bootrom anyway (and I will be making this more explicit by using the 'dm-spl’
and ‘dm-tpl’ decorators).

Regards,
Phil.

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

* [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses
  2017-06-20  3:34 ` [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses Simon Glass
@ 2017-08-14 14:53   ` Dr. Philipp Tomsich
  2017-08-14 17:26   ` [U-Boot] [U-Boot, " Philipp Tomsich
  1 sibling, 0 replies; 9+ messages in thread
From: Dr. Philipp Tomsich @ 2017-08-14 14:53 UTC (permalink / raw)
  To: u-boot


> On 20 Jun 2017, at 05:34, Simon Glass <sjg@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 <sjg@chromium.org>
> Suggested-by: Heiko Stuebner <heiko@sntech.de>
> Reported-by: Kever Yang <kever.yang@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
> 

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

* [U-Boot] [U-Boot,1/3] dtoc: Adjust Node to record its parent
  2017-06-20  3:34 ` [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent Simon Glass
@ 2017-08-14 17:13   ` Philipp Tomsich
  0 siblings, 0 replies; 9+ messages in thread
From: Philipp Tomsich @ 2017-08-14 17:13 UTC (permalink / raw)
  To: u-boot



On Mon, 19 Jun 2017, Simon Glass wrote:

> We need to be able to search back up the tree for #address-cells and
> #size-cells. Record the parent of each node to make this easier.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---

Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tested-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>

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

* [U-Boot] [U-Boot, 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits
  2017-06-20  3:34 ` [U-Boot] [PATCH 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits Simon Glass
@ 2017-08-14 17:14   ` Philipp Tomsich
  0 siblings, 0 replies; 9+ messages in thread
From: Philipp Tomsich @ 2017-08-14 17:14 UTC (permalink / raw)
  To: u-boot



On Mon, 19 Jun 2017, Simon Glass wrote:

> When dealing with multi-cell values we need a type that can hold this
> value. Add this and a function to process it from a list of cell values.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---

Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tested-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>

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

* [U-Boot] [U-Boot, 3/3] dtoc: Add support for 32 or 64-bit addresses
  2017-06-20  3:34 ` [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses Simon Glass
  2017-08-14 14:53   ` Dr. Philipp Tomsich
@ 2017-08-14 17:26   ` Philipp Tomsich
  1 sibling, 0 replies; 9+ messages in thread
From: Philipp Tomsich @ 2017-08-14 17:26 UTC (permalink / raw)
  To: u-boot

On Mon, 19 Jun 2017, Simon Glass 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.
>
> Add tests for the four combinations of address and size values (32/32,
> 64/64, 32/64, 64/32).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Suggested-by: Heiko Stuebner <heiko@sntech.de>
> Reported-by: Kever Yang <kever.yang@rock-chips.com>

Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tested-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>

See below for comments.

> ---
>
> 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

If there's just a single element in the reg expression (e.g. reg = <1>), 
as will be the case for I2C or SPI devices, the type of reg.na will be
str instead of list... thus causing a failures in fdt_cells_to_cpu.

> +                    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)
>

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

end of thread, other threads:[~2017-08-14 17:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-20  3:34 [U-Boot] [PATCH 0/3] dtoc: Add support for 64-bit addresses Simon Glass
2017-06-20  3:34 ` [U-Boot] [PATCH 1/3] dtoc: Adjust Node to record its parent Simon Glass
2017-08-14 17:13   ` [U-Boot] [U-Boot,1/3] " Philipp Tomsich
2017-06-20  3:34 ` [U-Boot] [PATCH 2/3] dtoc: Add a 64-bit type and a way to convert cells into 64 bits Simon Glass
2017-08-14 17:14   ` [U-Boot] [U-Boot, " Philipp Tomsich
2017-06-20  3:34 ` [U-Boot] [PATCH 3/3] dtoc: Add support for 32 or 64-bit addresses Simon Glass
2017-08-14 14:53   ` Dr. Philipp Tomsich
2017-08-14 17:26   ` [U-Boot] [U-Boot, " Philipp Tomsich
2017-08-14 14:36 ` [U-Boot] [PATCH 0/3] dtoc: Add support for " Dr. Philipp Tomsich

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.