diff options
Diffstat (limited to 'tools/dtoc')
-rw-r--r-- | tools/dtoc/dtb_platdata.py | 76 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_aliases.dts | 5 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_scan_drivers.cxx | 1 | ||||
-rwxr-xr-x | tools/dtoc/test_dtoc.py | 65 |
4 files changed, 74 insertions, 73 deletions
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 8ba8f16369..579a6749c4 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -113,21 +113,17 @@ def get_value(ftype, value): return '%#x' % value def get_compat_name(node): - """Get a node's first compatible string as a C identifier + """Get the node's list of compatible string as a C identifiers Args: node: Node object to check Return: - Tuple: - C identifier for the first compatible string - List of C identifiers for all the other compatible strings - (possibly empty) + List of C identifiers for all the compatible strings """ compat = node.props['compatible'].value - aliases = [] - if isinstance(compat, list): - compat, aliases = compat[0], compat[1:] - return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases] + if not isinstance(compat, list): + compat = [compat] + return [conv_name_to_c(c) for c in compat] class DtbPlatdata(object): @@ -145,17 +141,16 @@ class DtbPlatdata(object): _outfile: The current output file (sys.stdout or a real file) _warning_disabled: true to disable warnings about driver names not found _lines: Stashed list of output lines for outputting in the future - _aliases: Dict that hold aliases for compatible strings - key: First compatible string declared in a node - value: List of additional compatible strings declared in a node _drivers: List of valid driver names found in drivers/ _driver_aliases: Dict that holds aliases for driver names key: Driver alias declared with U_BOOT_DRIVER_ALIAS(driver_alias, driver_name) value: Driver name declared with U_BOOT_DRIVER(driver_name) _links: List of links to be included in dm_populate_phandle_data() + _drivers_additional: List of additional drivers to use during scanning """ - def __init__(self, dtb_fname, include_disabled, warning_disabled): + def __init__(self, dtb_fname, include_disabled, warning_disabled, + drivers_additional=[]): self._fdt = None self._dtb_fname = dtb_fname self._valid_nodes = None @@ -163,15 +158,15 @@ class DtbPlatdata(object): self._outfile = None self._warning_disabled = warning_disabled self._lines = [] - self._aliases = {} self._drivers = [] self._driver_aliases = {} self._links = [] + self._drivers_additional = drivers_additional def get_normalized_compat_name(self, node): """Get a node's normalized compat name - Returns a valid driver name by retrieving node's first compatible + Returns a valid driver name by retrieving node's list of compatible string as a C identifier and performing a check against _drivers and a lookup in driver_aliases printing a warning in case of failure. @@ -185,19 +180,24 @@ class DtbPlatdata(object): In case of no match found, the return will be the same as get_compat_name() """ - compat_c, aliases_c = get_compat_name(node) - if compat_c not in self._drivers: - compat_c_old = compat_c - compat_c = self._driver_aliases.get(compat_c) - if not compat_c: - if not self._warning_disabled: - print('WARNING: the driver %s was not found in the driver list' - % (compat_c_old)) - compat_c = compat_c_old - else: - aliases_c = [compat_c_old] + aliases_c + compat_list_c = get_compat_name(node) + + for compat_c in compat_list_c: + if not compat_c in self._drivers: + compat_c = self._driver_aliases.get(compat_c) + if not compat_c: + continue + + aliases_c = compat_list_c + if compat_c in aliases_c: + aliases_c.remove(compat_c) + return compat_c, aliases_c + + if not self._warning_disabled: + print('WARNING: the driver %s was not found in the driver list' + % (compat_list_c[0])) - return compat_c, aliases_c + return compat_list_c[0], compat_list_c[1:] def setup_output(self, fname): """Set up the output destination @@ -343,6 +343,14 @@ class DtbPlatdata(object): continue self.scan_driver(dirpath + '/' + fn) + for fn in self._drivers_additional: + if not isinstance(fn, str) or len(fn) == 0: + continue + if fn[0] == '/': + self.scan_driver(fn) + else: + self.scan_driver(basedir + '/' + fn) + def scan_dtb(self): """Scan the device tree to obtain a tree of nodes and properties @@ -484,10 +492,6 @@ class DtbPlatdata(object): prop.Widen(struct[name]) upto += 1 - struct_name, aliases = self.get_normalized_compat_name(node) - for alias in aliases: - self._aliases[alias] = struct_name - return structs def scan_phandles(self): @@ -550,11 +554,6 @@ class DtbPlatdata(object): self.out(';\n') self.out('};\n') - for alias, struct_name in self._aliases.items(): - if alias not in sorted(structs): - self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias, - STRUCT_PREFIX, struct_name)) - def output_node(self, node): """Output the C code for a node @@ -668,7 +667,8 @@ class DtbPlatdata(object): self.out(''.join(self.get_buf())) -def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False): +def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False, + drivers_additional=[]): """Run all the steps of the dtoc tool Args: @@ -680,7 +680,7 @@ def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False): if not args: raise ValueError('Please specify a command: struct, platdata') - plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled) + plat = DtbPlatdata(dtb_file, include_disabled, warning_disabled, drivers_additional) plat.scan_drivers() plat.scan_dtb() plat.scan_tree() diff --git a/tools/dtoc/dtoc_test_aliases.dts b/tools/dtoc/dtoc_test_aliases.dts index e545816f4e..ae33716863 100644 --- a/tools/dtoc/dtoc_test_aliases.dts +++ b/tools/dtoc/dtoc_test_aliases.dts @@ -14,4 +14,9 @@ intval = <1>; }; + spl-test2 { + u-boot,dm-pre-reloc; + compatible = "compat1", "simple_bus"; + intval = <1>; + }; }; diff --git a/tools/dtoc/dtoc_test_scan_drivers.cxx b/tools/dtoc/dtoc_test_scan_drivers.cxx new file mode 100644 index 0000000000..557c692ba2 --- /dev/null +++ b/tools/dtoc/dtoc_test_scan_drivers.cxx @@ -0,0 +1 @@ +U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias2) diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 08b02d4843..c2ff267de7 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -13,6 +13,7 @@ import collections import os import struct import sys +import tempfile import unittest from dtoc import dtb_platdata @@ -145,18 +146,18 @@ class TestDtoc(unittest.TestCase): prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1']) node = Node({'compatible': prop}) - self.assertEqual(('rockchip_rk3399_sdhci_5_1', ['arasan_sdhci_5_1']), + self.assertEqual((['rockchip_rk3399_sdhci_5_1', 'arasan_sdhci_5_1']), get_compat_name(node)) prop = Prop(['rockchip,rk3399-sdhci-5.1']) node = Node({'compatible': prop}) - self.assertEqual(('rockchip_rk3399_sdhci_5_1', []), + self.assertEqual((['rockchip_rk3399_sdhci_5_1']), get_compat_name(node)) prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third']) node = Node({'compatible': prop}) - self.assertEqual(('rockchip_rk3399_sdhci_5_1', - ['arasan_sdhci_5_1', 'third']), + self.assertEqual((['rockchip_rk3399_sdhci_5_1', + 'arasan_sdhci_5_1', 'third']), get_compat_name(node)) def test_empty_file(self): @@ -293,7 +294,6 @@ struct dtd_sandbox_gpio { \tbool\t\tgpio_controller; \tfdt32_t\t\tsandbox_gpio_count; }; -#define dtd_sandbox_gpio_alias dtd_sandbox_gpio ''', data) self.run_test(['platdata'], dtb_file, output) @@ -558,36 +558,6 @@ void dm_populate_phandle_data(void) { self.assertIn("Node 'phandle-target' has no cells property", str(e.exception)) - def test_aliases(self): - """Test output from a node with multiple compatible strings""" - dtb_file = get_dtb_file('dtoc_test_aliases.dts') - output = tools.GetOutputFilename('output') - self.run_test(['struct'], dtb_file, output) - with open(output) as infile: - data = infile.read() - self._CheckStrings(HEADER + ''' -struct dtd_compat1 { -\tfdt32_t\t\tintval; -}; -#define dtd_compat2_1_fred dtd_compat1 -#define dtd_compat3 dtd_compat1 -''', data) - - self.run_test(['platdata'], dtb_file, output) - with open(output) as infile: - data = infile.read() - self._CheckStrings(C_HEADER + ''' -static struct dtd_compat1 dtv_spl_test = { -\t.intval\t\t\t= 0x1, -}; -U_BOOT_DEVICE(spl_test) = { -\t.name\t\t= "compat1", -\t.platdata\t= &dtv_spl_test, -\t.platdata_size\t= sizeof(dtv_spl_test), -}; - -''' + C_EMPTY_POPULATE_PHANDLE_DATA, data) - def test_addresses64(self): """Test output from a node with a 'reg' property with na=2, ns=2""" dtb_file = get_dtb_file('dtoc_test_addr64.dts') @@ -863,3 +833,28 @@ U_BOOT_DEVICE(spl_test2) = { self.run_test(['invalid-cmd'], dtb_file, output) self.assertIn("Unknown command 'invalid-cmd': (use: struct, platdata)", str(e.exception)) + + def testScanDrivers(self): + """Test running dtoc with additional drivers to scan""" + dtb_file = get_dtb_file('dtoc_test_simple.dts') + output = tools.GetOutputFilename('output') + with test_util.capture_sys_output() as (stdout, stderr): + dtb_platdata.run_steps(['struct'], dtb_file, False, output, True, + [None, '', 'tools/dtoc/dtoc_test_scan_drivers.cxx']) + + def testUnicodeError(self): + """Test running dtoc with an invalid unicode file + + To be able to perform this test without adding a weird text file which + would produce issues when using checkpatch.pl or patman, generate the + file at runtime and then process it. + """ + dtb_file = get_dtb_file('dtoc_test_simple.dts') + output = tools.GetOutputFilename('output') + driver_fn = '/tmp/' + next(tempfile._get_candidate_names()) + with open(driver_fn, 'wb+') as df: + df.write(b'\x81') + + with test_util.capture_sys_output() as (stdout, stderr): + dtb_platdata.run_steps(['struct'], dtb_file, False, output, True, + [driver_fn]) |