From 059535291c6785bb64594dd0e47c767e8c9e02bf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Feb 2021 06:01:07 -0700 Subject: dtoc: Read aliases for uclasses Scan the aliases in the device tree to establish the number of devices within each uclass, and the sequence number of each. Signed-off-by: Simon Glass --- tools/dtoc/dtb_platdata.py | 28 ++++++++++++++ tools/dtoc/src_scan.py | 32 ++++++++++++++- tools/dtoc/test/dtoc_test_alias_bad.dts | 58 ++++++++++++++++++++++++++++ tools/dtoc/test/dtoc_test_alias_bad_path.dts | 58 ++++++++++++++++++++++++++++ tools/dtoc/test/dtoc_test_alias_bad_uc.dts | 58 ++++++++++++++++++++++++++++ tools/dtoc/test/dtoc_test_inst.dts | 58 ++++++++++++++++++++++++++++ tools/dtoc/test_dtoc.py | 56 ++++++++++++++++++++++++++- 7 files changed, 345 insertions(+), 3 deletions(-) create mode 100644 tools/dtoc/test/dtoc_test_alias_bad.dts create mode 100644 tools/dtoc/test/dtoc_test_alias_bad_path.dts create mode 100644 tools/dtoc/test/dtoc_test_alias_bad_uc.dts create mode 100644 tools/dtoc/test/dtoc_test_inst.dts (limited to 'tools') diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index ef0454c890..f6dcf47d49 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -647,6 +647,29 @@ class DtbPlatdata(): self._output_prop(node, node.props[pname]) self.buf('};\n') + def read_aliases(self): + """Read the aliases and attach the information to self._alias + + Raises: + ValueError: The alias path is not found + """ + alias_node = self._fdt.GetNode('/aliases') + if not alias_node: + return + re_num = re.compile('(^[a-z0-9-]+[a-z]+)([0-9]+)$') + for prop in alias_node.props.values(): + m_alias = re_num.match(prop.name) + if not m_alias: + raise ValueError("Cannot decode alias '%s'" % prop.name) + name, num = m_alias.groups() + node = self._fdt.GetNode(prop.value) + result = self._scan.add_uclass_alias(name, num, node) + if result is None: + raise ValueError("Alias '%s' path '%s' not found" % + (prop.name, prop.value)) + elif result is False: + print("Could not find uclass for alias '%s'" % prop.name) + def process_nodes(self, need_drivers): nodes_to_output = list(self._valid_nodes) @@ -757,6 +780,9 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase, scan (src_src.Scanner): Scanner from a previous run. This can help speed up tests. Use None for normal operation + Returns: + DtbPlatdata object + Raises: ValueError: if args has no command, or an unknown command """ @@ -782,6 +808,7 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase, plat.scan_phandles() if do_process: plat.process_nodes(False) + plat.read_aliases() cmds = args[0].split(',') if 'all' in cmds: @@ -796,3 +823,4 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase, plat.out_header(outfile) outfile.method(plat) plat.finish_output() + return plat diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py index fb78536e00..a275032179 100644 --- a/tools/dtoc/src_scan.py +++ b/tools/dtoc/src_scan.py @@ -116,6 +116,13 @@ class UclassDriver: e.g. 'pci_child_priv' per_child_plat (str): struct name of the per_child_plat_auto member, e.g. 'pci_child_plat' + alias_num_to_node (dict): Aliases for this uclasses (for sequence + numbers) + key (int): Alias number, e.g. 2 for "pci2" + value (str): Node the alias points to + alias_path_to_num (dict): Convert a path to an alias number + key (str): Full path to node (e.g. '/soc/pci') + seq (int): Alias number, e.g. 2 for "pci2" """ def __init__(self, name): self.name = name @@ -125,6 +132,8 @@ class UclassDriver: self.per_dev_plat = '' self.per_child_priv = '' self.per_child_plat = '' + self.alias_num_to_node = {} + self.alias_path_to_num = {} def __eq__(self, other): return (self.name == other.name and @@ -622,7 +631,6 @@ class Scanner: self.scan_driver(pathname) elif fname.endswith('.h'): self.scan_header(pathname) - for fname in self._drivers_additional: if not isinstance(fname, str) or len(fname) == 0: continue @@ -652,3 +660,25 @@ class Scanner: print("Warning: Duplicate driver name '%s' (orig=%s, dups=%s)" % (driver.name, driver.fname, ', '.join([drv.fname for drv in driver.dups]))) + + def add_uclass_alias(self, name, num, node): + """Add an alias to a uclass + + Args: + name: Name of uclass, e.g. 'i2c' + num: Alias number, e.g. 2 for alias 'i2c2' + node: Node the alias points to, or None if None + + Returns: + True if the node was added + False if the node was not added (uclass of that name not found) + None if the node could not be added because it was None + """ + for uclass in self._uclass.values(): + if uclass.name == name: + if node is None: + return None + uclass.alias_num_to_node[int(num)] = node + uclass.alias_path_to_num[node.path] = int(num) + return True + return False diff --git a/tools/dtoc/test/dtoc_test_alias_bad.dts b/tools/dtoc/test/dtoc_test_alias_bad.dts new file mode 100644 index 0000000000..d4f502ad0a --- /dev/null +++ b/tools/dtoc/test/dtoc_test_alias_bad.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + testbus2 = &bus2; + testfdt1 = &testfdt_1; + i2c4- = &i2c; + }; + + spl-test { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + boolval; + intval = <1>; + }; + + i2c: i2c { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c"; + intval = <3>; + }; + + spl-test3 { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + stringarray = "one"; + longbytearray = [09 0a 0b 0c 0d 0e 0f 10]; + }; + + bus2: some-bus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "denx,u-boot-test-bus"; + reg = <3 1>; + ping-expect = <4>; + ping-add = <4>; + testfdt_1: test { + compatible = "denx,u-boot-fdt-test", "google,another-fdt-test"; + reg = <5>; + ping-expect = <5>; + ping-add = <5>; + }; + + test0 { + compatible = "google,another-fdt-test"; + }; + }; +}; diff --git a/tools/dtoc/test/dtoc_test_alias_bad_path.dts b/tools/dtoc/test/dtoc_test_alias_bad_path.dts new file mode 100644 index 0000000000..0beca4f0d0 --- /dev/null +++ b/tools/dtoc/test/dtoc_test_alias_bad_path.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + testbus2 = &bus2; + testfdt1 = &testfdt_1; + i2c4 = "/does/not/exist"; + }; + + spl-test { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + boolval; + intval = <1>; + }; + + i2c: i2c { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c"; + intval = <3>; + }; + + spl-test3 { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + stringarray = "one"; + longbytearray = [09 0a 0b 0c 0d 0e 0f 10]; + }; + + bus2: some-bus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "denx,u-boot-test-bus"; + reg = <3 1>; + ping-expect = <4>; + ping-add = <4>; + testfdt_1: test { + compatible = "denx,u-boot-fdt-test", "google,another-fdt-test"; + reg = <5>; + ping-expect = <5>; + ping-add = <5>; + }; + + test0 { + compatible = "google,another-fdt-test"; + }; + }; +}; diff --git a/tools/dtoc/test/dtoc_test_alias_bad_uc.dts b/tools/dtoc/test/dtoc_test_alias_bad_uc.dts new file mode 100644 index 0000000000..ae64f5b3b2 --- /dev/null +++ b/tools/dtoc/test/dtoc_test_alias_bad_uc.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + testbus2 = &bus2; + testfdt1 = &testfdt_1; + other1 = &testfdt_1; + }; + + spl-test { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + boolval; + intval = <1>; + }; + + i2c: i2c { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c"; + intval = <3>; + }; + + spl-test3 { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + stringarray = "one"; + longbytearray = [09 0a 0b 0c 0d 0e 0f 10]; + }; + + bus2: some-bus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "denx,u-boot-test-bus"; + reg = <3 1>; + ping-expect = <4>; + ping-add = <4>; + testfdt_1: test { + compatible = "denx,u-boot-fdt-test", "google,another-fdt-test"; + reg = <5>; + ping-expect = <5>; + ping-add = <5>; + }; + + test0 { + compatible = "google,another-fdt-test"; + }; + }; +}; diff --git a/tools/dtoc/test/dtoc_test_inst.dts b/tools/dtoc/test/dtoc_test_inst.dts new file mode 100644 index 0000000000..b8177fcef5 --- /dev/null +++ b/tools/dtoc/test/dtoc_test_inst.dts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + testbus2 = &bus2; + testfdt1 = &testfdt_1; + i2c4 = &i2c; + }; + + spl-test { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + boolval; + intval = <1>; + }; + + i2c: i2c { + u-boot,dm-pre-reloc; + compatible = "sandbox,i2c"; + intval = <3>; + }; + + spl-test3 { + u-boot,dm-pre-reloc; + compatible = "sandbox,spl-test"; + stringarray = "one"; + longbytearray = [09 0a 0b 0c 0d 0e 0f 10]; + }; + + bus2: some-bus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "denx,u-boot-test-bus"; + reg = <3 1>; + ping-expect = <4>; + ping-add = <4>; + testfdt_1: test { + compatible = "denx,u-boot-fdt-test", "google,another-fdt-test"; + reg = <5>; + ping-expect = <5>; + ping-add = <5>; + }; + + test0 { + compatible = "google,another-fdt-test"; + }; + }; +}; diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index c1fafb656f..706cc39b3d 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -137,9 +137,12 @@ class TestDtoc(unittest.TestCase): args (list of str): List of arguments for dtoc dtb_file (str): Filename of .dtb file output (str): Filename of output file + + Returns: + DtbPlatdata object """ - dtb_platdata.run_steps(args, dtb_file, False, output, [], None, - warning_disabled=True, scan=copy_scan()) + return dtb_platdata.run_steps(args, dtb_file, False, output, [], None, + warning_disabled=True, scan=copy_scan()) def test_name(self): """Test conversion of device tree names to C identifiers""" @@ -1040,3 +1043,52 @@ U_BOOT_DRVINFO(spl_test2) = { gpio = scan._drivers['sandbox_gpio'] self.assertFalse(gpio.used) + + def test_alias_read(self): + """Test obtaining aliases""" + dtb_file = get_dtb_file('dtoc_test_inst.dts') + output = tools.GetOutputFilename('output') + plat = self.run_test(['struct'], dtb_file, output) + + scan = plat._scan + testfdt_node = plat._fdt.GetNode('/some-bus/test') + self.assertIn('UCLASS_TEST_FDT', scan._uclass) + uc = scan._uclass['UCLASS_TEST_FDT'] + self.assertEqual({1: testfdt_node}, uc.alias_num_to_node) + self.assertEqual({'/some-bus/test': 1}, uc.alias_path_to_num) + + # Try adding an alias that doesn't exist + self.assertFalse(scan.add_uclass_alias('fred', 3, None)) + + # Try adding an alias for a missing node + self.assertIsNone(scan.add_uclass_alias('testfdt', 3, None)) + + def test_alias_read_bad(self): + """Test invalid alias property name""" + dtb_file = get_dtb_file('dtoc_test_alias_bad.dts') + output = tools.GetOutputFilename('output') + with self.assertRaises(ValueError) as exc: + plat = self.run_test(['struct'], dtb_file, output) + self.assertIn("Cannot decode alias 'i2c4-'", str(exc.exception)) + + def test_alias_read_bad_path(self): + """Test alias pointing to a non-existent node""" + # This line may produce a warning, so capture it: + # Warning (alias_paths): /aliases:i2c4: aliases property is not a valid + # node (/does/not/exist) + dtb_file = get_dtb_file('dtoc_test_alias_bad_path.dts', True) + + output = tools.GetOutputFilename('output') + with self.assertRaises(ValueError) as exc: + plat = self.run_test(['struct'], dtb_file, output) + self.assertIn("Alias 'i2c4' path '/does/not/exist' not found", + str(exc.exception)) + + def test_alias_read_bad_uclass(self): + """Test alias for a uclass that doesn't exist""" + dtb_file = get_dtb_file('dtoc_test_alias_bad_uc.dts') + output = tools.GetOutputFilename('output') + with test_util.capture_sys_output() as (stdout, _): + plat = self.run_test(['struct'], dtb_file, output) + self.assertEqual("Could not find uclass for alias 'other1'", + stdout.getvalue().strip()) -- cgit v1.2.3