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