[PATCH v2 1/1] tools: binman: etype: Allow to replace 'NAME' in node names

This change allows to replace both 'SEQ' and 'NAME' keywords by respectively a sequence number and the name of the FDT to provide more flexibility in the node name for the device trees included in the FIT.
Signed-off-by: Paul HENRYS paul.henrys_ext@softathome.com --- Changes for v2: - Add a test - Add support to replace DEFAULT-NAME - Update entries.rst
tools/binman/entries.rst | 18 ++++++++ tools/binman/etype/fit.py | 20 +++++++++ tools/binman/ftest.py | 61 ++++++++++++++++++-------- tools/binman/test/345_fit_fdt_name.dts | 58 ++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 tools/binman/test/345_fit_fdt_name.dts
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index 53024acad4..83068ba6d3 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -899,6 +899,9 @@ DEFAULT-SEQ: Sequence number of the default fdt, as provided by the 'default-dt' entry argument
+DEFAULT-NAME: + Name of the default fdt, as provided by the 'default-dt' entry argument + Available operations ~~~~~~~~~~~~~~~~~~~~
@@ -960,6 +963,21 @@ You can create config nodes in a similar way:: This tells binman to create nodes `config-1` and `config-2`, i.e. a config for each of your two files.
+It is also possible to use NAME in the node names so that the FDT files name +will be used instead of the sequence number. This can be useful to identify +easily at runtime in U-Boot, the config to be used:: + + configurations { + default = "@config-DEFAULT-NAME"; + @config-NAME { + description = "NAME"; + firmware = "atf"; + loadables = "uboot"; + fdt = "fdt-NAME"; + fit,compatible; // optional + }; + }; + Note that if no devicetree files are provided (with '-a of-list' as above) then no nodes will be generated.
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index 70be9bea47..343094a16e 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -138,6 +138,9 @@ class Entry_fit(Entry_section): Sequence number of the default fdt, as provided by the 'default-dt' entry argument
+ DEFAULT-NAME: + Name of the default fdt, as provided by the 'default-dt' entry argument + Available operations ~~~~~~~~~~~~~~~~~~~~
@@ -199,6 +202,21 @@ class Entry_fit(Entry_section): This tells binman to create nodes `config-1` and `config-2`, i.e. a config for each of your two files.
+ It is also possible to use NAME in the node names so that the FDT files name + will be used instead of the sequence number. This can be useful to identify + easily at runtime in U-Boot, the config to be used:: + + configurations { + default = "@config-DEFAULT-NAME"; + @config-NAME { + description = "NAME"; + firmware = "atf"; + loadables = "uboot"; + fdt = "fdt-NAME"; + fit,compatible; // optional + }; + }; + Note that if no devicetree files are provided (with '-a of-list' as above) then no nodes will be generated.
@@ -674,6 +692,7 @@ class Entry_fit(Entry_section): f"not found in fdt list: {', '.join(self._fdts)}") seq = self._fdts.index(default_dt) val = val[1:].replace('DEFAULT-SEQ', str(seq + 1)) + val = val.replace('DEFAULT-NAME', self._fit_default_dt) fsw.property_string(pname, val) return elif pname.startswith('fit,'): @@ -740,6 +759,7 @@ class Entry_fit(Entry_section): # Generate nodes for each FDT for seq, fdt_fname in enumerate(self._fdts): node_name = node.name[1:].replace('SEQ', str(seq + 1)) + node_name = node_name.replace('NAME', fdt_fname) if self._fdt_dir: fname = os.path.join(self._fdt_dir, fdt_fname + '.dtb') else: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 92c6e59285..4a2a9f2288 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4233,44 +4233,54 @@ class TestFunctional(unittest.TestCase): self.assertEqual(SCP_DATA, data[:len(SCP_DATA)])
def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True, - default_dt=None): + default_dt=None, use_seq_num=True): """Check an image with an FIT with multiple FDT images""" - def _CheckFdt(seq, expected_data): + def _CheckFdt(val, expected_data): """Check the FDT nodes
Args: - seq: Sequence number to check (0 or 1) + val: Sequence number to check (0 or 1) or fdt name expected_data: Expected contents of 'data' property """ - name = 'fdt-%d' % seq + name = 'fdt-%s' % val fnode = dtb.GetNode('/images/%s' % name) self.assertIsNotNone(fnode) self.assertEqual({'description','type', 'compression', 'data'}, set(fnode.props.keys())) self.assertEqual(expected_data, fnode.props['data'].bytes) - self.assertEqual('fdt-test-fdt%d.dtb' % seq, - fnode.props['description'].value) + description = ( + 'fdt-test-fdt%s.dtb' % val if len(val) == 1 else + 'fdt-%s.dtb' % val + ) + self.assertEqual(description, fnode.props['description'].value) self.assertEqual(fnode.subnodes[0].name, 'hash')
- def _CheckConfig(seq, expected_data): + def _CheckConfig(val, expected_data): """Check the configuration nodes
Args: - seq: Sequence number to check (0 or 1) + val: Sequence number to check (0 or 1) or fdt name expected_data: Expected contents of 'data' property """ cnode = dtb.GetNode('/configurations') self.assertIn('default', cnode.props) - self.assertEqual('config-2', cnode.props['default'].value) + default = ( + 'config-2' if len(val) == 1 else + 'config-test-fdt2' + ) + self.assertEqual(default, cnode.props['default'].value)
- name = 'config-%d' % seq + name = 'config-%s' % val fnode = dtb.GetNode('/configurations/%s' % name) self.assertIsNotNone(fnode) self.assertEqual({'description','firmware', 'loadables', 'fdt'}, set(fnode.props.keys())) - self.assertEqual('conf-test-fdt%d.dtb' % seq, - fnode.props['description'].value) - self.assertEqual('fdt-%d' % seq, fnode.props['fdt'].value) + description = ( + 'conf-test-fdt%s.dtb' % val if len(val) == 1 else + 'conf-%s.dtb' % val + ) + self.assertEqual(description, fnode.props['description'].value) + self.assertEqual('fdt-%s' % val, fnode.props['fdt'].value)
entry_args = { 'default-dt': 'test-fdt2', @@ -4291,13 +4301,22 @@ class TestFunctional(unittest.TestCase): fnode = dtb.GetNode('/images/kernel') self.assertIn('data', fnode.props)
- # Check all the properties in fdt-1 and fdt-2 - _CheckFdt(1, TEST_FDT1_DATA) - _CheckFdt(2, TEST_FDT2_DATA) + if use_seq_num == True: + # Check all the properties in fdt-1 and fdt-2 + _CheckFdt('1', TEST_FDT1_DATA) + _CheckFdt('2', TEST_FDT2_DATA)
- # Check configurations - _CheckConfig(1, TEST_FDT1_DATA) - _CheckConfig(2, TEST_FDT2_DATA) + # Check configurations + _CheckConfig('1', TEST_FDT1_DATA) + _CheckConfig('2', TEST_FDT2_DATA) + else: + # Check all the properties in fdt-1 and fdt-2 + _CheckFdt('test-fdt1', TEST_FDT1_DATA) + _CheckFdt('test-fdt2', TEST_FDT2_DATA) + + # Check configurations + _CheckConfig('test-fdt1', TEST_FDT1_DATA) + _CheckConfig('test-fdt2', TEST_FDT2_DATA)
def testFitFdt(self): """Test an image with an FIT with multiple FDT images""" @@ -7945,5 +7964,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertIn("Filename 'aes256.bin' not found in input path", str(e.exception))
+ def testFitFdtName(self): + """Test an image with an FIT with multiple FDT images using NAME""" + self.CheckFitFdt('345_fit_fdt_name.dts', use_seq_num=False) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/345_fit_fdt_name.dts b/tools/binman/test/345_fit_fdt_name.dts new file mode 100644 index 0000000000..631a8e5f59 --- /dev/null +++ b/tools/binman/test/345_fit_fdt_name.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot { + }; + fit { + description = "test-desc"; + #address-cells = <1>; + fit,fdt-list = "of-list"; + + images { + kernel { + description = "Vanilla Linux kernel"; + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash-1 { + algo = "crc32"; + }; + hash-2 { + algo = "sha1"; + }; + u-boot { + }; + }; + @fdt-NAME { + description = "fdt-NAME.dtb"; + type = "flat_dt"; + compression = "none"; + hash { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "@config-DEFAULT-NAME"; + @config-NAME { + description = "conf-NAME.dtb"; + firmware = "uboot"; + loadables = "atf"; + fdt = "fdt-NAME"; + }; + }; + }; + u-boot-nodtb { + }; + }; +};

Hi Paul,
On Mon, 25 Nov 2024 at 10:54, Paul HENRYS paul.henrys_ext@softathome.com wrote:
This change allows to replace both 'SEQ' and 'NAME' keywords by respectively a sequence number and the name of the FDT to provide more flexibility in the node name for the device trees included in the FIT.
Signed-off-by: Paul HENRYS paul.henrys_ext@softathome.com
Changes for v2:
- Add a test
- Add support to replace DEFAULT-NAME
- Update entries.rst
tools/binman/entries.rst | 18 ++++++++ tools/binman/etype/fit.py | 20 +++++++++ tools/binman/ftest.py | 61 ++++++++++++++++++-------- tools/binman/test/345_fit_fdt_name.dts | 58 ++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 tools/binman/test/345_fit_fdt_name.dts
Reviewed-by: Simon Glass sjg@chromium.org
Note that entries.rst needs to be updated whenever the docs for an entry type change.

On Mon, 25 Nov 2024 18:54:21 +0100, Paul HENRYS wrote:
This change allows to replace both 'SEQ' and 'NAME' keywords by respectively a sequence number and the name of the FDT to provide more flexibility in the node name for the device trees included in the FIT.
Applied to u-boot/next, thanks!
participants (3)
-
Paul HENRYS
-
Simon Glass
-
Tom Rini