dtoc: Support widening a bool value
authorSimon Glass <sjg@chromium.org>
Thu, 29 Jul 2021 01:23:11 +0000 (19:23 -0600)
committerSimon Glass <sjg@chromium.org>
Sun, 1 Aug 2021 15:05:24 +0000 (09:05 -0600)
At present if we see 'ranges' property (with no value) we assume it is a
boolean, as per the devicetree spec.

But another node may define 'ranges' with a value, forcing us to widen it
to an int array. At present this is not supported and causes an error.

Fix this and add some test cases.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Tom Rini <trini@konsulko.com>
arch/sandbox/dts/sandbox.dtsi
test/dm/of_platdata.c
tools/dtoc/fdt.py
tools/dtoc/test/dtoc_test_simple.dts
tools/dtoc/test_dtoc.py
tools/dtoc/test_fdt.py

index 31db50d..200fcab 100644 (file)
                boolval;
                intval = <1>;
                intarray = <2 3 4>;
+               maybe-empty-int = <>;
                byteval = [05];
                bytearray = [06];
                longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
                u-boot,dm-pre-reloc;
                compatible = "sandbox,spl-test";
                stringarray = "one";
+               maybe-empty-int = <1>;
        };
 
        spl-test5 {
index e3fa01a..0463cf0 100644 (file)
@@ -40,6 +40,8 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
        ut_asserteq(3, plat->intarray[1]);
        ut_asserteq(4, plat->intarray[2]);
        ut_asserteq(5, plat->byteval);
+       ut_asserteq(1, ARRAY_SIZE(plat->maybe_empty_int));
+       ut_asserteq(0, plat->maybe_empty_int[0]);
        ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
        ut_asserteq(6, plat->bytearray[0]);
        ut_asserteq(0, plat->bytearray[1]);
@@ -78,6 +80,7 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
        ut_asserteq_str("one", plat->stringarray[0]);
        ut_asserteq_str("", plat->stringarray[1]);
        ut_asserteq_str("", plat->stringarray[2]);
+       ut_asserteq(1, plat->maybe_empty_int[0]);
 
        ut_assertok(uclass_next_device_err(&dev));
        plat = dev_get_plat(dev);
index 429e95f..32a7aa9 100644 (file)
@@ -153,6 +153,18 @@ class Prop:
         specific.
         """
         if self.type.needs_widening(newprop.type):
+
+            # A boolean has an empty value: if it exists it is True and if not
+            # it is False. So when widening we always start with an empty list
+            # since the only valid integer property would be an empty list of
+            # integers.
+            # e.g. this is a boolean:
+            #    some-prop;
+            # and it would be widened to int list by:
+            #    some-prop = <1 2>;
+            if self.type == Type.BOOL:
+                self.type = Type.INT
+                self.value = [self.GetEmpty(self.type)]
             if self.type == Type.INT and newprop.type == Type.BYTE:
                 if type(self.value) == list:
                     new_value = []
index b5c1274..5a6fa88 100644 (file)
@@ -14,6 +14,7 @@
                u-boot,dm-pre-reloc;
                compatible = "sandbox,spl-test";
                boolval;
+               maybe-empty-int = <>;
                intval = <1>;
                intarray = <2 3 4>;
                byteval = [05];
@@ -42,6 +43,7 @@
                compatible = "sandbox,spl-test";
                stringarray = "one";
                longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
+               maybe-empty-int = <1>;
        };
 
        i2c@0 {
index 44d5d0c..752061f 100755 (executable)
@@ -299,6 +299,7 @@ struct dtd_sandbox_spl_test {
 \tfdt32_t\t\tintarray[3];
 \tfdt32_t\t\tintval;
 \tunsigned char\tlongbytearray[9];
+\tfdt32_t\t\tmaybe_empty_int[1];
 \tunsigned char\tnotstring[5];
 \tconst char *\tstringarray[3];
 \tconst char *\tstringval;
@@ -358,6 +359,7 @@ static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 \t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
 \t\t0x11},
+\t.maybe_empty_int\t= {0x0},
 \t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
 \t.stringarray\t\t= {"multi-word", "message", ""},
 \t.stringval\t\t= "message",
@@ -398,6 +400,7 @@ U_BOOT_DRVINFO(spl_test2) = {
 static struct dtd_sandbox_spl_test dtv_spl_test3 = {
 \t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
 \t\t0x0},
+\t.maybe_empty_int\t= {0x1},
 \t.stringarray\t\t= {"one", "", ""},
 };
 U_BOOT_DRVINFO(spl_test3) = {
index 857861c..1119e6b 100755 (executable)
@@ -122,8 +122,9 @@ class TestFdt(unittest.TestCase):
         node = self.dtb.GetNode('/spl-test')
         props = self.dtb.GetProps(node)
         self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
-                          'intarray', 'intval', 'longbytearray', 'notstring',
-                          'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
+                          'intarray', 'intval', 'longbytearray',
+                          'maybe-empty-int', 'notstring', 'stringarray',
+                          'stringval', 'u-boot,dm-pre-reloc'],
                          sorted(props.keys()))
 
     def testCheckError(self):
@@ -431,6 +432,19 @@ class TestProp(unittest.TestCase):
         self.assertEqual(Type.INT, prop.type)
         self.assertEqual(3, len(prop.value))
 
+        # Widen an empty bool to an int
+        prop = self.node.props['maybe-empty-int']
+        prop3 = node3.props['maybe-empty-int']
+        self.assertEqual(Type.BOOL, prop.type)
+        self.assertEqual(True, prop.value)
+        self.assertEqual(Type.INT, prop3.type)
+        self.assertFalse(isinstance(prop.value, list))
+        self.assertEqual(4, len(prop3.value))
+        prop.Widen(prop3)
+        self.assertEqual(Type.INT, prop.type)
+        self.assertTrue(isinstance(prop.value, list))
+        self.assertEqual(1, len(prop.value))
+
     def testAdd(self):
         """Test adding properties"""
         self.fdt.pack()