From eec44c7218a3c3ce924a282cc46a59e83feb9de1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 28 Jul 2021 19:23:11 -0600 Subject: [PATCH] dtoc: Support widening a bool value 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 Reported-by: Tom Rini --- arch/sandbox/dts/sandbox.dtsi | 2 ++ test/dm/of_platdata.c | 3 +++ tools/dtoc/fdt.py | 12 ++++++++++++ tools/dtoc/test/dtoc_test_simple.dts | 2 ++ tools/dtoc/test_dtoc.py | 3 +++ tools/dtoc/test_fdt.py | 18 ++++++++++++++++-- 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 31db50db35..200fcab6a4 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -231,6 +231,7 @@ boolval; intval = <1>; intarray = <2 3 4>; + maybe-empty-int = <>; byteval = [05]; bytearray = [06]; longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11]; @@ -254,6 +255,7 @@ u-boot,dm-pre-reloc; compatible = "sandbox,spl-test"; stringarray = "one"; + maybe-empty-int = <1>; }; spl-test5 { diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c index e3fa01afdd..0463cf0b43 100644 --- a/test/dm/of_platdata.c +++ b/test/dm/of_platdata.c @@ -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); diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 429e95f9a9..32a7aa9829 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -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 = [] diff --git a/tools/dtoc/test/dtoc_test_simple.dts b/tools/dtoc/test/dtoc_test_simple.dts index b5c1274bb7..5a6fa88d5c 100644 --- a/tools/dtoc/test/dtoc_test_simple.dts +++ b/tools/dtoc/test/dtoc_test_simple.dts @@ -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 { diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 44d5d0c354..752061f27a 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -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) = { diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 857861c14e..1119e6b784 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -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() -- 2.39.5