dtoc: Improve handling of reg properties
authorSimon Glass <sjg@chromium.org>
Fri, 26 Mar 2021 03:17:27 +0000 (16:17 +1300)
committerSimon Glass <sjg@chromium.org>
Tue, 6 Apr 2021 04:33:19 +0000 (16:33 +1200)
This existing code assumes that a reg property is larger than one cell,
but this is not always the case. Fix this assumption.

Also if a node's parent is missing the #address-cells and #size-cells
properties we use 2 as a default for each. But this should not happen in
practice. More likely the properties were removed for SPL due to there
being no 'u-boot,dm-pre-reloc' property, or similar. Add a warning for
this as the failure can be very confusing.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/dtoc/dtb_platdata.py
tools/dtoc/test/dtoc_test_noprops.dts [new file with mode: 0644]
tools/dtoc/test/dtoc_test_single_reg.dts [new file with mode: 0644]
tools/dtoc/test_dtoc.py

index b989b4f..1374f01 100644 (file)
@@ -440,6 +440,9 @@ class DtbPlatdata():
                 Number of size cells for this node
         """
         parent = node.parent
+        if parent and not parent.props:
+            raise ValueError("Parent node '%s' has no properties - do you need u-boot,dm-spl or similar?" %
+                             parent.path)
         num_addr, num_size = 2, 2
         if parent:
             addr_prop = parent.props.get('#address-cells')
@@ -471,9 +474,10 @@ class DtbPlatdata():
                 reg.value = [reg.value]
             if len(reg.value) % total:
                 raise ValueError(
-                    "Node '%s' reg property has %d cells "
+                    "Node '%s' (parent '%s') reg property has %d cells "
                     'which is not a multiple of na + ns = %d + %d)' %
-                    (node.name, len(reg.value), num_addr, num_size))
+                    (node.name, node.parent.name, len(reg.value), num_addr,
+                     num_size))
             reg.num_addr = num_addr
             reg.num_size = num_size
             if num_addr > 1 or num_size > 1:
diff --git a/tools/dtoc/test/dtoc_test_noprops.dts b/tools/dtoc/test/dtoc_test_noprops.dts
new file mode 100644 (file)
index 0000000..e6fdd11
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       i2c@0 {
+               pmic@9 {
+                       compatible = "sandbox,pmic";
+                       u-boot,dm-pre-reloc;
+                       reg = <9>;
+                       low-power;
+               };
+       };
+};
diff --git a/tools/dtoc/test/dtoc_test_single_reg.dts b/tools/dtoc/test/dtoc_test_single_reg.dts
new file mode 100644 (file)
index 0000000..804b678
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       i2c@0 {
+               compatible = "sandbox,i2c";
+               u-boot,dm-pre-reloc;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pmic@9 {
+                       compatible = "sandbox,pmic";
+                       u-boot,dm-pre-reloc;
+                       reg = <9>;
+                       low-power;
+
+                       gpio {
+                               compatible = "sandbox,gpio";
+                       };
+               };
+       };
+};
index cff5225..a05e3d9 100755 (executable)
@@ -1462,7 +1462,7 @@ U_BOOT_DRVINFO(test3) = {
         with self.assertRaises(ValueError) as exc:
             self.run_test(['struct'], dtb_file, output)
         self.assertIn(
-            "Node 'spl-test' reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
+            "Node 'spl-test' (parent '/') reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
             str(exc.exception))
 
     def test_add_prop(self):
@@ -1824,3 +1824,18 @@ U_BOOT_DRVINFO(spl_test2) = {
         self.assertEqual(
             'Warning: Cannot find header file for struct dm_test_uc_priv',
             stdout.getvalue().strip())
+
+    def test_missing_props(self):
+        """Test detection of a parent node with no properties"""
+        dtb_file = get_dtb_file('dtoc_test_noprops.dts', capture_stderr=True)
+        output = tools.GetOutputFilename('output')
+        with self.assertRaises(ValueError) as exc:
+            self.run_test(['struct'], dtb_file, output)
+        self.assertIn("Parent node '/i2c@0' has no properties - do you need",
+                      str(exc.exception))
+
+    def test_single_reg(self):
+        """Test detection of a parent node with no properties"""
+        dtb_file = get_dtb_file('dtoc_test_single_reg.dts')
+        output = tools.GetOutputFilename('output')
+        self.run_test(['struct'], dtb_file, output)