mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-20 22:21:41 +00:00
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 <sjg@chromium.org>
This commit is contained in:
parent
5a1b25c201
commit
426d12f42f
2 changed files with 120 additions and 7 deletions
|
@ -689,6 +689,39 @@ class DtbPlatdata():
|
||||||
elif result is False:
|
elif result is False:
|
||||||
print("Could not find uclass for alias '%s'" % prop.name)
|
print("Could not find uclass for alias '%s'" % prop.name)
|
||||||
|
|
||||||
|
def generate_decl(self):
|
||||||
|
nodes_to_output = list(self._valid_nodes)
|
||||||
|
|
||||||
|
self.buf('#include <dm/device-internal.h>\n')
|
||||||
|
self.buf('#include <dm/uclass-internal.h>\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):
|
def assign_seqs(self):
|
||||||
"""Assign a sequence number to each node"""
|
"""Assign a sequence number to each node"""
|
||||||
for node in self._valid_nodes_unsorted:
|
for node in self._valid_nodes_unsorted:
|
||||||
|
@ -794,6 +827,9 @@ class DtbPlatdata():
|
||||||
# key: Command used to generate this file
|
# key: Command used to generate this file
|
||||||
# value: OutputFile for this command
|
# value: OutputFile for this command
|
||||||
OUTPUT_FILES = {
|
OUTPUT_FILES = {
|
||||||
|
'decl':
|
||||||
|
OutputFile(Ftype.HEADER, 'dt-decl.h', DtbPlatdata.generate_decl,
|
||||||
|
'Declares externs for all device/uclass instances'),
|
||||||
'struct':
|
'struct':
|
||||||
OutputFile(Ftype.HEADER, 'dt-structs-gen.h',
|
OutputFile(Ftype.HEADER, 'dt-structs-gen.h',
|
||||||
DtbPlatdata.generate_structs,
|
DtbPlatdata.generate_structs,
|
||||||
|
|
|
@ -40,6 +40,14 @@ HEADER = '''/*
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <linux/libfdt.h>'''
|
#include <linux/libfdt.h>'''
|
||||||
|
|
||||||
|
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 = '''/*
|
C_HEADER = '''/*
|
||||||
* DO NOT MODIFY
|
* DO NOT MODIFY
|
||||||
*
|
*
|
||||||
|
@ -213,6 +221,54 @@ class TestDtoc(unittest.TestCase):
|
||||||
lines = infile.read().splitlines()
|
lines = infile.read().splitlines()
|
||||||
self.assertEqual(C_HEADER.splitlines() + [''], lines)
|
self.assertEqual(C_HEADER.splitlines() + [''], lines)
|
||||||
|
|
||||||
|
decl_text = DECL_HEADER + '''
|
||||||
|
#include <dm/device-internal.h>
|
||||||
|
#include <dm/uclass-internal.h>
|
||||||
|
|
||||||
|
/* 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 <dm/device-internal.h>
|
||||||
|
#include <dm/uclass-internal.h>
|
||||||
|
|
||||||
|
/* 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_text = HEADER + '''
|
||||||
struct dtd_sandbox_i2c {
|
struct dtd_sandbox_i2c {
|
||||||
};
|
};
|
||||||
|
@ -327,10 +383,17 @@ U_BOOT_DRVINFO(spl_test3) = {
|
||||||
|
|
||||||
self._check_strings(self.platdata_text, data)
|
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
|
# Try the 'all' command
|
||||||
self.run_test(['all'], dtb_file, output)
|
self.run_test(['all'], dtb_file, output)
|
||||||
data = tools.ReadFile(output, binary=False)
|
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):
|
def test_driver_alias(self):
|
||||||
"""Test output from a device tree file with a driver alias"""
|
"""Test output from a device tree file with a driver alias"""
|
||||||
|
@ -916,7 +979,8 @@ U_BOOT_DRVINFO(spl_test2) = {
|
||||||
output = tools.GetOutputFilename('output')
|
output = tools.GetOutputFilename('output')
|
||||||
self.run_test(['all'], dtb_file, output)
|
self.run_test(['all'], dtb_file, output)
|
||||||
data = tools.ReadFile(output, binary=False)
|
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):
|
def test_no_command(self):
|
||||||
"""Test running dtoc without a command"""
|
"""Test running dtoc without a command"""
|
||||||
|
@ -930,8 +994,9 @@ U_BOOT_DRVINFO(spl_test2) = {
|
||||||
dtb_file = get_dtb_file('dtoc_test_simple.dts')
|
dtb_file = get_dtb_file('dtoc_test_simple.dts')
|
||||||
output = tools.GetOutputFilename('output')
|
output = tools.GetOutputFilename('output')
|
||||||
with self.assertRaises(ValueError) as exc:
|
with self.assertRaises(ValueError) as exc:
|
||||||
self.run_test(['invalid-cmd'], dtb_file, output, False)
|
self.run_test(['invalid-cmd'], dtb_file, output)
|
||||||
self.assertIn("Unknown command 'invalid-cmd': (use: platdata, struct)",
|
self.assertIn(
|
||||||
|
"Unknown command 'invalid-cmd': (use: decl, platdata, struct)",
|
||||||
str(exc.exception))
|
str(exc.exception))
|
||||||
|
|
||||||
def test_output_conflict(self):
|
def test_output_conflict(self):
|
||||||
|
@ -959,11 +1024,12 @@ U_BOOT_DRVINFO(spl_test2) = {
|
||||||
['all'], dtb_file, False, None, [outdir], None, False,
|
['all'], dtb_file, False, None, [outdir], None, False,
|
||||||
warning_disabled=True, scan=copy_scan())
|
warning_disabled=True, scan=copy_scan())
|
||||||
fnames = glob.glob(outdir + '/*')
|
fnames = glob.glob(outdir + '/*')
|
||||||
self.assertEqual(4, len(fnames))
|
self.assertEqual(5, len(fnames))
|
||||||
|
|
||||||
leafs = set(os.path.basename(fname) for fname in fnames)
|
leafs = set(os.path.basename(fname) for fname in fnames)
|
||||||
self.assertEqual(
|
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)
|
leafs)
|
||||||
|
|
||||||
def setup_process_test(self):
|
def setup_process_test(self):
|
||||||
|
@ -1149,3 +1215,14 @@ U_BOOT_DRVINFO(spl_test2) = {
|
||||||
self.assertIn(root, plat._valid_nodes)
|
self.assertIn(root, plat._valid_nodes)
|
||||||
self.assertEqual('root_driver',
|
self.assertEqual('root_driver',
|
||||||
scan.get_normalized_compat_name(root)[0])
|
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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue