]> Git Repo - J-u-boot.git/blame - tools/dtoc/test_dtoc.py
Merge tag 'dm-pull-5jan21' of git://git.denx.de/u-boot-dm into next
[J-u-boot.git] / tools / dtoc / test_dtoc.py
CommitLineData
3c19dc8b 1#!/usr/bin/env python3
83d290c5 2# SPDX-License-Identifier: GPL-2.0+
c0791928
SG
3# Copyright (c) 2012 The Chromium OS Authors.
4#
c0791928
SG
5
6"""Tests for the dtb_platdata module
7
3def0cf2
SG
8This includes unit tests for some functions and functional tests for the dtoc
9tool.
c0791928
SG
10"""
11
12import collections
10cbd3b7 13import glob
c0791928
SG
14import os
15import struct
16import unittest
17
c0791928
SG
18from dtb_platdata import get_value
19from dtb_platdata import tab_to
67b5ec54 20from dtoc import dtb_platdata
bf776679
SG
21from dtoc import fdt
22from dtoc import fdt_util
a542a70c
SG
23from dtoc.src_scan import conv_name_to_c
24from dtoc.src_scan import get_compat_name
bf776679
SG
25from patman import test_util
26from patman import tools
c0791928 27
67b5ec54 28OUR_PATH = os.path.dirname(os.path.realpath(__file__))
c0791928
SG
29
30
aab660fe
SG
31HEADER = '''/*
32 * DO NOT MODIFY
33 *
d1055d68
SG
34 * Defines the structs used to hold devicetree data.
35 * This was generated by dtoc from a .dtb (device tree binary) file.
aab660fe
SG
36 */
37
38#include <stdbool.h>
b08c8c48 39#include <linux/libfdt.h>'''
aab660fe
SG
40
41C_HEADER = '''/*
42 * DO NOT MODIFY
43 *
d1055d68
SG
44 * Declares the U_BOOT_DRIVER() records and platform data.
45 * This was generated by dtoc from a .dtb (device tree binary) file.
aab660fe
SG
46 */
47
20e442ab 48/* Allow use of U_BOOT_DRVINFO() in this file */
f31fa99a 49#define DT_PLAT_C
cb43ac18 50
aab660fe
SG
51#include <common.h>
52#include <dm.h>
53#include <dt-structs.h>
54'''
55
67b5ec54
SG
56# This is a test so is allowed to access private things in the module it is
57# testing
58# pylint: disable=W0212
fe57c784
SG
59
60def get_dtb_file(dts_fname, capture_stderr=False):
c0791928
SG
61 """Compile a .dts file to a .dtb
62
63 Args:
67b5ec54
SG
64 dts_fname (str): Filename of .dts file in the current directory
65 capture_stderr (bool): True to capture and discard stderr output
c0791928
SG
66
67 Returns:
67b5ec54 68 str: Filename of compiled file in output directory
c0791928 69 """
67b5ec54 70 return fdt_util.EnsureCompiled(os.path.join(OUR_PATH, dts_fname),
fe57c784 71 capture_stderr=capture_stderr)
c0791928
SG
72
73
74class TestDtoc(unittest.TestCase):
75 """Tests for dtoc"""
76 @classmethod
77 def setUpClass(cls):
78 tools.PrepareOutputDir(None)
f02d0eb3 79 cls.maxDiff = None
c0791928
SG
80
81 @classmethod
82 def tearDownClass(cls):
67b5ec54 83 tools.FinaliseOutputDir()
c0791928 84
67b5ec54
SG
85 @staticmethod
86 def _write_python_string(fname, data):
57f0bc42
SG
87 """Write a string with tabs expanded as done in this Python file
88
89 Args:
67b5ec54
SG
90 fname (str): Filename to write to
91 data (str): Raw string to convert
57f0bc42
SG
92 """
93 data = data.replace('\t', '\\t')
67b5ec54
SG
94 with open(fname, 'w') as fout:
95 fout.write(data)
57f0bc42 96
67b5ec54 97 def _check_strings(self, expected, actual):
57f0bc42
SG
98 """Check that a string matches its expected value
99
100 If the strings do not match, they are written to the /tmp directory in
101 the same Python format as is used here in the test. This allows for
102 easy comparison and update of the tests.
103
104 Args:
67b5ec54
SG
105 expected (str): Expected string
106 actual (str): Actual string
57f0bc42
SG
107 """
108 if expected != actual:
67b5ec54
SG
109 self._write_python_string('/tmp/binman.expected', expected)
110 self._write_python_string('/tmp/binman.actual', actual)
90a8132f 111 print('Failures written to /tmp/binman.{expected,actual}')
67b5ec54 112 self.assertEqual(expected, actual)
57f0bc42 113
67b5ec54
SG
114 @staticmethod
115 def run_test(args, dtb_file, output):
116 """Run a test using dtoc
361e7335 117
67b5ec54
SG
118 Args:
119 args (list of str): List of arguments for dtoc
120 dtb_file (str): Filename of .dtb file
121 output (str): Filename of output file
122 """
192c111c 123 dtb_platdata.run_steps(args, dtb_file, False, output, [], True)
361e7335 124
c0791928
SG
125 def test_name(self):
126 """Test conversion of device tree names to C identifiers"""
127 self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
128 self.assertEqual('vendor_clock_frequency',
129 conv_name_to_c('vendor,clock-frequency'))
130 self.assertEqual('rockchip_rk3399_sdhci_5_1',
131 conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
132
133 def test_tab_to(self):
134 """Test operation of tab_to() function"""
135 self.assertEqual('fred ', tab_to(0, 'fred'))
136 self.assertEqual('fred\t', tab_to(1, 'fred'))
137 self.assertEqual('fred was here ', tab_to(1, 'fred was here'))
138 self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here'))
139 self.assertEqual('exactly8 ', tab_to(1, 'exactly8'))
140 self.assertEqual('exactly8\t', tab_to(2, 'exactly8'))
141
142 def test_get_value(self):
143 """Test operation of get_value() function"""
144 self.assertEqual('0x45',
5ea9dccf 145 get_value(fdt.Type.INT, struct.pack('>I', 0x45)))
c0791928 146 self.assertEqual('0x45',
5ea9dccf 147 get_value(fdt.Type.BYTE, struct.pack('<I', 0x45)))
c0791928 148 self.assertEqual('0x0',
5ea9dccf
SG
149 get_value(fdt.Type.BYTE, struct.pack('>I', 0x45)))
150 self.assertEqual('"test"', get_value(fdt.Type.STRING, 'test'))
151 self.assertEqual('true', get_value(fdt.Type.BOOL, None))
c0791928
SG
152
153 def test_get_compat_name(self):
154 """Test operation of get_compat_name() function"""
155 Prop = collections.namedtuple('Prop', ['value'])
156 Node = collections.namedtuple('Node', ['props'])
157
158 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1'])
159 node = Node({'compatible': prop})
dcb3ed64 160 self.assertEqual((['rockchip_rk3399_sdhci_5_1', 'arasan_sdhci_5_1']),
c0791928
SG
161 get_compat_name(node))
162
163 prop = Prop(['rockchip,rk3399-sdhci-5.1'])
164 node = Node({'compatible': prop})
dcb3ed64 165 self.assertEqual((['rockchip_rk3399_sdhci_5_1']),
c0791928
SG
166 get_compat_name(node))
167
168 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third'])
169 node = Node({'compatible': prop})
dcb3ed64 170 self.assertEqual((['rockchip_rk3399_sdhci_5_1',
67b5ec54 171 'arasan_sdhci_5_1', 'third']),
c0791928
SG
172 get_compat_name(node))
173
174 def test_empty_file(self):
175 """Test output from a device tree file with no nodes"""
176 dtb_file = get_dtb_file('dtoc_test_empty.dts')
177 output = tools.GetOutputFilename('output')
361e7335 178 self.run_test(['struct'], dtb_file, output)
c0791928
SG
179 with open(output) as infile:
180 lines = infile.read().splitlines()
aab660fe 181 self.assertEqual(HEADER.splitlines(), lines)
c0791928 182
361e7335 183 self.run_test(['platdata'], dtb_file, output)
c0791928
SG
184 with open(output) as infile:
185 lines = infile.read().splitlines()
d960f0db 186 self.assertEqual(C_HEADER.splitlines() + [''], lines)
c0791928 187
de846cbb 188 struct_text = HEADER + '''
5ec741fd
SG
189struct dtd_sandbox_i2c_test {
190};
191struct dtd_sandbox_pmic_test {
192\tbool\t\tlow_power;
193\tfdt64_t\t\treg[2];
194};
c0791928 195struct dtd_sandbox_spl_test {
f02d0eb3 196\tconst char * acpi_name;
c0791928
SG
197\tbool\t\tboolval;
198\tunsigned char\tbytearray[3];
199\tunsigned char\tbyteval;
200\tfdt32_t\t\tintarray[4];
201\tfdt32_t\t\tintval;
202\tunsigned char\tlongbytearray[9];
2a2d91d0 203\tunsigned char\tnotstring[5];
c0791928
SG
204\tconst char *\tstringarray[3];
205\tconst char *\tstringval;
206};
de846cbb 207'''
c0791928 208
de846cbb 209 platdata_text = C_HEADER + '''
1b27273e
SG
210/* Node /i2c@0 index 0 */
211static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
212};
20e442ab 213U_BOOT_DRVINFO(i2c_at_0) = {
1b27273e 214\t.name\t\t= "sandbox_i2c_test",
caa4daa2 215\t.plat\t= &dtv_i2c_at_0,
4f50086a 216\t.plat_size\t= sizeof(dtv_i2c_at_0),
e41651ff 217\t.parent_idx\t= -1,
1b27273e
SG
218};
219
220/* Node /i2c@0/pmic@9 index 1 */
221static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
222\t.low_power\t\t= true,
223\t.reg\t\t\t= {0x9, 0x0},
224};
20e442ab 225U_BOOT_DRVINFO(pmic_at_9) = {
1b27273e 226\t.name\t\t= "sandbox_pmic_test",
caa4daa2 227\t.plat\t= &dtv_pmic_at_9,
4f50086a 228\t.plat_size\t= sizeof(dtv_pmic_at_9),
e41651ff 229\t.parent_idx\t= 0,
1b27273e
SG
230};
231
232/* Node /spl-test index 2 */
51f1263d 233static struct dtd_sandbox_spl_test dtv_spl_test = {
1953ce75 234\t.boolval\t\t= true,
c0791928
SG
235\t.bytearray\t\t= {0x6, 0x0, 0x0},
236\t.byteval\t\t= 0x5,
1953ce75 237\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
c0791928 238\t.intval\t\t\t= 0x1,
21d54ac3
SG
239\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
240\t\t0x11},
1953ce75 241\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
c0791928 242\t.stringarray\t\t= {"multi-word", "message", ""},
1953ce75 243\t.stringval\t\t= "message",
c0791928 244};
20e442ab 245U_BOOT_DRVINFO(spl_test) = {
c0791928 246\t.name\t\t= "sandbox_spl_test",
caa4daa2 247\t.plat\t= &dtv_spl_test,
4f50086a 248\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 249\t.parent_idx\t= -1,
c0791928
SG
250};
251
1b27273e 252/* Node /spl-test2 index 3 */
51f1263d 253static struct dtd_sandbox_spl_test dtv_spl_test2 = {
f02d0eb3 254\t.acpi_name\t\t= "\\\\_SB.GPO0",
c0791928
SG
255\t.bytearray\t\t= {0x1, 0x23, 0x34},
256\t.byteval\t\t= 0x8,
1953ce75 257\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
c0791928 258\t.intval\t\t\t= 0x3,
e144cafe 259\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0x0, 0x0, 0x0, 0x0,
21d54ac3 260\t\t0x0},
c0791928 261\t.stringarray\t\t= {"another", "multi-word", "message"},
1953ce75 262\t.stringval\t\t= "message2",
c0791928 263};
20e442ab 264U_BOOT_DRVINFO(spl_test2) = {
c0791928 265\t.name\t\t= "sandbox_spl_test",
caa4daa2 266\t.plat\t= &dtv_spl_test2,
4f50086a 267\t.plat_size\t= sizeof(dtv_spl_test2),
e41651ff 268\t.parent_idx\t= -1,
c0791928
SG
269};
270
1b27273e 271/* Node /spl-test3 index 4 */
51f1263d 272static struct dtd_sandbox_spl_test dtv_spl_test3 = {
e144cafe
SG
273\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
274\t\t0x0},
c0791928
SG
275\t.stringarray\t\t= {"one", "", ""},
276};
20e442ab 277U_BOOT_DRVINFO(spl_test3) = {
c0791928 278\t.name\t\t= "sandbox_spl_test",
caa4daa2 279\t.plat\t= &dtv_spl_test3,
4f50086a 280\t.plat_size\t= sizeof(dtv_spl_test3),
e41651ff 281\t.parent_idx\t= -1,
c0791928
SG
282};
283
d960f0db 284'''
de846cbb
SG
285
286 def test_simple(self):
287 """Test output from some simple nodes with various types of data"""
288 dtb_file = get_dtb_file('dtoc_test_simple.dts')
289 output = tools.GetOutputFilename('output')
290 self.run_test(['struct'], dtb_file, output)
291 with open(output) as infile:
292 data = infile.read()
293
294 self._check_strings(self.struct_text, data)
295
296 self.run_test(['platdata'], dtb_file, output)
297 with open(output) as infile:
298 data = infile.read()
299
300 self._check_strings(self.platdata_text, data)
dac8228d 301
10cbd3b7
SG
302 # Try the 'all' command
303 self.run_test(['all'], dtb_file, output)
304 data = tools.ReadFile(output, binary=False)
305 self._check_strings(self.platdata_text + self.struct_text, data)
306
dac8228d
WL
307 def test_driver_alias(self):
308 """Test output from a device tree file with a driver alias"""
309 dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
310 output = tools.GetOutputFilename('output')
361e7335 311 self.run_test(['struct'], dtb_file, output)
dac8228d
WL
312 with open(output) as infile:
313 data = infile.read()
67b5ec54 314 self._check_strings(HEADER + '''
dac8228d
WL
315struct dtd_sandbox_gpio {
316\tconst char *\tgpio_bank_name;
317\tbool\t\tgpio_controller;
318\tfdt32_t\t\tsandbox_gpio_count;
319};
dac8228d
WL
320''', data)
321
361e7335 322 self.run_test(['platdata'], dtb_file, output)
dac8228d
WL
323 with open(output) as infile:
324 data = infile.read()
67b5ec54 325 self._check_strings(C_HEADER + '''
1b27273e 326/* Node /gpios@0 index 0 */
51f1263d 327static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
dac8228d
WL
328\t.gpio_bank_name\t\t= "a",
329\t.gpio_controller\t= true,
330\t.sandbox_gpio_count\t= 0x14,
331};
20e442ab 332U_BOOT_DRVINFO(gpios_at_0) = {
dac8228d 333\t.name\t\t= "sandbox_gpio",
caa4daa2 334\t.plat\t= &dtv_gpios_at_0,
4f50086a 335\t.plat_size\t= sizeof(dtv_gpios_at_0),
e41651ff 336\t.parent_idx\t= -1,
dac8228d
WL
337};
338
361e7335
WL
339''', data)
340
341 def test_invalid_driver(self):
342 """Test output from a device tree file with an invalid driver"""
343 dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts')
344 output = tools.GetOutputFilename('output')
67b5ec54 345 with test_util.capture_sys_output() as _:
192c111c 346 dtb_platdata.run_steps(['struct'], dtb_file, False, output, [])
361e7335
WL
347 with open(output) as infile:
348 data = infile.read()
67b5ec54 349 self._check_strings(HEADER + '''
361e7335
WL
350struct dtd_invalid {
351};
352''', data)
353
67b5ec54 354 with test_util.capture_sys_output() as _:
192c111c 355 dtb_platdata.run_steps(['platdata'], dtb_file, False, output, [])
361e7335
WL
356 with open(output) as infile:
357 data = infile.read()
67b5ec54 358 self._check_strings(C_HEADER + '''
1b27273e 359/* Node /spl-test index 0 */
51f1263d 360static struct dtd_invalid dtv_spl_test = {
361e7335 361};
20e442ab 362U_BOOT_DRVINFO(spl_test) = {
361e7335 363\t.name\t\t= "invalid",
caa4daa2 364\t.plat\t= &dtv_spl_test,
4f50086a 365\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 366\t.parent_idx\t= -1,
361e7335
WL
367};
368
c0791928
SG
369''', data)
370
371 def test_phandle(self):
372 """Test output from a node containing a phandle reference"""
373 dtb_file = get_dtb_file('dtoc_test_phandle.dts')
374 output = tools.GetOutputFilename('output')
361e7335 375 self.run_test(['struct'], dtb_file, output)
c0791928
SG
376 with open(output) as infile:
377 data = infile.read()
67b5ec54 378 self._check_strings(HEADER + '''
c0791928 379struct dtd_source {
634eba4b 380\tstruct phandle_2_arg clocks[4];
c0791928
SG
381};
382struct dtd_target {
383\tfdt32_t\t\tintval;
384};
385''', data)
386
361e7335 387 self.run_test(['platdata'], dtb_file, output)
c0791928
SG
388 with open(output) as infile:
389 data = infile.read()
67b5ec54 390 self._check_strings(C_HEADER + '''
1b27273e 391/* Node /phandle2-target index 0 */
51f1263d 392static struct dtd_target dtv_phandle2_target = {
634eba4b
SG
393\t.intval\t\t\t= 0x1,
394};
20e442ab 395U_BOOT_DRVINFO(phandle2_target) = {
634eba4b 396\t.name\t\t= "target",
caa4daa2 397\t.plat\t= &dtv_phandle2_target,
4f50086a 398\t.plat_size\t= sizeof(dtv_phandle2_target),
e41651ff 399\t.parent_idx\t= -1,
634eba4b
SG
400};
401
1b27273e 402/* Node /phandle3-target index 1 */
51f1263d 403static struct dtd_target dtv_phandle3_target = {
634eba4b
SG
404\t.intval\t\t\t= 0x2,
405};
20e442ab 406U_BOOT_DRVINFO(phandle3_target) = {
634eba4b 407\t.name\t\t= "target",
caa4daa2 408\t.plat\t= &dtv_phandle3_target,
4f50086a 409\t.plat_size\t= sizeof(dtv_phandle3_target),
e41651ff 410\t.parent_idx\t= -1,
634eba4b
SG
411};
412
1b27273e 413/* Node /phandle-source index 2 */
51f1263d 414static struct dtd_source dtv_phandle_source = {
35d50370 415\t.clocks\t\t\t= {
8a38abfc
SG
416\t\t\t{4, {}},
417\t\t\t{0, {11}},
418\t\t\t{1, {12, 13}},
419\t\t\t{4, {}},},
c0791928 420};
20e442ab 421U_BOOT_DRVINFO(phandle_source) = {
c0791928 422\t.name\t\t= "source",
caa4daa2 423\t.plat\t= &dtv_phandle_source,
4f50086a 424\t.plat_size\t= sizeof(dtv_phandle_source),
e41651ff 425\t.parent_idx\t= -1,
c0791928
SG
426};
427
1b27273e 428/* Node /phandle-source2 index 3 */
51f1263d 429static struct dtd_source dtv_phandle_source2 = {
760b7170 430\t.clocks\t\t\t= {
8a38abfc 431\t\t\t{4, {}},},
760b7170 432};
20e442ab 433U_BOOT_DRVINFO(phandle_source2) = {
760b7170 434\t.name\t\t= "source",
caa4daa2 435\t.plat\t= &dtv_phandle_source2,
4f50086a 436\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 437\t.parent_idx\t= -1,
760b7170
SG
438};
439
9eca08dc
SG
440/* Node /phandle-target index 4 */
441static struct dtd_target dtv_phandle_target = {
442\t.intval\t\t\t= 0x0,
443};
444U_BOOT_DRVINFO(phandle_target) = {
445\t.name\t\t= "target",
446\t.plat\t= &dtv_phandle_target,
447\t.plat_size\t= sizeof(dtv_phandle_target),
448\t.parent_idx\t= -1,
449};
450
c0791928
SG
451''', data)
452
8512ea2e
SG
453 def test_phandle_single(self):
454 """Test output from a node containing a phandle reference"""
455 dtb_file = get_dtb_file('dtoc_test_phandle_single.dts')
456 output = tools.GetOutputFilename('output')
361e7335 457 self.run_test(['struct'], dtb_file, output)
8512ea2e
SG
458 with open(output) as infile:
459 data = infile.read()
67b5ec54 460 self._check_strings(HEADER + '''
8512ea2e
SG
461struct dtd_source {
462\tstruct phandle_0_arg clocks[1];
463};
464struct dtd_target {
465\tfdt32_t\t\tintval;
466};
467''', data)
468
469 def test_phandle_reorder(self):
470 """Test that phandle targets are generated before their references"""
471 dtb_file = get_dtb_file('dtoc_test_phandle_reorder.dts')
472 output = tools.GetOutputFilename('output')
361e7335 473 self.run_test(['platdata'], dtb_file, output)
8512ea2e
SG
474 with open(output) as infile:
475 data = infile.read()
67b5ec54 476 self._check_strings(C_HEADER + '''
1b27273e 477/* Node /phandle-source2 index 0 */
51f1263d 478static struct dtd_source dtv_phandle_source2 = {
8512ea2e 479\t.clocks\t\t\t= {
8a38abfc 480\t\t\t{1, {}},},
8512ea2e 481};
20e442ab 482U_BOOT_DRVINFO(phandle_source2) = {
8512ea2e 483\t.name\t\t= "source",
caa4daa2 484\t.plat\t= &dtv_phandle_source2,
4f50086a 485\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 486\t.parent_idx\t= -1,
8512ea2e
SG
487};
488
9eca08dc
SG
489/* Node /phandle-target index 1 */
490static struct dtd_target dtv_phandle_target = {
491};
492U_BOOT_DRVINFO(phandle_target) = {
493\t.name\t\t= "target",
494\t.plat\t= &dtv_phandle_target,
495\t.plat_size\t= sizeof(dtv_phandle_target),
496\t.parent_idx\t= -1,
497};
498
6c3fc50e
WL
499''', data)
500
501 def test_phandle_cd_gpio(self):
502 """Test that phandle targets are generated when unsing cd-gpios"""
503 dtb_file = get_dtb_file('dtoc_test_phandle_cd_gpios.dts')
504 output = tools.GetOutputFilename('output')
192c111c 505 dtb_platdata.run_steps(['platdata'], dtb_file, False, output, [], True)
6c3fc50e
WL
506 with open(output) as infile:
507 data = infile.read()
67b5ec54 508 self._check_strings(C_HEADER + '''
1b27273e 509/* Node /phandle2-target index 0 */
6c3fc50e
WL
510static struct dtd_target dtv_phandle2_target = {
511\t.intval\t\t\t= 0x1,
512};
20e442ab 513U_BOOT_DRVINFO(phandle2_target) = {
6c3fc50e 514\t.name\t\t= "target",
caa4daa2 515\t.plat\t= &dtv_phandle2_target,
4f50086a 516\t.plat_size\t= sizeof(dtv_phandle2_target),
e41651ff 517\t.parent_idx\t= -1,
6c3fc50e
WL
518};
519
1b27273e 520/* Node /phandle3-target index 1 */
6c3fc50e
WL
521static struct dtd_target dtv_phandle3_target = {
522\t.intval\t\t\t= 0x2,
523};
20e442ab 524U_BOOT_DRVINFO(phandle3_target) = {
6c3fc50e 525\t.name\t\t= "target",
caa4daa2 526\t.plat\t= &dtv_phandle3_target,
4f50086a 527\t.plat_size\t= sizeof(dtv_phandle3_target),
e41651ff 528\t.parent_idx\t= -1,
6c3fc50e
WL
529};
530
1b27273e 531/* Node /phandle-source index 2 */
6c3fc50e
WL
532static struct dtd_source dtv_phandle_source = {
533\t.cd_gpios\t\t= {
8a38abfc
SG
534\t\t\t{4, {}},
535\t\t\t{0, {11}},
536\t\t\t{1, {12, 13}},
537\t\t\t{4, {}},},
6c3fc50e 538};
20e442ab 539U_BOOT_DRVINFO(phandle_source) = {
6c3fc50e 540\t.name\t\t= "source",
caa4daa2 541\t.plat\t= &dtv_phandle_source,
4f50086a 542\t.plat_size\t= sizeof(dtv_phandle_source),
e41651ff 543\t.parent_idx\t= -1,
6c3fc50e
WL
544};
545
1b27273e 546/* Node /phandle-source2 index 3 */
6c3fc50e
WL
547static struct dtd_source dtv_phandle_source2 = {
548\t.cd_gpios\t\t= {
8a38abfc 549\t\t\t{4, {}},},
6c3fc50e 550};
20e442ab 551U_BOOT_DRVINFO(phandle_source2) = {
6c3fc50e 552\t.name\t\t= "source",
caa4daa2 553\t.plat\t= &dtv_phandle_source2,
4f50086a 554\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 555\t.parent_idx\t= -1,
9eca08dc
SG
556};
557
558/* Node /phandle-target index 4 */
559static struct dtd_target dtv_phandle_target = {
560\t.intval\t\t\t= 0x0,
561};
562U_BOOT_DRVINFO(phandle_target) = {
563\t.name\t\t= "target",
564\t.plat\t= &dtv_phandle_target,
565\t.plat_size\t= sizeof(dtv_phandle_target),
566\t.parent_idx\t= -1,
6c3fc50e
WL
567};
568
8512ea2e
SG
569''', data)
570
571 def test_phandle_bad(self):
572 """Test a node containing an invalid phandle fails"""
4b4bc06e
SG
573 dtb_file = get_dtb_file('dtoc_test_phandle_bad.dts',
574 capture_stderr=True)
8512ea2e 575 output = tools.GetOutputFilename('output')
67b5ec54 576 with self.assertRaises(ValueError) as exc:
361e7335 577 self.run_test(['struct'], dtb_file, output)
8512ea2e 578 self.assertIn("Cannot parse 'clocks' in node 'phandle-source'",
67b5ec54 579 str(exc.exception))
8512ea2e
SG
580
581 def test_phandle_bad2(self):
582 """Test a phandle target missing its #*-cells property"""
4b4bc06e
SG
583 dtb_file = get_dtb_file('dtoc_test_phandle_bad2.dts',
584 capture_stderr=True)
8512ea2e 585 output = tools.GetOutputFilename('output')
67b5ec54 586 with self.assertRaises(ValueError) as exc:
361e7335 587 self.run_test(['struct'], dtb_file, output)
ad34017c 588 self.assertIn("Node 'phandle-target' has no cells property",
67b5ec54 589 str(exc.exception))
8512ea2e 590
c20ee0ed
SG
591 def test_addresses64(self):
592 """Test output from a node with a 'reg' property with na=2, ns=2"""
593 dtb_file = get_dtb_file('dtoc_test_addr64.dts')
594 output = tools.GetOutputFilename('output')
361e7335 595 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
596 with open(output) as infile:
597 data = infile.read()
67b5ec54 598 self._check_strings(HEADER + '''
c20ee0ed
SG
599struct dtd_test1 {
600\tfdt64_t\t\treg[2];
601};
602struct dtd_test2 {
603\tfdt64_t\t\treg[2];
604};
605struct dtd_test3 {
606\tfdt64_t\t\treg[4];
607};
608''', data)
609
361e7335 610 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
611 with open(output) as infile:
612 data = infile.read()
67b5ec54 613 self._check_strings(C_HEADER + '''
1b27273e 614/* Node /test1 index 0 */
51f1263d 615static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
616\t.reg\t\t\t= {0x1234, 0x5678},
617};
20e442ab 618U_BOOT_DRVINFO(test1) = {
c20ee0ed 619\t.name\t\t= "test1",
caa4daa2 620\t.plat\t= &dtv_test1,
4f50086a 621\t.plat_size\t= sizeof(dtv_test1),
e41651ff 622\t.parent_idx\t= -1,
c20ee0ed
SG
623};
624
1b27273e 625/* Node /test2 index 1 */
51f1263d 626static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
627\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
628};
20e442ab 629U_BOOT_DRVINFO(test2) = {
c20ee0ed 630\t.name\t\t= "test2",
caa4daa2 631\t.plat\t= &dtv_test2,
4f50086a 632\t.plat_size\t= sizeof(dtv_test2),
e41651ff 633\t.parent_idx\t= -1,
c20ee0ed
SG
634};
635
1b27273e 636/* Node /test3 index 2 */
51f1263d 637static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
638\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
639};
20e442ab 640U_BOOT_DRVINFO(test3) = {
c20ee0ed 641\t.name\t\t= "test3",
caa4daa2 642\t.plat\t= &dtv_test3,
4f50086a 643\t.plat_size\t= sizeof(dtv_test3),
e41651ff 644\t.parent_idx\t= -1,
c20ee0ed
SG
645};
646
d960f0db 647''', data)
c20ee0ed
SG
648
649 def test_addresses32(self):
650 """Test output from a node with a 'reg' property with na=1, ns=1"""
651 dtb_file = get_dtb_file('dtoc_test_addr32.dts')
652 output = tools.GetOutputFilename('output')
361e7335 653 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
654 with open(output) as infile:
655 data = infile.read()
67b5ec54 656 self._check_strings(HEADER + '''
c20ee0ed
SG
657struct dtd_test1 {
658\tfdt32_t\t\treg[2];
659};
660struct dtd_test2 {
661\tfdt32_t\t\treg[4];
662};
663''', data)
664
361e7335 665 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
666 with open(output) as infile:
667 data = infile.read()
67b5ec54 668 self._check_strings(C_HEADER + '''
1b27273e 669/* Node /test1 index 0 */
51f1263d 670static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
671\t.reg\t\t\t= {0x1234, 0x5678},
672};
20e442ab 673U_BOOT_DRVINFO(test1) = {
c20ee0ed 674\t.name\t\t= "test1",
caa4daa2 675\t.plat\t= &dtv_test1,
4f50086a 676\t.plat_size\t= sizeof(dtv_test1),
e41651ff 677\t.parent_idx\t= -1,
c20ee0ed
SG
678};
679
1b27273e 680/* Node /test2 index 1 */
51f1263d 681static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
682\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
683};
20e442ab 684U_BOOT_DRVINFO(test2) = {
c20ee0ed 685\t.name\t\t= "test2",
caa4daa2 686\t.plat\t= &dtv_test2,
4f50086a 687\t.plat_size\t= sizeof(dtv_test2),
e41651ff 688\t.parent_idx\t= -1,
c20ee0ed
SG
689};
690
d960f0db 691''', data)
c20ee0ed
SG
692
693 def test_addresses64_32(self):
694 """Test output from a node with a 'reg' property with na=2, ns=1"""
695 dtb_file = get_dtb_file('dtoc_test_addr64_32.dts')
696 output = tools.GetOutputFilename('output')
361e7335 697 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
698 with open(output) as infile:
699 data = infile.read()
67b5ec54 700 self._check_strings(HEADER + '''
c20ee0ed
SG
701struct dtd_test1 {
702\tfdt64_t\t\treg[2];
703};
704struct dtd_test2 {
705\tfdt64_t\t\treg[2];
706};
707struct dtd_test3 {
708\tfdt64_t\t\treg[4];
709};
710''', data)
711
361e7335 712 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
713 with open(output) as infile:
714 data = infile.read()
67b5ec54 715 self._check_strings(C_HEADER + '''
1b27273e 716/* Node /test1 index 0 */
51f1263d 717static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
718\t.reg\t\t\t= {0x123400000000, 0x5678},
719};
20e442ab 720U_BOOT_DRVINFO(test1) = {
c20ee0ed 721\t.name\t\t= "test1",
caa4daa2 722\t.plat\t= &dtv_test1,
4f50086a 723\t.plat_size\t= sizeof(dtv_test1),
e41651ff 724\t.parent_idx\t= -1,
c20ee0ed
SG
725};
726
1b27273e 727/* Node /test2 index 1 */
51f1263d 728static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
729\t.reg\t\t\t= {0x1234567890123456, 0x98765432},
730};
20e442ab 731U_BOOT_DRVINFO(test2) = {
c20ee0ed 732\t.name\t\t= "test2",
caa4daa2 733\t.plat\t= &dtv_test2,
4f50086a 734\t.plat_size\t= sizeof(dtv_test2),
e41651ff 735\t.parent_idx\t= -1,
c20ee0ed
SG
736};
737
1b27273e 738/* Node /test3 index 2 */
51f1263d 739static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
740\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
741};
20e442ab 742U_BOOT_DRVINFO(test3) = {
c20ee0ed 743\t.name\t\t= "test3",
caa4daa2 744\t.plat\t= &dtv_test3,
4f50086a 745\t.plat_size\t= sizeof(dtv_test3),
e41651ff 746\t.parent_idx\t= -1,
c20ee0ed
SG
747};
748
d960f0db 749''', data)
c20ee0ed
SG
750
751 def test_addresses32_64(self):
752 """Test output from a node with a 'reg' property with na=1, ns=2"""
753 dtb_file = get_dtb_file('dtoc_test_addr32_64.dts')
754 output = tools.GetOutputFilename('output')
361e7335 755 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
756 with open(output) as infile:
757 data = infile.read()
67b5ec54 758 self._check_strings(HEADER + '''
c20ee0ed
SG
759struct dtd_test1 {
760\tfdt64_t\t\treg[2];
761};
762struct dtd_test2 {
763\tfdt64_t\t\treg[2];
764};
765struct dtd_test3 {
766\tfdt64_t\t\treg[4];
767};
768''', data)
769
361e7335 770 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
771 with open(output) as infile:
772 data = infile.read()
67b5ec54 773 self._check_strings(C_HEADER + '''
1b27273e 774/* Node /test1 index 0 */
51f1263d 775static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
776\t.reg\t\t\t= {0x1234, 0x567800000000},
777};
20e442ab 778U_BOOT_DRVINFO(test1) = {
c20ee0ed 779\t.name\t\t= "test1",
caa4daa2 780\t.plat\t= &dtv_test1,
4f50086a 781\t.plat_size\t= sizeof(dtv_test1),
e41651ff 782\t.parent_idx\t= -1,
c20ee0ed
SG
783};
784
1b27273e 785/* Node /test2 index 1 */
51f1263d 786static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
787\t.reg\t\t\t= {0x12345678, 0x9876543210987654},
788};
20e442ab 789U_BOOT_DRVINFO(test2) = {
c20ee0ed 790\t.name\t\t= "test2",
caa4daa2 791\t.plat\t= &dtv_test2,
4f50086a 792\t.plat_size\t= sizeof(dtv_test2),
e41651ff 793\t.parent_idx\t= -1,
c20ee0ed
SG
794};
795
1b27273e 796/* Node /test3 index 2 */
51f1263d 797static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
798\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
799};
20e442ab 800U_BOOT_DRVINFO(test3) = {
c20ee0ed 801\t.name\t\t= "test3",
caa4daa2 802\t.plat\t= &dtv_test3,
4f50086a 803\t.plat_size\t= sizeof(dtv_test3),
e41651ff 804\t.parent_idx\t= -1,
c20ee0ed
SG
805};
806
d960f0db 807''', data)
8512ea2e
SG
808
809 def test_bad_reg(self):
810 """Test that a reg property with an invalid type generates an error"""
fe57c784
SG
811 # Capture stderr since dtc will emit warnings for this file
812 dtb_file = get_dtb_file('dtoc_test_bad_reg.dts', capture_stderr=True)
8512ea2e 813 output = tools.GetOutputFilename('output')
67b5ec54 814 with self.assertRaises(ValueError) as exc:
361e7335 815 self.run_test(['struct'], dtb_file, output)
8512ea2e 816 self.assertIn("Node 'spl-test' reg property is not an int",
67b5ec54 817 str(exc.exception))
8512ea2e
SG
818
819 def test_bad_reg2(self):
820 """Test that a reg property with an invalid cell count is detected"""
fe57c784
SG
821 # Capture stderr since dtc will emit warnings for this file
822 dtb_file = get_dtb_file('dtoc_test_bad_reg2.dts', capture_stderr=True)
8512ea2e 823 output = tools.GetOutputFilename('output')
67b5ec54 824 with self.assertRaises(ValueError) as exc:
361e7335 825 self.run_test(['struct'], dtb_file, output)
67b5ec54
SG
826 self.assertIn(
827 "Node 'spl-test' reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
828 str(exc.exception))
8512ea2e
SG
829
830 def test_add_prop(self):
831 """Test that a subequent node can add a new property to a struct"""
832 dtb_file = get_dtb_file('dtoc_test_add_prop.dts')
833 output = tools.GetOutputFilename('output')
361e7335 834 self.run_test(['struct'], dtb_file, output)
8512ea2e
SG
835 with open(output) as infile:
836 data = infile.read()
67b5ec54 837 self._check_strings(HEADER + '''
8512ea2e
SG
838struct dtd_sandbox_spl_test {
839\tfdt32_t\t\tintarray;
840\tfdt32_t\t\tintval;
841};
842''', data)
843
361e7335 844 self.run_test(['platdata'], dtb_file, output)
8512ea2e
SG
845 with open(output) as infile:
846 data = infile.read()
67b5ec54 847 self._check_strings(C_HEADER + '''
1b27273e 848/* Node /spl-test index 0 */
51f1263d 849static struct dtd_sandbox_spl_test dtv_spl_test = {
8512ea2e
SG
850\t.intval\t\t\t= 0x1,
851};
20e442ab 852U_BOOT_DRVINFO(spl_test) = {
8512ea2e 853\t.name\t\t= "sandbox_spl_test",
caa4daa2 854\t.plat\t= &dtv_spl_test,
4f50086a 855\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 856\t.parent_idx\t= -1,
8512ea2e
SG
857};
858
1b27273e 859/* Node /spl-test2 index 1 */
51f1263d 860static struct dtd_sandbox_spl_test dtv_spl_test2 = {
8512ea2e
SG
861\t.intarray\t\t= 0x5,
862};
20e442ab 863U_BOOT_DRVINFO(spl_test2) = {
8512ea2e 864\t.name\t\t= "sandbox_spl_test",
caa4daa2 865\t.plat\t= &dtv_spl_test2,
4f50086a 866\t.plat_size\t= sizeof(dtv_spl_test2),
e41651ff 867\t.parent_idx\t= -1,
8512ea2e
SG
868};
869
d960f0db 870''', data)
8512ea2e 871
67b5ec54 872 def test_stdout(self):
8512ea2e
SG
873 """Test output to stdout"""
874 dtb_file = get_dtb_file('dtoc_test_simple.dts')
de846cbb 875 with test_util.capture_sys_output() as (stdout, _):
f62cea0e 876 self.run_test(['struct'], dtb_file, None)
de846cbb 877 self._check_strings(self.struct_text, stdout.getvalue())
8512ea2e 878
be44f271
SG
879 def test_multi_to_file(self):
880 """Test output of multiple pieces to a single file"""
881 dtb_file = get_dtb_file('dtoc_test_simple.dts')
882 output = tools.GetOutputFilename('output')
10cbd3b7 883 self.run_test(['all'], dtb_file, output)
be44f271 884 data = tools.ReadFile(output, binary=False)
10cbd3b7 885 self._check_strings(self.platdata_text + self.struct_text, data)
be44f271 886
67b5ec54 887 def test_no_command(self):
8512ea2e 888 """Test running dtoc without a command"""
67b5ec54 889 with self.assertRaises(ValueError) as exc:
361e7335 890 self.run_test([], '', '')
8512ea2e 891 self.assertIn("Please specify a command: struct, platdata",
67b5ec54 892 str(exc.exception))
8512ea2e 893
67b5ec54 894 def test_bad_command(self):
8512ea2e
SG
895 """Test running dtoc with an invalid command"""
896 dtb_file = get_dtb_file('dtoc_test_simple.dts')
897 output = tools.GetOutputFilename('output')
67b5ec54 898 with self.assertRaises(ValueError) as exc:
361e7335 899 self.run_test(['invalid-cmd'], dtb_file, output)
10cbd3b7 900 self.assertIn("Unknown command 'invalid-cmd': (use: platdata, struct)",
67b5ec54 901 str(exc.exception))
6c74d1b8 902
10cbd3b7
SG
903 def test_output_conflict(self):
904 """Test a conflict between and output dirs and output file"""
905 with self.assertRaises(ValueError) as exc:
906 dtb_platdata.run_steps(['all'], None, False, 'out', ['cdir'], True)
907 self.assertIn("Must specify either output or output_dirs, not both",
908 str(exc.exception))
909
910 def test_output_dirs(self):
911 """Test outputting files to a directory"""
912 # Remove the directory so that files from other tests are not there
913 tools._RemoveOutputDir()
914 tools.PrepareOutputDir(None)
915
916 # This should create the .dts and .dtb in the output directory
917 dtb_file = get_dtb_file('dtoc_test_simple.dts')
918 outdir = tools.GetOutputDir()
919 fnames = glob.glob(outdir + '/*')
920 self.assertEqual(2, len(fnames))
921
922 dtb_platdata.run_steps(['all'], dtb_file, False, None, [outdir], True)
923 fnames = glob.glob(outdir + '/*')
924 self.assertEqual(4, len(fnames))
925
926 leafs = set(os.path.basename(fname) for fname in fnames)
927 self.assertEqual(
f31fa99a 928 {'dt-structs-gen.h', 'source.dts', 'dt-plat.c', 'source.dtb'},
10cbd3b7 929 leafs)
This page took 0.334714 seconds and 4 git commands to generate.