From 426d12f42f47b0b004c838f753dcf415c3268c37 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Feb 2021 06:01:14 -0700 Subject: [PATCH] dtoc: Add support for decl file Add an option to generate the declaration file, which declares all drivers and uclasses, so references can be used in the code. Signed-off-by: Simon Glass --- tools/dtoc/dtb_platdata.py | 36 ++++++++++++++++++ tools/dtoc/test_dtoc.py | 91 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 7 deletions(-) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 46e2725..040b724 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -689,6 +689,39 @@ class DtbPlatdata(): elif result is False: print("Could not find uclass for alias '%s'" % prop.name) + def generate_decl(self): + nodes_to_output = list(self._valid_nodes) + + self.buf('#include \n') + self.buf('#include \n') + self.buf('\n') + self.buf( + '/* driver declarations - these allow DM_DRIVER_GET() to be used */\n') + for node in nodes_to_output: + self.buf('DM_DRIVER_DECL(%s);\n' % node.struct_name); + self.buf('\n') + + if self._instantiate: + self.buf( + '/* device declarations - these allow DM_DEVICE_REF() to be used */\n') + for node in nodes_to_output: + self.buf('DM_DEVICE_DECL(%s);\n' % node.var_name) + self.buf('\n') + + uclass_list = self._valid_uclasses + + self.buf( + '/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */\n') + for uclass in uclass_list: + self.buf('DM_UCLASS_DRIVER_DECL(%s);\n' % uclass.name) + + if self._instantiate: + self.buf('\n') + self.buf('/* uclass declarations - needed for DM_UCLASS_REF() */\n') + for uclass in uclass_list: + self.buf('DM_UCLASS_DECL(%s);\n' % uclass.name) + self.out(''.join(self.get_buf())) + def assign_seqs(self): """Assign a sequence number to each node""" for node in self._valid_nodes_unsorted: @@ -794,6 +827,9 @@ class DtbPlatdata(): # key: Command used to generate this file # value: OutputFile for this command OUTPUT_FILES = { + 'decl': + OutputFile(Ftype.HEADER, 'dt-decl.h', DtbPlatdata.generate_decl, + 'Declares externs for all device/uclass instances'), 'struct': OutputFile(Ftype.HEADER, 'dt-structs-gen.h', DtbPlatdata.generate_structs, diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index cbddd62..a51a7f3 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -40,6 +40,14 @@ HEADER = '''/* #include #include ''' +DECL_HEADER = '''/* + * DO NOT MODIFY + * + * Declares externs for all device/uclass instances. + * This was generated by dtoc from a .dtb (device tree binary) file. + */ +''' + C_HEADER = '''/* * DO NOT MODIFY * @@ -213,6 +221,54 @@ class TestDtoc(unittest.TestCase): lines = infile.read().splitlines() self.assertEqual(C_HEADER.splitlines() + [''], lines) + decl_text = DECL_HEADER + ''' +#include +#include + +/* driver declarations - these allow DM_DRIVER_GET() to be used */ +DM_DRIVER_DECL(sandbox_i2c); +DM_DRIVER_DECL(sandbox_pmic); +DM_DRIVER_DECL(sandbox_spl_test); +DM_DRIVER_DECL(sandbox_spl_test); +DM_DRIVER_DECL(sandbox_spl_test); + +/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */ +DM_UCLASS_DRIVER_DECL(i2c); +DM_UCLASS_DRIVER_DECL(misc); +DM_UCLASS_DRIVER_DECL(pmic); +''' + decl_text_inst = DECL_HEADER + ''' +#include +#include + +/* driver declarations - these allow DM_DRIVER_GET() to be used */ +DM_DRIVER_DECL(sandbox_i2c); +DM_DRIVER_DECL(sandbox_pmic); +DM_DRIVER_DECL(root_driver); +DM_DRIVER_DECL(sandbox_spl_test); +DM_DRIVER_DECL(sandbox_spl_test); +DM_DRIVER_DECL(sandbox_spl_test); + +/* device declarations - these allow DM_DEVICE_REF() to be used */ +DM_DEVICE_DECL(i2c_at_0); +DM_DEVICE_DECL(pmic_at_9); +DM_DEVICE_DECL(root); +DM_DEVICE_DECL(spl_test); +DM_DEVICE_DECL(spl_test2); +DM_DEVICE_DECL(spl_test3); + +/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */ +DM_UCLASS_DRIVER_DECL(i2c); +DM_UCLASS_DRIVER_DECL(misc); +DM_UCLASS_DRIVER_DECL(pmic); +DM_UCLASS_DRIVER_DECL(root); + +/* uclass declarations - needed for DM_UCLASS_REF() */ +DM_UCLASS_DECL(i2c); +DM_UCLASS_DECL(misc); +DM_UCLASS_DECL(pmic); +DM_UCLASS_DECL(root); +''' struct_text = HEADER + ''' struct dtd_sandbox_i2c { }; @@ -327,10 +383,17 @@ U_BOOT_DRVINFO(spl_test3) = { self._check_strings(self.platdata_text, data) + self.run_test(['decl'], dtb_file, output) + with open(output) as infile: + data = infile.read() + + self._check_strings(self.decl_text, data) + # Try the 'all' command self.run_test(['all'], dtb_file, output) data = tools.ReadFile(output, binary=False) - self._check_strings(self.platdata_text + self.struct_text, data) + self._check_strings(self.decl_text + self.platdata_text + + self.struct_text, data) def test_driver_alias(self): """Test output from a device tree file with a driver alias""" @@ -916,7 +979,8 @@ U_BOOT_DRVINFO(spl_test2) = { output = tools.GetOutputFilename('output') self.run_test(['all'], dtb_file, output) data = tools.ReadFile(output, binary=False) - self._check_strings(self.platdata_text + self.struct_text, data) + self._check_strings(self.decl_text + self.platdata_text + + self.struct_text, data) def test_no_command(self): """Test running dtoc without a command""" @@ -930,9 +994,10 @@ U_BOOT_DRVINFO(spl_test2) = { dtb_file = get_dtb_file('dtoc_test_simple.dts') output = tools.GetOutputFilename('output') with self.assertRaises(ValueError) as exc: - self.run_test(['invalid-cmd'], dtb_file, output, False) - self.assertIn("Unknown command 'invalid-cmd': (use: platdata, struct)", - str(exc.exception)) + self.run_test(['invalid-cmd'], dtb_file, output) + self.assertIn( + "Unknown command 'invalid-cmd': (use: decl, platdata, struct)", + str(exc.exception)) def test_output_conflict(self): """Test a conflict between and output dirs and output file""" @@ -959,11 +1024,12 @@ U_BOOT_DRVINFO(spl_test2) = { ['all'], dtb_file, False, None, [outdir], None, False, warning_disabled=True, scan=copy_scan()) fnames = glob.glob(outdir + '/*') - self.assertEqual(4, len(fnames)) + self.assertEqual(5, len(fnames)) leafs = set(os.path.basename(fname) for fname in fnames) self.assertEqual( - {'dt-structs-gen.h', 'source.dts', 'dt-plat.c', 'source.dtb'}, + {'dt-structs-gen.h', 'source.dts', 'dt-plat.c', 'source.dtb', + 'dt-decl.h'}, leafs) def setup_process_test(self): @@ -1149,3 +1215,14 @@ U_BOOT_DRVINFO(spl_test2) = { self.assertIn(root, plat._valid_nodes) self.assertEqual('root_driver', scan.get_normalized_compat_name(root)[0]) + + def test_simple_inst(self): + """Test output from some simple nodes with instantiate enabled""" + dtb_file = get_dtb_file('dtoc_test_simple.dts') + output = tools.GetOutputFilename('output') + + self.run_test(['decl'], dtb_file, output, True) + with open(output) as infile: + data = infile.read() + + self._check_strings(self.decl_text_inst, data) -- 2.7.4