]> Git Repo - J-u-boot.git/blame - tools/dtoc/test_dtoc.py
Merge tag 'xilinx-for-v2021.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u...
[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
a32eb7dc 13import copy
10cbd3b7 14import glob
c0791928
SG
15import os
16import struct
17import unittest
18
ea74c951 19from dtb_platdata import Ftype
c0791928
SG
20from dtb_platdata import get_value
21from dtb_platdata import tab_to
67b5ec54 22from dtoc import dtb_platdata
bf776679
SG
23from dtoc import fdt
24from dtoc import fdt_util
a32eb7dc 25from dtoc import src_scan
a542a70c
SG
26from dtoc.src_scan import conv_name_to_c
27from dtoc.src_scan import get_compat_name
bf776679
SG
28from patman import test_util
29from patman import tools
c0791928 30
67b5ec54 31OUR_PATH = os.path.dirname(os.path.realpath(__file__))
c0791928
SG
32
33
aab660fe
SG
34HEADER = '''/*
35 * DO NOT MODIFY
36 *
d1055d68
SG
37 * Defines the structs used to hold devicetree data.
38 * This was generated by dtoc from a .dtb (device tree binary) file.
aab660fe
SG
39 */
40
41#include <stdbool.h>
b08c8c48 42#include <linux/libfdt.h>'''
aab660fe 43
426d12f4
SG
44DECL_HEADER = '''/*
45 * DO NOT MODIFY
46 *
47 * Declares externs for all device/uclass instances.
48 * This was generated by dtoc from a .dtb (device tree binary) file.
49 */
50'''
51
4b91be2f 52C_HEADER_PRE = '''/*
aab660fe
SG
53 * DO NOT MODIFY
54 *
d1055d68
SG
55 * Declares the U_BOOT_DRIVER() records and platform data.
56 * This was generated by dtoc from a .dtb (device tree binary) file.
aab660fe 57 */
4b91be2f 58'''
aab660fe 59
4b91be2f 60C_HEADER = C_HEADER_PRE + '''
20e442ab 61/* Allow use of U_BOOT_DRVINFO() in this file */
f31fa99a 62#define DT_PLAT_C
cb43ac18 63
aab660fe
SG
64#include <common.h>
65#include <dm.h>
66#include <dt-structs.h>
67'''
68
ea74c951
SG
69UCLASS_HEADER_COMMON = '''/*
70 * DO NOT MODIFY
71 *
72 * Declares the uclass instances (struct uclass).
73 * This was generated by dtoc from a .dtb (device tree binary) file.
74 */
75'''
76
a32eb7dc
SG
77# Scanner saved from a previous run of the tests (to speed things up)
78saved_scan = None
79
67b5ec54
SG
80# This is a test so is allowed to access private things in the module it is
81# testing
82# pylint: disable=W0212
fe57c784
SG
83
84def get_dtb_file(dts_fname, capture_stderr=False):
c0791928
SG
85 """Compile a .dts file to a .dtb
86
87 Args:
67b5ec54
SG
88 dts_fname (str): Filename of .dts file in the current directory
89 capture_stderr (bool): True to capture and discard stderr output
c0791928
SG
90
91 Returns:
67b5ec54 92 str: Filename of compiled file in output directory
c0791928 93 """
dff51a52 94 return fdt_util.EnsureCompiled(os.path.join(OUR_PATH, 'test', dts_fname),
fe57c784 95 capture_stderr=capture_stderr)
c0791928
SG
96
97
a32eb7dc
SG
98def setup():
99 global saved_scan
100
101 # Disable warnings so that calls to get_normalized_compat_name() will not
102 # output things.
0c59acef 103 saved_scan = src_scan.Scanner(None, False)
a32eb7dc
SG
104 saved_scan.scan_drivers()
105
106def copy_scan():
107 """Get a copy of saved_scan so that each test can start clean"""
108 return copy.deepcopy(saved_scan)
109
110
c0791928
SG
111class TestDtoc(unittest.TestCase):
112 """Tests for dtoc"""
113 @classmethod
114 def setUpClass(cls):
115 tools.PrepareOutputDir(None)
f02d0eb3 116 cls.maxDiff = None
c0791928
SG
117
118 @classmethod
119 def tearDownClass(cls):
67b5ec54 120 tools.FinaliseOutputDir()
c0791928 121
67b5ec54
SG
122 @staticmethod
123 def _write_python_string(fname, data):
57f0bc42
SG
124 """Write a string with tabs expanded as done in this Python file
125
126 Args:
67b5ec54
SG
127 fname (str): Filename to write to
128 data (str): Raw string to convert
57f0bc42
SG
129 """
130 data = data.replace('\t', '\\t')
67b5ec54
SG
131 with open(fname, 'w') as fout:
132 fout.write(data)
57f0bc42 133
67b5ec54 134 def _check_strings(self, expected, actual):
57f0bc42
SG
135 """Check that a string matches its expected value
136
137 If the strings do not match, they are written to the /tmp directory in
138 the same Python format as is used here in the test. This allows for
139 easy comparison and update of the tests.
140
141 Args:
67b5ec54
SG
142 expected (str): Expected string
143 actual (str): Actual string
57f0bc42
SG
144 """
145 if expected != actual:
67b5ec54
SG
146 self._write_python_string('/tmp/binman.expected', expected)
147 self._write_python_string('/tmp/binman.actual', actual)
90a8132f 148 print('Failures written to /tmp/binman.{expected,actual}')
67b5ec54 149 self.assertEqual(expected, actual)
57f0bc42 150
67b5ec54 151 @staticmethod
4a092350 152 def run_test(args, dtb_file, output, instantiate=False):
67b5ec54 153 """Run a test using dtoc
361e7335 154
67b5ec54
SG
155 Args:
156 args (list of str): List of arguments for dtoc
157 dtb_file (str): Filename of .dtb file
158 output (str): Filename of output file
05953529
SG
159
160 Returns:
161 DtbPlatdata object
67b5ec54 162 """
337d6972
SG
163 # Make a copy of the 'scan' object, since it includes uclasses and
164 # drivers, which get updated during execution.
4a092350
SG
165 return dtb_platdata.run_steps(
166 args, dtb_file, False, output, [], None, instantiate,
167 warning_disabled=True, scan=copy_scan())
361e7335 168
c0791928
SG
169 def test_name(self):
170 """Test conversion of device tree names to C identifiers"""
171 self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
172 self.assertEqual('vendor_clock_frequency',
173 conv_name_to_c('vendor,clock-frequency'))
174 self.assertEqual('rockchip_rk3399_sdhci_5_1',
175 conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
176
177 def test_tab_to(self):
178 """Test operation of tab_to() function"""
179 self.assertEqual('fred ', tab_to(0, 'fred'))
180 self.assertEqual('fred\t', tab_to(1, 'fred'))
181 self.assertEqual('fred was here ', tab_to(1, 'fred was here'))
182 self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here'))
183 self.assertEqual('exactly8 ', tab_to(1, 'exactly8'))
184 self.assertEqual('exactly8\t', tab_to(2, 'exactly8'))
185
186 def test_get_value(self):
187 """Test operation of get_value() function"""
188 self.assertEqual('0x45',
5ea9dccf 189 get_value(fdt.Type.INT, struct.pack('>I', 0x45)))
c0791928 190 self.assertEqual('0x45',
5ea9dccf 191 get_value(fdt.Type.BYTE, struct.pack('<I', 0x45)))
c0791928 192 self.assertEqual('0x0',
5ea9dccf
SG
193 get_value(fdt.Type.BYTE, struct.pack('>I', 0x45)))
194 self.assertEqual('"test"', get_value(fdt.Type.STRING, 'test'))
195 self.assertEqual('true', get_value(fdt.Type.BOOL, None))
c0791928
SG
196
197 def test_get_compat_name(self):
198 """Test operation of get_compat_name() function"""
199 Prop = collections.namedtuple('Prop', ['value'])
200 Node = collections.namedtuple('Node', ['props'])
201
202 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1'])
203 node = Node({'compatible': prop})
dcb3ed64 204 self.assertEqual((['rockchip_rk3399_sdhci_5_1', 'arasan_sdhci_5_1']),
c0791928
SG
205 get_compat_name(node))
206
207 prop = Prop(['rockchip,rk3399-sdhci-5.1'])
208 node = Node({'compatible': prop})
dcb3ed64 209 self.assertEqual((['rockchip_rk3399_sdhci_5_1']),
c0791928
SG
210 get_compat_name(node))
211
212 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third'])
213 node = Node({'compatible': prop})
dcb3ed64 214 self.assertEqual((['rockchip_rk3399_sdhci_5_1',
67b5ec54 215 'arasan_sdhci_5_1', 'third']),
c0791928
SG
216 get_compat_name(node))
217
218 def test_empty_file(self):
219 """Test output from a device tree file with no nodes"""
220 dtb_file = get_dtb_file('dtoc_test_empty.dts')
221 output = tools.GetOutputFilename('output')
a32eb7dc
SG
222
223 # Run this one without saved_scan to complete test coverage
4a092350
SG
224 dtb_platdata.run_steps(['struct'], dtb_file, False, output, [], None,
225 False)
c0791928
SG
226 with open(output) as infile:
227 lines = infile.read().splitlines()
aab660fe 228 self.assertEqual(HEADER.splitlines(), lines)
c0791928 229
361e7335 230 self.run_test(['platdata'], dtb_file, output)
c0791928
SG
231 with open(output) as infile:
232 lines = infile.read().splitlines()
d960f0db 233 self.assertEqual(C_HEADER.splitlines() + [''], lines)
c0791928 234
426d12f4
SG
235 decl_text = DECL_HEADER + '''
236#include <dm/device-internal.h>
237#include <dm/uclass-internal.h>
238
239/* driver declarations - these allow DM_DRIVER_GET() to be used */
cff7dcf3
SG
240extern U_BOOT_DRIVER(sandbox_i2c);
241extern U_BOOT_DRIVER(sandbox_pmic);
242extern U_BOOT_DRIVER(sandbox_spl_test);
243extern U_BOOT_DRIVER(sandbox_spl_test);
244extern U_BOOT_DRIVER(sandbox_spl_test);
426d12f4
SG
245
246/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */
cff7dcf3
SG
247extern UCLASS_DRIVER(i2c);
248extern UCLASS_DRIVER(misc);
249extern UCLASS_DRIVER(pmic);
426d12f4
SG
250'''
251 decl_text_inst = DECL_HEADER + '''
252#include <dm/device-internal.h>
253#include <dm/uclass-internal.h>
254
255/* driver declarations - these allow DM_DRIVER_GET() to be used */
cff7dcf3
SG
256extern U_BOOT_DRIVER(sandbox_i2c);
257extern U_BOOT_DRIVER(root_driver);
258extern U_BOOT_DRIVER(denx_u_boot_test_bus);
259extern U_BOOT_DRIVER(sandbox_spl_test);
260extern U_BOOT_DRIVER(sandbox_spl_test);
261extern U_BOOT_DRIVER(denx_u_boot_fdt_test);
262extern U_BOOT_DRIVER(denx_u_boot_fdt_test);
426d12f4
SG
263
264/* device declarations - these allow DM_DEVICE_REF() to be used */
cff7dcf3
SG
265extern DM_DEVICE_INST(i2c);
266extern DM_DEVICE_INST(root);
267extern DM_DEVICE_INST(some_bus);
268extern DM_DEVICE_INST(spl_test);
269extern DM_DEVICE_INST(spl_test3);
270extern DM_DEVICE_INST(test);
271extern DM_DEVICE_INST(test0);
426d12f4
SG
272
273/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */
cff7dcf3
SG
274extern UCLASS_DRIVER(i2c);
275extern UCLASS_DRIVER(misc);
276extern UCLASS_DRIVER(root);
277extern UCLASS_DRIVER(testbus);
278extern UCLASS_DRIVER(testfdt);
426d12f4
SG
279
280/* uclass declarations - needed for DM_UCLASS_REF() */
cff7dcf3
SG
281extern DM_UCLASS_INST(i2c);
282extern DM_UCLASS_INST(misc);
283extern DM_UCLASS_INST(root);
284extern DM_UCLASS_INST(testbus);
285extern DM_UCLASS_INST(testfdt);
426d12f4 286'''
de846cbb 287 struct_text = HEADER + '''
f38161c5 288struct dtd_sandbox_i2c {
5ec741fd 289};
f38161c5 290struct dtd_sandbox_pmic {
5ec741fd 291\tbool\t\tlow_power;
3e200caf 292\tfdt32_t\t\treg[1];
5ec741fd 293};
c0791928 294struct dtd_sandbox_spl_test {
f02d0eb3 295\tconst char * acpi_name;
c0791928
SG
296\tbool\t\tboolval;
297\tunsigned char\tbytearray[3];
298\tunsigned char\tbyteval;
ca04494d 299\tfdt32_t\t\tintarray[3];
c0791928
SG
300\tfdt32_t\t\tintval;
301\tunsigned char\tlongbytearray[9];
eec44c72 302\tfdt32_t\t\tmaybe_empty_int[1];
2a2d91d0 303\tunsigned char\tnotstring[5];
c0791928
SG
304\tconst char *\tstringarray[3];
305\tconst char *\tstringval;
306};
de846cbb 307'''
de846cbb 308 platdata_text = C_HEADER + '''
9763e4eb
SG
309/*
310 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
311 *
312 * idx driver_info driver
313 * --- -------------------- --------------------
314 * 0: i2c_at_0 sandbox_i2c
315 * 1: pmic_at_9 sandbox_pmic
316 * 2: spl_test sandbox_spl_test
317 * 3: spl_test2 sandbox_spl_test
318 * 4: spl_test3 sandbox_spl_test
319 * --- -------------------- --------------------
320 */
321
4b91be2f
SG
322/*
323 * Node /i2c@0 index 0
324 * driver sandbox_i2c parent None
325 */
f38161c5 326static struct dtd_sandbox_i2c dtv_i2c_at_0 = {
1b27273e 327};
20e442ab 328U_BOOT_DRVINFO(i2c_at_0) = {
f38161c5 329\t.name\t\t= "sandbox_i2c",
9763e4eb 330\t.plat\t\t= &dtv_i2c_at_0,
4f50086a 331\t.plat_size\t= sizeof(dtv_i2c_at_0),
e41651ff 332\t.parent_idx\t= -1,
1b27273e
SG
333};
334
4b91be2f
SG
335/*
336 * Node /i2c@0/pmic@9 index 1
337 * driver sandbox_pmic parent sandbox_i2c
338 */
f38161c5 339static struct dtd_sandbox_pmic dtv_pmic_at_9 = {
1b27273e 340\t.low_power\t\t= true,
3e200caf 341\t.reg\t\t\t= {0x9},
1b27273e 342};
20e442ab 343U_BOOT_DRVINFO(pmic_at_9) = {
f38161c5 344\t.name\t\t= "sandbox_pmic",
9763e4eb 345\t.plat\t\t= &dtv_pmic_at_9,
4f50086a 346\t.plat_size\t= sizeof(dtv_pmic_at_9),
e41651ff 347\t.parent_idx\t= 0,
1b27273e
SG
348};
349
4b91be2f
SG
350/*
351 * Node /spl-test index 2
352 * driver sandbox_spl_test parent None
353 */
51f1263d 354static struct dtd_sandbox_spl_test dtv_spl_test = {
1953ce75 355\t.boolval\t\t= true,
c0791928
SG
356\t.bytearray\t\t= {0x6, 0x0, 0x0},
357\t.byteval\t\t= 0x5,
ca04494d 358\t.intarray\t\t= {0x2, 0x3, 0x4},
c0791928 359\t.intval\t\t\t= 0x1,
21d54ac3
SG
360\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
361\t\t0x11},
eec44c72 362\t.maybe_empty_int\t= {0x0},
1953ce75 363\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
c0791928 364\t.stringarray\t\t= {"multi-word", "message", ""},
1953ce75 365\t.stringval\t\t= "message",
c0791928 366};
20e442ab 367U_BOOT_DRVINFO(spl_test) = {
c0791928 368\t.name\t\t= "sandbox_spl_test",
9763e4eb 369\t.plat\t\t= &dtv_spl_test,
4f50086a 370\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 371\t.parent_idx\t= -1,
c0791928
SG
372};
373
4b91be2f
SG
374/*
375 * Node /spl-test2 index 3
376 * driver sandbox_spl_test parent None
377 */
51f1263d 378static struct dtd_sandbox_spl_test dtv_spl_test2 = {
f02d0eb3 379\t.acpi_name\t\t= "\\\\_SB.GPO0",
c0791928
SG
380\t.bytearray\t\t= {0x1, 0x23, 0x34},
381\t.byteval\t\t= 0x8,
ca04494d 382\t.intarray\t\t= {0x5, 0x0, 0x0},
c0791928 383\t.intval\t\t\t= 0x3,
e144cafe 384\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0x0, 0x0, 0x0, 0x0,
21d54ac3 385\t\t0x0},
c0791928 386\t.stringarray\t\t= {"another", "multi-word", "message"},
1953ce75 387\t.stringval\t\t= "message2",
c0791928 388};
20e442ab 389U_BOOT_DRVINFO(spl_test2) = {
c0791928 390\t.name\t\t= "sandbox_spl_test",
9763e4eb 391\t.plat\t\t= &dtv_spl_test2,
4f50086a 392\t.plat_size\t= sizeof(dtv_spl_test2),
e41651ff 393\t.parent_idx\t= -1,
c0791928
SG
394};
395
4b91be2f
SG
396/*
397 * Node /spl-test3 index 4
398 * driver sandbox_spl_test parent None
399 */
51f1263d 400static struct dtd_sandbox_spl_test dtv_spl_test3 = {
e144cafe
SG
401\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
402\t\t0x0},
eec44c72 403\t.maybe_empty_int\t= {0x1},
c0791928
SG
404\t.stringarray\t\t= {"one", "", ""},
405};
20e442ab 406U_BOOT_DRVINFO(spl_test3) = {
c0791928 407\t.name\t\t= "sandbox_spl_test",
9763e4eb 408\t.plat\t\t= &dtv_spl_test3,
4f50086a 409\t.plat_size\t= sizeof(dtv_spl_test3),
e41651ff 410\t.parent_idx\t= -1,
c0791928
SG
411};
412
ea74c951 413'''
ea74c951
SG
414 uclass_text_inst = '''
415
416#include <common.h>
417#include <dm.h>
418#include <dt-structs.h>
419
420/*
d392d32f
SG
421 * uclass declarations, ordered by 'struct uclass' linker_list idx:
422 * 0: i2c
423 * 1: misc
424 * 2: root
425 * 3: testbus
426 * 4: testfdt
ea74c951 427 *
d392d32f 428 * Sequence numbers allocated in each uclass:
ea74c951
SG
429 * i2c: UCLASS_I2C
430 * 4: /i2c
431 * misc: UCLASS_MISC
432 * 0: /spl-test
433 * 1: /spl-test3
434 * root: UCLASS_ROOT
435 * 0: /
436 * testbus: UCLASS_TEST_BUS
437 * 2: /some-bus
438 * testfdt: UCLASS_TEST_FDT
439 * 1: /some-bus/test
440 * 2: /some-bus/test0
441 */
442
443struct list_head uclass_head = {
444 .prev = &DM_UCLASS_REF(testfdt)->sibling_node,
445 .next = &DM_UCLASS_REF(i2c)->sibling_node,
446};
447
448DM_UCLASS_INST(i2c) = {
449 .uc_drv = DM_UCLASS_DRIVER_REF(i2c),
450 .sibling_node = {
451 .prev = &uclass_head,
452 .next = &DM_UCLASS_REF(misc)->sibling_node,
453 },
454 .dev_head = {
455 .prev = &DM_DEVICE_REF(i2c)->uclass_node,
456 .next = &DM_DEVICE_REF(i2c)->uclass_node,
457 },
458};
459
460DM_UCLASS_INST(misc) = {
461 .uc_drv = DM_UCLASS_DRIVER_REF(misc),
462 .sibling_node = {
463 .prev = &DM_UCLASS_REF(i2c)->sibling_node,
464 .next = &DM_UCLASS_REF(root)->sibling_node,
465 },
466 .dev_head = {
467 .prev = &DM_DEVICE_REF(spl_test3)->uclass_node,
468 .next = &DM_DEVICE_REF(spl_test)->uclass_node,
469 },
470};
471
472DM_UCLASS_INST(root) = {
473 .uc_drv = DM_UCLASS_DRIVER_REF(root),
474 .sibling_node = {
475 .prev = &DM_UCLASS_REF(misc)->sibling_node,
476 .next = &DM_UCLASS_REF(testbus)->sibling_node,
477 },
478 .dev_head = {
479 .prev = &DM_DEVICE_REF(root)->uclass_node,
480 .next = &DM_DEVICE_REF(root)->uclass_node,
481 },
482};
483
484DM_UCLASS_INST(testbus) = {
485 .uc_drv = DM_UCLASS_DRIVER_REF(testbus),
486 .sibling_node = {
487 .prev = &DM_UCLASS_REF(root)->sibling_node,
488 .next = &DM_UCLASS_REF(testfdt)->sibling_node,
489 },
490 .dev_head = {
491 .prev = &DM_DEVICE_REF(some_bus)->uclass_node,
492 .next = &DM_DEVICE_REF(some_bus)->uclass_node,
493 },
494};
495
496#include <dm/test.h>
497u8 _testfdt_priv_[sizeof(struct dm_test_uc_priv)]
498 __attribute__ ((section (".priv_data")));
499DM_UCLASS_INST(testfdt) = {
500 .priv_ = _testfdt_priv_,
501 .uc_drv = DM_UCLASS_DRIVER_REF(testfdt),
502 .sibling_node = {
503 .prev = &DM_UCLASS_REF(testbus)->sibling_node,
504 .next = &uclass_head,
505 },
506 .dev_head = {
507 .prev = &DM_DEVICE_REF(test0)->uclass_node,
508 .next = &DM_DEVICE_REF(test)->uclass_node,
509 },
510};
511
d392d32f
SG
512'''
513 device_text_inst = '''/*
514 * DO NOT MODIFY
515 *
516 * Declares the DM_DEVICE_INST() records.
517 * This was generated by dtoc from a .dtb (device tree binary) file.
518 */
519
520#include <common.h>
521#include <dm.h>
522#include <dt-structs.h>
523
524/*
525 * udevice declarations, ordered by 'struct udevice' linker_list position:
526 *
527 * idx udevice driver
528 * --- -------------------- --------------------
529 * 0: i2c sandbox_i2c
530 * 1: root root_driver
531 * 2: some_bus denx_u_boot_test_bus
532 * 3: spl_test sandbox_spl_test
533 * 4: spl_test3 sandbox_spl_test
534 * 5: test denx_u_boot_fdt_test
535 * 6: test0 denx_u_boot_fdt_test
536 * --- -------------------- --------------------
537 */
538
539/*
540 * Node /i2c index 0
541 * driver sandbox_i2c parent root_driver
542*/
543static struct dtd_sandbox_i2c dtv_i2c = {
544\t.intval\t\t\t= 0x3,
545};
546
547#include <asm/i2c.h>
548u8 _sandbox_i2c_priv_i2c[sizeof(struct sandbox_i2c_priv)]
549\t__attribute__ ((section (".priv_data")));
550#include <i2c.h>
551u8 _sandbox_i2c_uc_priv_i2c[sizeof(struct dm_i2c_bus)]
552\t__attribute__ ((section (".priv_data")));
553
554DM_DEVICE_INST(i2c) = {
555\t.driver\t\t= DM_DRIVER_REF(sandbox_i2c),
556\t.name\t\t= "sandbox_i2c",
557\t.plat_\t\t= &dtv_i2c,
558\t.priv_\t\t= _sandbox_i2c_priv_i2c,
559\t.uclass\t\t= DM_UCLASS_REF(i2c),
560\t.uclass_priv_ = _sandbox_i2c_uc_priv_i2c,
561\t.uclass_node\t= {
562\t\t.prev = &DM_UCLASS_REF(i2c)->dev_head,
563\t\t.next = &DM_UCLASS_REF(i2c)->dev_head,
564\t},
565\t.child_head\t= {
566\t\t.prev = &DM_DEVICE_REF(i2c)->child_head,
567\t\t.next = &DM_DEVICE_REF(i2c)->child_head,
568\t},
569\t.sibling_node\t= {
570\t\t.prev = &DM_DEVICE_REF(root)->child_head,
571\t\t.next = &DM_DEVICE_REF(some_bus)->sibling_node,
572\t},
573\t.seq_ = 4,
574};
575
576/*
577 * Node / index 1
578 * driver root_driver parent None
579*/
580static struct dtd_root_driver dtv_root = {
581};
582
583DM_DEVICE_INST(root) = {
584\t.driver\t\t= DM_DRIVER_REF(root_driver),
585\t.name\t\t= "root_driver",
586\t.plat_\t\t= &dtv_root,
587\t.uclass\t\t= DM_UCLASS_REF(root),
588\t.uclass_node\t= {
589\t\t.prev = &DM_UCLASS_REF(root)->dev_head,
590\t\t.next = &DM_UCLASS_REF(root)->dev_head,
591\t},
592\t.child_head\t= {
593\t\t.prev = &DM_DEVICE_REF(spl_test3)->sibling_node,
594\t\t.next = &DM_DEVICE_REF(i2c)->sibling_node,
595\t},
596\t.seq_ = 0,
597};
598
599/*
600 * Node /some-bus index 2
601 * driver denx_u_boot_test_bus parent root_driver
602*/
603
604#include <dm/test.h>
605struct dm_test_pdata __attribute__ ((section (".priv_data")))
606\t_denx_u_boot_test_bus_plat_some_bus = {
607\t.dtplat = {
608\t\t.ping_add\t\t= 0x4,
609\t\t.ping_expect\t\t= 0x4,
610\t\t.reg\t\t\t= {0x3, 0x1},
611\t},
612};
613#include <dm/test.h>
614u8 _denx_u_boot_test_bus_priv_some_bus[sizeof(struct dm_test_priv)]
615\t__attribute__ ((section (".priv_data")));
616#include <dm/test.h>
617u8 _denx_u_boot_test_bus_ucplat_some_bus[sizeof(struct dm_test_uclass_priv)]
618\t__attribute__ ((section (".priv_data")));
619#include <test.h>
620
621DM_DEVICE_INST(some_bus) = {
622\t.driver\t\t= DM_DRIVER_REF(denx_u_boot_test_bus),
623\t.name\t\t= "denx_u_boot_test_bus",
624\t.plat_\t\t= &_denx_u_boot_test_bus_plat_some_bus,
625\t.uclass_plat_\t= _denx_u_boot_test_bus_ucplat_some_bus,
626\t.driver_data\t= DM_TEST_TYPE_FIRST,
627\t.priv_\t\t= _denx_u_boot_test_bus_priv_some_bus,
628\t.uclass\t\t= DM_UCLASS_REF(testbus),
629\t.uclass_node\t= {
630\t\t.prev = &DM_UCLASS_REF(testbus)->dev_head,
631\t\t.next = &DM_UCLASS_REF(testbus)->dev_head,
632\t},
633\t.child_head\t= {
634\t\t.prev = &DM_DEVICE_REF(test0)->sibling_node,
635\t\t.next = &DM_DEVICE_REF(test)->sibling_node,
636\t},
637\t.sibling_node\t= {
638\t\t.prev = &DM_DEVICE_REF(i2c)->sibling_node,
639\t\t.next = &DM_DEVICE_REF(spl_test)->sibling_node,
640\t},
641\t.seq_ = 2,
642};
643
644/*
645 * Node /spl-test index 3
646 * driver sandbox_spl_test parent root_driver
647*/
648static struct dtd_sandbox_spl_test dtv_spl_test = {
649\t.boolval\t\t= true,
650\t.intval\t\t\t= 0x1,
651};
652
653DM_DEVICE_INST(spl_test) = {
654\t.driver\t\t= DM_DRIVER_REF(sandbox_spl_test),
655\t.name\t\t= "sandbox_spl_test",
656\t.plat_\t\t= &dtv_spl_test,
657\t.uclass\t\t= DM_UCLASS_REF(misc),
658\t.uclass_node\t= {
659\t\t.prev = &DM_UCLASS_REF(misc)->dev_head,
660\t\t.next = &DM_DEVICE_REF(spl_test3)->uclass_node,
661\t},
662\t.child_head\t= {
663\t\t.prev = &DM_DEVICE_REF(spl_test)->child_head,
664\t\t.next = &DM_DEVICE_REF(spl_test)->child_head,
665\t},
666\t.sibling_node\t= {
667\t\t.prev = &DM_DEVICE_REF(some_bus)->sibling_node,
668\t\t.next = &DM_DEVICE_REF(spl_test3)->sibling_node,
669\t},
670\t.seq_ = 0,
671};
672
673/*
674 * Node /spl-test3 index 4
675 * driver sandbox_spl_test parent root_driver
676*/
677static struct dtd_sandbox_spl_test dtv_spl_test3 = {
678\t.longbytearray\t\t= {0x90a0b0c, 0xd0e0f10},
679\t.stringarray\t\t= "one",
680};
681
682DM_DEVICE_INST(spl_test3) = {
683\t.driver\t\t= DM_DRIVER_REF(sandbox_spl_test),
684\t.name\t\t= "sandbox_spl_test",
685\t.plat_\t\t= &dtv_spl_test3,
686\t.uclass\t\t= DM_UCLASS_REF(misc),
687\t.uclass_node\t= {
688\t\t.prev = &DM_DEVICE_REF(spl_test)->uclass_node,
689\t\t.next = &DM_UCLASS_REF(misc)->dev_head,
690\t},
691\t.child_head\t= {
692\t\t.prev = &DM_DEVICE_REF(spl_test3)->child_head,
693\t\t.next = &DM_DEVICE_REF(spl_test3)->child_head,
694\t},
695\t.sibling_node\t= {
696\t\t.prev = &DM_DEVICE_REF(spl_test)->sibling_node,
697\t\t.next = &DM_DEVICE_REF(root)->child_head,
698\t},
699\t.seq_ = 1,
700};
701
702/*
703 * Node /some-bus/test index 5
704 * driver denx_u_boot_fdt_test parent denx_u_boot_test_bus
705*/
706
707#include <dm/test.h>
708struct dm_test_pdata __attribute__ ((section (".priv_data")))
709\t_denx_u_boot_fdt_test_plat_test = {
710\t.dtplat = {
711\t\t.ping_add\t\t= 0x5,
712\t\t.ping_expect\t\t= 0x5,
3e200caf 713\t\t.reg\t\t\t= {0x5},
d392d32f
SG
714\t},
715};
716#include <dm/test.h>
717u8 _denx_u_boot_fdt_test_priv_test[sizeof(struct dm_test_priv)]
718\t__attribute__ ((section (".priv_data")));
719#include <dm/test.h>
720u8 _denx_u_boot_fdt_test_parent_plat_test[sizeof(struct dm_test_parent_plat)]
721\t__attribute__ ((section (".priv_data")));
722#include <dm/test.h>
723u8 _denx_u_boot_fdt_test_parent_priv_test[sizeof(struct dm_test_parent_data)]
724\t__attribute__ ((section (".priv_data")));
725
726DM_DEVICE_INST(test) = {
727\t.driver\t\t= DM_DRIVER_REF(denx_u_boot_fdt_test),
728\t.name\t\t= "denx_u_boot_fdt_test",
729\t.plat_\t\t= &_denx_u_boot_fdt_test_plat_test,
730\t.parent_plat_\t= _denx_u_boot_fdt_test_parent_plat_test,
731\t.driver_data\t= DM_TEST_TYPE_FIRST,
732\t.parent\t\t= DM_DEVICE_REF(some_bus),
733\t.priv_\t\t= _denx_u_boot_fdt_test_priv_test,
734\t.uclass\t\t= DM_UCLASS_REF(testfdt),
735\t.parent_priv_\t= _denx_u_boot_fdt_test_parent_priv_test,
736\t.uclass_node\t= {
737\t\t.prev = &DM_UCLASS_REF(testfdt)->dev_head,
738\t\t.next = &DM_DEVICE_REF(test0)->uclass_node,
739\t},
740\t.child_head\t= {
741\t\t.prev = &DM_DEVICE_REF(test)->child_head,
742\t\t.next = &DM_DEVICE_REF(test)->child_head,
743\t},
744\t.sibling_node\t= {
745\t\t.prev = &DM_DEVICE_REF(some_bus)->child_head,
746\t\t.next = &DM_DEVICE_REF(test0)->sibling_node,
747\t},
748\t.seq_ = 1,
749};
750
751/*
752 * Node /some-bus/test0 index 6
753 * driver denx_u_boot_fdt_test parent denx_u_boot_test_bus
754*/
755
756#include <dm/test.h>
757struct dm_test_pdata __attribute__ ((section (".priv_data")))
758\t_denx_u_boot_fdt_test_plat_test0 = {
759\t.dtplat = {
760\t},
761};
762#include <dm/test.h>
763u8 _denx_u_boot_fdt_test_priv_test0[sizeof(struct dm_test_priv)]
764\t__attribute__ ((section (".priv_data")));
765#include <dm/test.h>
766u8 _denx_u_boot_fdt_test_parent_plat_test0[sizeof(struct dm_test_parent_plat)]
767\t__attribute__ ((section (".priv_data")));
768#include <dm/test.h>
769u8 _denx_u_boot_fdt_test_parent_priv_test0[sizeof(struct dm_test_parent_data)]
770\t__attribute__ ((section (".priv_data")));
771
772DM_DEVICE_INST(test0) = {
773\t.driver\t\t= DM_DRIVER_REF(denx_u_boot_fdt_test),
774\t.name\t\t= "denx_u_boot_fdt_test",
775\t.plat_\t\t= &_denx_u_boot_fdt_test_plat_test0,
776\t.parent_plat_\t= _denx_u_boot_fdt_test_parent_plat_test0,
777\t.driver_data\t= DM_TEST_TYPE_SECOND,
778\t.parent\t\t= DM_DEVICE_REF(some_bus),
779\t.priv_\t\t= _denx_u_boot_fdt_test_priv_test0,
780\t.uclass\t\t= DM_UCLASS_REF(testfdt),
781\t.parent_priv_\t= _denx_u_boot_fdt_test_parent_priv_test0,
782\t.uclass_node\t= {
783\t\t.prev = &DM_DEVICE_REF(test)->uclass_node,
784\t\t.next = &DM_UCLASS_REF(testfdt)->dev_head,
785\t},
786\t.child_head\t= {
787\t\t.prev = &DM_DEVICE_REF(test0)->child_head,
788\t\t.next = &DM_DEVICE_REF(test0)->child_head,
789\t},
790\t.sibling_node\t= {
791\t\t.prev = &DM_DEVICE_REF(test)->sibling_node,
792\t\t.next = &DM_DEVICE_REF(some_bus)->child_head,
793\t},
794\t.seq_ = 2,
795};
796
d960f0db 797'''
de846cbb
SG
798
799 def test_simple(self):
800 """Test output from some simple nodes with various types of data"""
801 dtb_file = get_dtb_file('dtoc_test_simple.dts')
802 output = tools.GetOutputFilename('output')
803 self.run_test(['struct'], dtb_file, output)
804 with open(output) as infile:
805 data = infile.read()
806
807 self._check_strings(self.struct_text, data)
808
809 self.run_test(['platdata'], dtb_file, output)
810 with open(output) as infile:
811 data = infile.read()
812
813 self._check_strings(self.platdata_text, data)
dac8228d 814
426d12f4
SG
815 self.run_test(['decl'], dtb_file, output)
816 with open(output) as infile:
817 data = infile.read()
818
819 self._check_strings(self.decl_text, data)
820
10cbd3b7
SG
821 # Try the 'all' command
822 self.run_test(['all'], dtb_file, output)
823 data = tools.ReadFile(output, binary=False)
d392d32f 824 self._check_strings(
17073252 825 self.decl_text + self.platdata_text + self.struct_text, data)
10cbd3b7 826
dac8228d
WL
827 def test_driver_alias(self):
828 """Test output from a device tree file with a driver alias"""
829 dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
830 output = tools.GetOutputFilename('output')
361e7335 831 self.run_test(['struct'], dtb_file, output)
dac8228d
WL
832 with open(output) as infile:
833 data = infile.read()
67b5ec54 834 self._check_strings(HEADER + '''
dac8228d
WL
835struct dtd_sandbox_gpio {
836\tconst char *\tgpio_bank_name;
837\tbool\t\tgpio_controller;
838\tfdt32_t\t\tsandbox_gpio_count;
839};
dac8228d
WL
840''', data)
841
361e7335 842 self.run_test(['platdata'], dtb_file, output)
dac8228d
WL
843 with open(output) as infile:
844 data = infile.read()
67b5ec54 845 self._check_strings(C_HEADER + '''
9763e4eb
SG
846/*
847 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
848 *
849 * idx driver_info driver
850 * --- -------------------- --------------------
851 * 0: gpios_at_0 sandbox_gpio
852 * --- -------------------- --------------------
853 */
854
4b91be2f
SG
855/*
856 * Node /gpios@0 index 0
857 * driver sandbox_gpio parent None
858 */
51f1263d 859static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
dac8228d
WL
860\t.gpio_bank_name\t\t= "a",
861\t.gpio_controller\t= true,
862\t.sandbox_gpio_count\t= 0x14,
863};
20e442ab 864U_BOOT_DRVINFO(gpios_at_0) = {
dac8228d 865\t.name\t\t= "sandbox_gpio",
9763e4eb 866\t.plat\t\t= &dtv_gpios_at_0,
4f50086a 867\t.plat_size\t= sizeof(dtv_gpios_at_0),
e41651ff 868\t.parent_idx\t= -1,
dac8228d
WL
869};
870
361e7335
WL
871''', data)
872
873 def test_invalid_driver(self):
874 """Test output from a device tree file with an invalid driver"""
875 dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts')
876 output = tools.GetOutputFilename('output')
67b5ec54 877 with test_util.capture_sys_output() as _:
4a092350
SG
878 dtb_platdata.run_steps(
879 ['struct'], dtb_file, False, output, [], None, False,
880 scan=copy_scan())
361e7335
WL
881 with open(output) as infile:
882 data = infile.read()
67b5ec54 883 self._check_strings(HEADER + '''
361e7335
WL
884struct dtd_invalid {
885};
886''', data)
887
67b5ec54 888 with test_util.capture_sys_output() as _:
4a092350
SG
889 dtb_platdata.run_steps(
890 ['platdata'], dtb_file, False, output, [], None, False,
891 scan=copy_scan())
361e7335
WL
892 with open(output) as infile:
893 data = infile.read()
67b5ec54 894 self._check_strings(C_HEADER + '''
9763e4eb
SG
895/*
896 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
897 *
898 * idx driver_info driver
899 * --- -------------------- --------------------
900 * 0: spl_test invalid
901 * --- -------------------- --------------------
902 */
903
1b27273e 904/* Node /spl-test index 0 */
51f1263d 905static struct dtd_invalid dtv_spl_test = {
361e7335 906};
20e442ab 907U_BOOT_DRVINFO(spl_test) = {
361e7335 908\t.name\t\t= "invalid",
9763e4eb 909\t.plat\t\t= &dtv_spl_test,
4f50086a 910\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 911\t.parent_idx\t= -1,
361e7335
WL
912};
913
c0791928
SG
914''', data)
915
916 def test_phandle(self):
917 """Test output from a node containing a phandle reference"""
918 dtb_file = get_dtb_file('dtoc_test_phandle.dts')
919 output = tools.GetOutputFilename('output')
361e7335 920 self.run_test(['struct'], dtb_file, output)
c0791928
SG
921 with open(output) as infile:
922 data = infile.read()
67b5ec54 923 self._check_strings(HEADER + '''
c0791928 924struct dtd_source {
634eba4b 925\tstruct phandle_2_arg clocks[4];
c0791928
SG
926};
927struct dtd_target {
928\tfdt32_t\t\tintval;
929};
930''', data)
931
361e7335 932 self.run_test(['platdata'], dtb_file, output)
c0791928
SG
933 with open(output) as infile:
934 data = infile.read()
67b5ec54 935 self._check_strings(C_HEADER + '''
9763e4eb
SG
936/*
937 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
938 *
939 * idx driver_info driver
940 * --- -------------------- --------------------
941 * 0: phandle2_target target
942 * 1: phandle3_target target
943 * 2: phandle_source source
944 * 3: phandle_source2 source
945 * 4: phandle_target target
946 * --- -------------------- --------------------
947 */
948
1b27273e 949/* Node /phandle2-target index 0 */
51f1263d 950static struct dtd_target dtv_phandle2_target = {
634eba4b
SG
951\t.intval\t\t\t= 0x1,
952};
20e442ab 953U_BOOT_DRVINFO(phandle2_target) = {
634eba4b 954\t.name\t\t= "target",
9763e4eb 955\t.plat\t\t= &dtv_phandle2_target,
4f50086a 956\t.plat_size\t= sizeof(dtv_phandle2_target),
e41651ff 957\t.parent_idx\t= -1,
634eba4b
SG
958};
959
1b27273e 960/* Node /phandle3-target index 1 */
51f1263d 961static struct dtd_target dtv_phandle3_target = {
634eba4b
SG
962\t.intval\t\t\t= 0x2,
963};
20e442ab 964U_BOOT_DRVINFO(phandle3_target) = {
634eba4b 965\t.name\t\t= "target",
9763e4eb 966\t.plat\t\t= &dtv_phandle3_target,
4f50086a 967\t.plat_size\t= sizeof(dtv_phandle3_target),
e41651ff 968\t.parent_idx\t= -1,
634eba4b
SG
969};
970
1b27273e 971/* Node /phandle-source index 2 */
51f1263d 972static struct dtd_source dtv_phandle_source = {
35d50370 973\t.clocks\t\t\t= {
8a38abfc
SG
974\t\t\t{4, {}},
975\t\t\t{0, {11}},
976\t\t\t{1, {12, 13}},
977\t\t\t{4, {}},},
c0791928 978};
20e442ab 979U_BOOT_DRVINFO(phandle_source) = {
c0791928 980\t.name\t\t= "source",
9763e4eb 981\t.plat\t\t= &dtv_phandle_source,
4f50086a 982\t.plat_size\t= sizeof(dtv_phandle_source),
e41651ff 983\t.parent_idx\t= -1,
c0791928
SG
984};
985
1b27273e 986/* Node /phandle-source2 index 3 */
51f1263d 987static struct dtd_source dtv_phandle_source2 = {
760b7170 988\t.clocks\t\t\t= {
8a38abfc 989\t\t\t{4, {}},},
760b7170 990};
20e442ab 991U_BOOT_DRVINFO(phandle_source2) = {
760b7170 992\t.name\t\t= "source",
9763e4eb 993\t.plat\t\t= &dtv_phandle_source2,
4f50086a 994\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 995\t.parent_idx\t= -1,
760b7170
SG
996};
997
9eca08dc
SG
998/* Node /phandle-target index 4 */
999static struct dtd_target dtv_phandle_target = {
1000\t.intval\t\t\t= 0x0,
1001};
1002U_BOOT_DRVINFO(phandle_target) = {
1003\t.name\t\t= "target",
9763e4eb 1004\t.plat\t\t= &dtv_phandle_target,
9eca08dc
SG
1005\t.plat_size\t= sizeof(dtv_phandle_target),
1006\t.parent_idx\t= -1,
1007};
1008
c0791928
SG
1009''', data)
1010
8512ea2e
SG
1011 def test_phandle_single(self):
1012 """Test output from a node containing a phandle reference"""
1013 dtb_file = get_dtb_file('dtoc_test_phandle_single.dts')
1014 output = tools.GetOutputFilename('output')
361e7335 1015 self.run_test(['struct'], dtb_file, output)
8512ea2e
SG
1016 with open(output) as infile:
1017 data = infile.read()
67b5ec54 1018 self._check_strings(HEADER + '''
8512ea2e
SG
1019struct dtd_source {
1020\tstruct phandle_0_arg clocks[1];
1021};
1022struct dtd_target {
1023\tfdt32_t\t\tintval;
1024};
1025''', data)
1026
1027 def test_phandle_reorder(self):
1028 """Test that phandle targets are generated before their references"""
1029 dtb_file = get_dtb_file('dtoc_test_phandle_reorder.dts')
1030 output = tools.GetOutputFilename('output')
361e7335 1031 self.run_test(['platdata'], dtb_file, output)
8512ea2e
SG
1032 with open(output) as infile:
1033 data = infile.read()
67b5ec54 1034 self._check_strings(C_HEADER + '''
9763e4eb
SG
1035/*
1036 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1037 *
1038 * idx driver_info driver
1039 * --- -------------------- --------------------
1040 * 0: phandle_source2 source
1041 * 1: phandle_target target
1042 * --- -------------------- --------------------
1043 */
1044
1b27273e 1045/* Node /phandle-source2 index 0 */
51f1263d 1046static struct dtd_source dtv_phandle_source2 = {
8512ea2e 1047\t.clocks\t\t\t= {
8a38abfc 1048\t\t\t{1, {}},},
8512ea2e 1049};
20e442ab 1050U_BOOT_DRVINFO(phandle_source2) = {
8512ea2e 1051\t.name\t\t= "source",
9763e4eb 1052\t.plat\t\t= &dtv_phandle_source2,
4f50086a 1053\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 1054\t.parent_idx\t= -1,
8512ea2e
SG
1055};
1056
9eca08dc
SG
1057/* Node /phandle-target index 1 */
1058static struct dtd_target dtv_phandle_target = {
1059};
1060U_BOOT_DRVINFO(phandle_target) = {
1061\t.name\t\t= "target",
9763e4eb 1062\t.plat\t\t= &dtv_phandle_target,
9eca08dc
SG
1063\t.plat_size\t= sizeof(dtv_phandle_target),
1064\t.parent_idx\t= -1,
1065};
1066
6c3fc50e
WL
1067''', data)
1068
1069 def test_phandle_cd_gpio(self):
1070 """Test that phandle targets are generated when unsing cd-gpios"""
1071 dtb_file = get_dtb_file('dtoc_test_phandle_cd_gpios.dts')
1072 output = tools.GetOutputFilename('output')
4a092350
SG
1073 dtb_platdata.run_steps(
1074 ['platdata'], dtb_file, False, output, [], None, False,
1075 warning_disabled=True, scan=copy_scan())
6c3fc50e
WL
1076 with open(output) as infile:
1077 data = infile.read()
67b5ec54 1078 self._check_strings(C_HEADER + '''
9763e4eb
SG
1079/*
1080 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1081 *
1082 * idx driver_info driver
1083 * --- -------------------- --------------------
1084 * 0: phandle2_target target
1085 * 1: phandle3_target target
1086 * 2: phandle_source source
1087 * 3: phandle_source2 source
1088 * 4: phandle_target target
1089 * --- -------------------- --------------------
1090 */
1091
1b27273e 1092/* Node /phandle2-target index 0 */
6c3fc50e
WL
1093static struct dtd_target dtv_phandle2_target = {
1094\t.intval\t\t\t= 0x1,
1095};
20e442ab 1096U_BOOT_DRVINFO(phandle2_target) = {
6c3fc50e 1097\t.name\t\t= "target",
9763e4eb 1098\t.plat\t\t= &dtv_phandle2_target,
4f50086a 1099\t.plat_size\t= sizeof(dtv_phandle2_target),
e41651ff 1100\t.parent_idx\t= -1,
6c3fc50e
WL
1101};
1102
1b27273e 1103/* Node /phandle3-target index 1 */
6c3fc50e
WL
1104static struct dtd_target dtv_phandle3_target = {
1105\t.intval\t\t\t= 0x2,
1106};
20e442ab 1107U_BOOT_DRVINFO(phandle3_target) = {
6c3fc50e 1108\t.name\t\t= "target",
9763e4eb 1109\t.plat\t\t= &dtv_phandle3_target,
4f50086a 1110\t.plat_size\t= sizeof(dtv_phandle3_target),
e41651ff 1111\t.parent_idx\t= -1,
6c3fc50e
WL
1112};
1113
1b27273e 1114/* Node /phandle-source index 2 */
6c3fc50e
WL
1115static struct dtd_source dtv_phandle_source = {
1116\t.cd_gpios\t\t= {
8a38abfc
SG
1117\t\t\t{4, {}},
1118\t\t\t{0, {11}},
1119\t\t\t{1, {12, 13}},
1120\t\t\t{4, {}},},
6c3fc50e 1121};
20e442ab 1122U_BOOT_DRVINFO(phandle_source) = {
6c3fc50e 1123\t.name\t\t= "source",
9763e4eb 1124\t.plat\t\t= &dtv_phandle_source,
4f50086a 1125\t.plat_size\t= sizeof(dtv_phandle_source),
e41651ff 1126\t.parent_idx\t= -1,
6c3fc50e
WL
1127};
1128
1b27273e 1129/* Node /phandle-source2 index 3 */
6c3fc50e
WL
1130static struct dtd_source dtv_phandle_source2 = {
1131\t.cd_gpios\t\t= {
8a38abfc 1132\t\t\t{4, {}},},
6c3fc50e 1133};
20e442ab 1134U_BOOT_DRVINFO(phandle_source2) = {
6c3fc50e 1135\t.name\t\t= "source",
9763e4eb 1136\t.plat\t\t= &dtv_phandle_source2,
4f50086a 1137\t.plat_size\t= sizeof(dtv_phandle_source2),
e41651ff 1138\t.parent_idx\t= -1,
9eca08dc
SG
1139};
1140
1141/* Node /phandle-target index 4 */
1142static struct dtd_target dtv_phandle_target = {
1143\t.intval\t\t\t= 0x0,
1144};
1145U_BOOT_DRVINFO(phandle_target) = {
1146\t.name\t\t= "target",
9763e4eb 1147\t.plat\t\t= &dtv_phandle_target,
9eca08dc
SG
1148\t.plat_size\t= sizeof(dtv_phandle_target),
1149\t.parent_idx\t= -1,
6c3fc50e
WL
1150};
1151
8512ea2e
SG
1152''', data)
1153
1154 def test_phandle_bad(self):
1155 """Test a node containing an invalid phandle fails"""
4b4bc06e
SG
1156 dtb_file = get_dtb_file('dtoc_test_phandle_bad.dts',
1157 capture_stderr=True)
8512ea2e 1158 output = tools.GetOutputFilename('output')
67b5ec54 1159 with self.assertRaises(ValueError) as exc:
361e7335 1160 self.run_test(['struct'], dtb_file, output)
8512ea2e 1161 self.assertIn("Cannot parse 'clocks' in node 'phandle-source'",
67b5ec54 1162 str(exc.exception))
8512ea2e
SG
1163
1164 def test_phandle_bad2(self):
1165 """Test a phandle target missing its #*-cells property"""
4b4bc06e
SG
1166 dtb_file = get_dtb_file('dtoc_test_phandle_bad2.dts',
1167 capture_stderr=True)
8512ea2e 1168 output = tools.GetOutputFilename('output')
67b5ec54 1169 with self.assertRaises(ValueError) as exc:
361e7335 1170 self.run_test(['struct'], dtb_file, output)
ad34017c 1171 self.assertIn("Node 'phandle-target' has no cells property",
67b5ec54 1172 str(exc.exception))
8512ea2e 1173
c20ee0ed
SG
1174 def test_addresses64(self):
1175 """Test output from a node with a 'reg' property with na=2, ns=2"""
1176 dtb_file = get_dtb_file('dtoc_test_addr64.dts')
1177 output = tools.GetOutputFilename('output')
361e7335 1178 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
1179 with open(output) as infile:
1180 data = infile.read()
67b5ec54 1181 self._check_strings(HEADER + '''
c20ee0ed
SG
1182struct dtd_test1 {
1183\tfdt64_t\t\treg[2];
1184};
1185struct dtd_test2 {
1186\tfdt64_t\t\treg[2];
1187};
1188struct dtd_test3 {
1189\tfdt64_t\t\treg[4];
1190};
1191''', data)
1192
361e7335 1193 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
1194 with open(output) as infile:
1195 data = infile.read()
67b5ec54 1196 self._check_strings(C_HEADER + '''
9763e4eb
SG
1197/*
1198 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1199 *
1200 * idx driver_info driver
1201 * --- -------------------- --------------------
1202 * 0: test1 test1
1203 * 1: test2 test2
1204 * 2: test3 test3
1205 * --- -------------------- --------------------
1206 */
1207
1b27273e 1208/* Node /test1 index 0 */
51f1263d 1209static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
1210\t.reg\t\t\t= {0x1234, 0x5678},
1211};
20e442ab 1212U_BOOT_DRVINFO(test1) = {
c20ee0ed 1213\t.name\t\t= "test1",
9763e4eb 1214\t.plat\t\t= &dtv_test1,
4f50086a 1215\t.plat_size\t= sizeof(dtv_test1),
e41651ff 1216\t.parent_idx\t= -1,
c20ee0ed
SG
1217};
1218
1b27273e 1219/* Node /test2 index 1 */
51f1263d 1220static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
1221\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
1222};
20e442ab 1223U_BOOT_DRVINFO(test2) = {
c20ee0ed 1224\t.name\t\t= "test2",
9763e4eb 1225\t.plat\t\t= &dtv_test2,
4f50086a 1226\t.plat_size\t= sizeof(dtv_test2),
e41651ff 1227\t.parent_idx\t= -1,
c20ee0ed
SG
1228};
1229
1b27273e 1230/* Node /test3 index 2 */
51f1263d 1231static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
1232\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
1233};
20e442ab 1234U_BOOT_DRVINFO(test3) = {
c20ee0ed 1235\t.name\t\t= "test3",
9763e4eb 1236\t.plat\t\t= &dtv_test3,
4f50086a 1237\t.plat_size\t= sizeof(dtv_test3),
e41651ff 1238\t.parent_idx\t= -1,
c20ee0ed
SG
1239};
1240
d960f0db 1241''', data)
c20ee0ed
SG
1242
1243 def test_addresses32(self):
1244 """Test output from a node with a 'reg' property with na=1, ns=1"""
1245 dtb_file = get_dtb_file('dtoc_test_addr32.dts')
1246 output = tools.GetOutputFilename('output')
361e7335 1247 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
1248 with open(output) as infile:
1249 data = infile.read()
67b5ec54 1250 self._check_strings(HEADER + '''
c20ee0ed
SG
1251struct dtd_test1 {
1252\tfdt32_t\t\treg[2];
1253};
1254struct dtd_test2 {
1255\tfdt32_t\t\treg[4];
1256};
1257''', data)
1258
361e7335 1259 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
1260 with open(output) as infile:
1261 data = infile.read()
67b5ec54 1262 self._check_strings(C_HEADER + '''
9763e4eb
SG
1263/*
1264 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1265 *
1266 * idx driver_info driver
1267 * --- -------------------- --------------------
1268 * 0: test1 test1
1269 * 1: test2 test2
1270 * --- -------------------- --------------------
1271 */
1272
1b27273e 1273/* Node /test1 index 0 */
51f1263d 1274static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
1275\t.reg\t\t\t= {0x1234, 0x5678},
1276};
20e442ab 1277U_BOOT_DRVINFO(test1) = {
c20ee0ed 1278\t.name\t\t= "test1",
9763e4eb 1279\t.plat\t\t= &dtv_test1,
4f50086a 1280\t.plat_size\t= sizeof(dtv_test1),
e41651ff 1281\t.parent_idx\t= -1,
c20ee0ed
SG
1282};
1283
1b27273e 1284/* Node /test2 index 1 */
51f1263d 1285static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
1286\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
1287};
20e442ab 1288U_BOOT_DRVINFO(test2) = {
c20ee0ed 1289\t.name\t\t= "test2",
9763e4eb 1290\t.plat\t\t= &dtv_test2,
4f50086a 1291\t.plat_size\t= sizeof(dtv_test2),
e41651ff 1292\t.parent_idx\t= -1,
c20ee0ed
SG
1293};
1294
d960f0db 1295''', data)
c20ee0ed
SG
1296
1297 def test_addresses64_32(self):
1298 """Test output from a node with a 'reg' property with na=2, ns=1"""
1299 dtb_file = get_dtb_file('dtoc_test_addr64_32.dts')
1300 output = tools.GetOutputFilename('output')
361e7335 1301 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
1302 with open(output) as infile:
1303 data = infile.read()
67b5ec54 1304 self._check_strings(HEADER + '''
c20ee0ed
SG
1305struct dtd_test1 {
1306\tfdt64_t\t\treg[2];
1307};
1308struct dtd_test2 {
1309\tfdt64_t\t\treg[2];
1310};
1311struct dtd_test3 {
1312\tfdt64_t\t\treg[4];
1313};
1314''', data)
1315
361e7335 1316 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
1317 with open(output) as infile:
1318 data = infile.read()
67b5ec54 1319 self._check_strings(C_HEADER + '''
9763e4eb
SG
1320/*
1321 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1322 *
1323 * idx driver_info driver
1324 * --- -------------------- --------------------
1325 * 0: test1 test1
1326 * 1: test2 test2
1327 * 2: test3 test3
1328 * --- -------------------- --------------------
1329 */
1330
1b27273e 1331/* Node /test1 index 0 */
51f1263d 1332static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
1333\t.reg\t\t\t= {0x123400000000, 0x5678},
1334};
20e442ab 1335U_BOOT_DRVINFO(test1) = {
c20ee0ed 1336\t.name\t\t= "test1",
9763e4eb 1337\t.plat\t\t= &dtv_test1,
4f50086a 1338\t.plat_size\t= sizeof(dtv_test1),
e41651ff 1339\t.parent_idx\t= -1,
c20ee0ed
SG
1340};
1341
1b27273e 1342/* Node /test2 index 1 */
51f1263d 1343static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
1344\t.reg\t\t\t= {0x1234567890123456, 0x98765432},
1345};
20e442ab 1346U_BOOT_DRVINFO(test2) = {
c20ee0ed 1347\t.name\t\t= "test2",
9763e4eb 1348\t.plat\t\t= &dtv_test2,
4f50086a 1349\t.plat_size\t= sizeof(dtv_test2),
e41651ff 1350\t.parent_idx\t= -1,
c20ee0ed
SG
1351};
1352
1b27273e 1353/* Node /test3 index 2 */
51f1263d 1354static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
1355\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
1356};
20e442ab 1357U_BOOT_DRVINFO(test3) = {
c20ee0ed 1358\t.name\t\t= "test3",
9763e4eb 1359\t.plat\t\t= &dtv_test3,
4f50086a 1360\t.plat_size\t= sizeof(dtv_test3),
e41651ff 1361\t.parent_idx\t= -1,
c20ee0ed
SG
1362};
1363
d960f0db 1364''', data)
c20ee0ed
SG
1365
1366 def test_addresses32_64(self):
1367 """Test output from a node with a 'reg' property with na=1, ns=2"""
1368 dtb_file = get_dtb_file('dtoc_test_addr32_64.dts')
1369 output = tools.GetOutputFilename('output')
361e7335 1370 self.run_test(['struct'], dtb_file, output)
c20ee0ed
SG
1371 with open(output) as infile:
1372 data = infile.read()
67b5ec54 1373 self._check_strings(HEADER + '''
c20ee0ed
SG
1374struct dtd_test1 {
1375\tfdt64_t\t\treg[2];
1376};
1377struct dtd_test2 {
1378\tfdt64_t\t\treg[2];
1379};
1380struct dtd_test3 {
1381\tfdt64_t\t\treg[4];
1382};
1383''', data)
1384
361e7335 1385 self.run_test(['platdata'], dtb_file, output)
c20ee0ed
SG
1386 with open(output) as infile:
1387 data = infile.read()
67b5ec54 1388 self._check_strings(C_HEADER + '''
9763e4eb
SG
1389/*
1390 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1391 *
1392 * idx driver_info driver
1393 * --- -------------------- --------------------
1394 * 0: test1 test1
1395 * 1: test2 test2
1396 * 2: test3 test3
1397 * --- -------------------- --------------------
1398 */
1399
1b27273e 1400/* Node /test1 index 0 */
51f1263d 1401static struct dtd_test1 dtv_test1 = {
c20ee0ed
SG
1402\t.reg\t\t\t= {0x1234, 0x567800000000},
1403};
20e442ab 1404U_BOOT_DRVINFO(test1) = {
c20ee0ed 1405\t.name\t\t= "test1",
9763e4eb 1406\t.plat\t\t= &dtv_test1,
4f50086a 1407\t.plat_size\t= sizeof(dtv_test1),
e41651ff 1408\t.parent_idx\t= -1,
c20ee0ed
SG
1409};
1410
1b27273e 1411/* Node /test2 index 1 */
51f1263d 1412static struct dtd_test2 dtv_test2 = {
c20ee0ed
SG
1413\t.reg\t\t\t= {0x12345678, 0x9876543210987654},
1414};
20e442ab 1415U_BOOT_DRVINFO(test2) = {
c20ee0ed 1416\t.name\t\t= "test2",
9763e4eb 1417\t.plat\t\t= &dtv_test2,
4f50086a 1418\t.plat_size\t= sizeof(dtv_test2),
e41651ff 1419\t.parent_idx\t= -1,
c20ee0ed
SG
1420};
1421
1b27273e 1422/* Node /test3 index 2 */
51f1263d 1423static struct dtd_test3 dtv_test3 = {
c20ee0ed
SG
1424\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
1425};
20e442ab 1426U_BOOT_DRVINFO(test3) = {
c20ee0ed 1427\t.name\t\t= "test3",
9763e4eb 1428\t.plat\t\t= &dtv_test3,
4f50086a 1429\t.plat_size\t= sizeof(dtv_test3),
e41651ff 1430\t.parent_idx\t= -1,
c20ee0ed
SG
1431};
1432
d960f0db 1433''', data)
8512ea2e
SG
1434
1435 def test_bad_reg(self):
1436 """Test that a reg property with an invalid type generates an error"""
fe57c784
SG
1437 # Capture stderr since dtc will emit warnings for this file
1438 dtb_file = get_dtb_file('dtoc_test_bad_reg.dts', capture_stderr=True)
8512ea2e 1439 output = tools.GetOutputFilename('output')
67b5ec54 1440 with self.assertRaises(ValueError) as exc:
361e7335 1441 self.run_test(['struct'], dtb_file, output)
8512ea2e 1442 self.assertIn("Node 'spl-test' reg property is not an int",
67b5ec54 1443 str(exc.exception))
8512ea2e
SG
1444
1445 def test_bad_reg2(self):
1446 """Test that a reg property with an invalid cell count is detected"""
fe57c784
SG
1447 # Capture stderr since dtc will emit warnings for this file
1448 dtb_file = get_dtb_file('dtoc_test_bad_reg2.dts', capture_stderr=True)
8512ea2e 1449 output = tools.GetOutputFilename('output')
67b5ec54 1450 with self.assertRaises(ValueError) as exc:
361e7335 1451 self.run_test(['struct'], dtb_file, output)
67b5ec54 1452 self.assertIn(
da393412 1453 "Node 'spl-test' (parent '/') reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
67b5ec54 1454 str(exc.exception))
8512ea2e
SG
1455
1456 def test_add_prop(self):
1457 """Test that a subequent node can add a new property to a struct"""
1458 dtb_file = get_dtb_file('dtoc_test_add_prop.dts')
1459 output = tools.GetOutputFilename('output')
361e7335 1460 self.run_test(['struct'], dtb_file, output)
8512ea2e
SG
1461 with open(output) as infile:
1462 data = infile.read()
67b5ec54 1463 self._check_strings(HEADER + '''
8512ea2e
SG
1464struct dtd_sandbox_spl_test {
1465\tfdt32_t\t\tintarray;
1466\tfdt32_t\t\tintval;
1467};
1468''', data)
1469
361e7335 1470 self.run_test(['platdata'], dtb_file, output)
8512ea2e
SG
1471 with open(output) as infile:
1472 data = infile.read()
67b5ec54 1473 self._check_strings(C_HEADER + '''
9763e4eb
SG
1474/*
1475 * driver_info declarations, ordered by 'struct driver_info' linker_list idx:
1476 *
1477 * idx driver_info driver
1478 * --- -------------------- --------------------
1479 * 0: spl_test sandbox_spl_test
1480 * 1: spl_test2 sandbox_spl_test
1481 * --- -------------------- --------------------
1482 */
1483
4b91be2f
SG
1484/*
1485 * Node /spl-test index 0
1486 * driver sandbox_spl_test parent None
1487 */
51f1263d 1488static struct dtd_sandbox_spl_test dtv_spl_test = {
8512ea2e
SG
1489\t.intval\t\t\t= 0x1,
1490};
20e442ab 1491U_BOOT_DRVINFO(spl_test) = {
8512ea2e 1492\t.name\t\t= "sandbox_spl_test",
9763e4eb 1493\t.plat\t\t= &dtv_spl_test,
4f50086a 1494\t.plat_size\t= sizeof(dtv_spl_test),
e41651ff 1495\t.parent_idx\t= -1,
8512ea2e
SG
1496};
1497
4b91be2f
SG
1498/*
1499 * Node /spl-test2 index 1
1500 * driver sandbox_spl_test parent None
1501 */
51f1263d 1502static struct dtd_sandbox_spl_test dtv_spl_test2 = {
8512ea2e
SG
1503\t.intarray\t\t= 0x5,
1504};
20e442ab 1505U_BOOT_DRVINFO(spl_test2) = {
8512ea2e 1506\t.name\t\t= "sandbox_spl_test",
9763e4eb 1507\t.plat\t\t= &dtv_spl_test2,
4f50086a 1508\t.plat_size\t= sizeof(dtv_spl_test2),
e41651ff 1509\t.parent_idx\t= -1,
8512ea2e
SG
1510};
1511
d960f0db 1512''', data)
8512ea2e 1513
67b5ec54 1514 def test_stdout(self):
8512ea2e
SG
1515 """Test output to stdout"""
1516 dtb_file = get_dtb_file('dtoc_test_simple.dts')
de846cbb 1517 with test_util.capture_sys_output() as (stdout, _):
f62cea0e 1518 self.run_test(['struct'], dtb_file, None)
de846cbb 1519 self._check_strings(self.struct_text, stdout.getvalue())
8512ea2e 1520
be44f271
SG
1521 def test_multi_to_file(self):
1522 """Test output of multiple pieces to a single file"""
1523 dtb_file = get_dtb_file('dtoc_test_simple.dts')
1524 output = tools.GetOutputFilename('output')
10cbd3b7 1525 self.run_test(['all'], dtb_file, output)
be44f271 1526 data = tools.ReadFile(output, binary=False)
d392d32f 1527 self._check_strings(
17073252 1528 self.decl_text + self.platdata_text + self.struct_text, data)
be44f271 1529
67b5ec54 1530 def test_no_command(self):
8512ea2e 1531 """Test running dtoc without a command"""
67b5ec54 1532 with self.assertRaises(ValueError) as exc:
361e7335 1533 self.run_test([], '', '')
8512ea2e 1534 self.assertIn("Please specify a command: struct, platdata",
67b5ec54 1535 str(exc.exception))
8512ea2e 1536
67b5ec54 1537 def test_bad_command(self):
8512ea2e
SG
1538 """Test running dtoc with an invalid command"""
1539 dtb_file = get_dtb_file('dtoc_test_simple.dts')
1540 output = tools.GetOutputFilename('output')
67b5ec54 1541 with self.assertRaises(ValueError) as exc:
426d12f4
SG
1542 self.run_test(['invalid-cmd'], dtb_file, output)
1543 self.assertIn(
8490c578 1544 "Unknown command 'invalid-cmd': (use: decl, platdata, struct)",
426d12f4 1545 str(exc.exception))
6c74d1b8 1546
10cbd3b7
SG
1547 def test_output_conflict(self):
1548 """Test a conflict between and output dirs and output file"""
1549 with self.assertRaises(ValueError) as exc:
4a092350
SG
1550 dtb_platdata.run_steps(
1551 ['all'], None, False, 'out', ['cdir'], None, False,
1552 warning_disabled=True, scan=copy_scan())
10cbd3b7
SG
1553 self.assertIn("Must specify either output or output_dirs, not both",
1554 str(exc.exception))
1555
17073252 1556 def check_output_dirs(self, instantiate):
10cbd3b7
SG
1557 # Remove the directory so that files from other tests are not there
1558 tools._RemoveOutputDir()
1559 tools.PrepareOutputDir(None)
1560
1561 # This should create the .dts and .dtb in the output directory
1562 dtb_file = get_dtb_file('dtoc_test_simple.dts')
1563 outdir = tools.GetOutputDir()
1564 fnames = glob.glob(outdir + '/*')
1565 self.assertEqual(2, len(fnames))
1566
4a092350 1567 dtb_platdata.run_steps(
17073252 1568 ['all'], dtb_file, False, None, [outdir], None, instantiate,
4a092350 1569 warning_disabled=True, scan=copy_scan())
10cbd3b7 1570 fnames = glob.glob(outdir + '/*')
17073252
SG
1571 return fnames
1572
1573 def test_output_dirs(self):
1574 """Test outputting files to a directory"""
1575 fnames = self.check_output_dirs(False)
1576 self.assertEqual(5, len(fnames))
10cbd3b7
SG
1577
1578 leafs = set(os.path.basename(fname) for fname in fnames)
1579 self.assertEqual(
426d12f4 1580 {'dt-structs-gen.h', 'source.dts', 'dt-plat.c', 'source.dtb',
17073252
SG
1581 'dt-decl.h'},
1582 leafs)
1583
1584 def test_output_dirs_inst(self):
1585 """Test outputting files to a directory with instantiation"""
1586 fnames = self.check_output_dirs(True)
1587 self.assertEqual(6, len(fnames))
1588
1589 leafs = set(os.path.basename(fname) for fname in fnames)
1590 self.assertEqual(
1591 {'dt-structs-gen.h', 'source.dts', 'source.dtb',
d392d32f 1592 'dt-uclass.c', 'dt-decl.h', 'dt-device.c'},
10cbd3b7 1593 leafs)
fd471e2c
SG
1594
1595 def setup_process_test(self):
1596 """Set up a test of process_nodes()
1597
1598 This uses saved_scan but returns a deep copy of it, so it is safe to
1599 modify it in these tests
1600
1601 Returns:
1602 tuple:
1603 DtbPlatdata: object to test
1604 Scanner: scanner to use
1605 """
1606 dtb_file = get_dtb_file('dtoc_test_simple.dts')
1607 output = tools.GetOutputFilename('output')
1608
1609 # Take a copy before messing with it
50aae3e6 1610 scan = copy_scan()
fd471e2c
SG
1611 plat = dtb_platdata.DtbPlatdata(scan, dtb_file, False)
1612 plat.scan_dtb()
50aae3e6 1613 plat.scan_tree(False)
fd471e2c
SG
1614 plat.prepare_nodes()
1615 return plat, scan
1616
1617 def test_process_nodes(self):
1618 """Test processing nodes to add various info"""
1619 plat, scan = self.setup_process_test()
1620 plat.process_nodes(True)
1621
1622 i2c_node = plat._fdt.GetNode('/i2c@0')
1623 pmic_node = plat._fdt.GetNode('/i2c@0/pmic@9')
1624 pmic = scan._drivers['sandbox_pmic']
1625 i2c = scan._drivers['sandbox_i2c']
1626 self.assertEqual('DM_DEVICE_REF(pmic_at_9)', pmic_node.dev_ref)
1627 self.assertEqual(pmic, pmic_node.driver)
1628 self.assertEqual(i2c_node, pmic_node.parent)
1629 self.assertEqual(i2c, pmic_node.parent_driver)
1630
1631 # The pmic is the only child
1632 self.assertEqual(pmic_node.parent_seq, 0)
1633 self.assertEqual([pmic_node], i2c_node.child_devs)
1634
1635 # Start and end of the list should be the child_head
1636 ref = '&DM_DEVICE_REF(i2c_at_0)->child_head'
1637 self.assertEqual(
1638 {-1: ref, 0: '&DM_DEVICE_REF(pmic_at_9)->sibling_node', 1: ref},
1639 i2c_node.child_refs)
1640
1641 def test_process_nodes_bad_parent(self):
1642 # Pretend that i2c has a parent (the pmic) and delete that driver
1643 plat, scan = self.setup_process_test()
1644
1645 i2c_node = plat._fdt.GetNode('/i2c@0')
1646 pmic_node = plat._fdt.GetNode('/i2c@0/pmic@9')
1647 del scan._drivers['sandbox_pmic']
1648 i2c_node.parent = pmic_node
1649
1650 # Process twice, the second time to generate an exception
1651 plat.process_nodes(False)
1652 with self.assertRaises(ValueError) as exc:
1653 plat.process_nodes(True)
1654 self.assertIn(
1655 "Cannot parse/find parent driver 'sandbox_pmic' for 'sandbox_i2c",
1656 str(exc.exception))
1657
1658 def test_process_nodes_bad_node(self):
1659 plat, scan = self.setup_process_test()
1660
1661 # Now remove the pmic driver
1662 del scan._drivers['sandbox_pmic']
1663
1664 # Process twice, the second time to generate an exception
1665 plat.process_nodes(False)
1666 with self.assertRaises(ValueError) as exc:
1667 plat.process_nodes(True)
1668 self.assertIn("Cannot parse/find driver for 'sandbox_pmic",
1669 str(exc.exception))
b9319c4f 1670
337d6972
SG
1671 def test_process_nodes_bad_uclass(self):
1672 plat, scan = self.setup_process_test()
1673
1674 self.assertIn('UCLASS_I2C', scan._uclass)
1675 del scan._uclass['UCLASS_I2C']
1676 with self.assertRaises(ValueError) as exc:
1677 plat.process_nodes(True)
1678 self.assertIn("Cannot parse/find uclass 'UCLASS_I2C' for driver 'sandbox_i2c'",
1679 str(exc.exception))
1680
b9319c4f
SG
1681 def test_process_nodes_used(self):
1682 """Test processing nodes to add various info"""
1683 plat, scan = self.setup_process_test()
1684 plat.process_nodes(True)
1685
1686 pmic = scan._drivers['sandbox_pmic']
1687 self.assertTrue(pmic.used)
1688
1689 gpio = scan._drivers['sandbox_gpio']
1690 self.assertFalse(gpio.used)
05953529
SG
1691
1692 def test_alias_read(self):
1693 """Test obtaining aliases"""
1694 dtb_file = get_dtb_file('dtoc_test_inst.dts')
1695 output = tools.GetOutputFilename('output')
1696 plat = self.run_test(['struct'], dtb_file, output)
1697
1698 scan = plat._scan
1699 testfdt_node = plat._fdt.GetNode('/some-bus/test')
337d6972 1700 test0_node = plat._fdt.GetNode('/some-bus/test0')
05953529
SG
1701 self.assertIn('UCLASS_TEST_FDT', scan._uclass)
1702 uc = scan._uclass['UCLASS_TEST_FDT']
337d6972
SG
1703 self.assertEqual({1: testfdt_node, 2: test0_node},
1704 uc.alias_num_to_node)
1705 self.assertEqual({'/some-bus/test': 1, '/some-bus/test0': 2},
1706 uc.alias_path_to_num)
05953529
SG
1707
1708 # Try adding an alias that doesn't exist
1709 self.assertFalse(scan.add_uclass_alias('fred', 3, None))
1710
1711 # Try adding an alias for a missing node
1712 self.assertIsNone(scan.add_uclass_alias('testfdt', 3, None))
1713
1714 def test_alias_read_bad(self):
1715 """Test invalid alias property name"""
1716 dtb_file = get_dtb_file('dtoc_test_alias_bad.dts')
1717 output = tools.GetOutputFilename('output')
1718 with self.assertRaises(ValueError) as exc:
1719 plat = self.run_test(['struct'], dtb_file, output)
1720 self.assertIn("Cannot decode alias 'i2c4-'", str(exc.exception))
1721
1722 def test_alias_read_bad_path(self):
1723 """Test alias pointing to a non-existent node"""
1724 # This line may produce a warning, so capture it:
1725 # Warning (alias_paths): /aliases:i2c4: aliases property is not a valid
1726 # node (/does/not/exist)
1727 dtb_file = get_dtb_file('dtoc_test_alias_bad_path.dts', True)
1728
1729 output = tools.GetOutputFilename('output')
1730 with self.assertRaises(ValueError) as exc:
1731 plat = self.run_test(['struct'], dtb_file, output)
1732 self.assertIn("Alias 'i2c4' path '/does/not/exist' not found",
1733 str(exc.exception))
1734
1735 def test_alias_read_bad_uclass(self):
1736 """Test alias for a uclass that doesn't exist"""
1737 dtb_file = get_dtb_file('dtoc_test_alias_bad_uc.dts')
1738 output = tools.GetOutputFilename('output')
1739 with test_util.capture_sys_output() as (stdout, _):
1740 plat = self.run_test(['struct'], dtb_file, output)
1741 self.assertEqual("Could not find uclass for alias 'other1'",
1742 stdout.getvalue().strip())
074197aa
SG
1743
1744 def test_sequence(self):
1745 """Test assignment of sequence numnbers"""
1746 dtb_file = get_dtb_file('dtoc_test_inst.dts')
1747 output = tools.GetOutputFilename('output')
1748 plat = self.run_test(['struct'], dtb_file, output)
337d6972
SG
1749
1750 scan = plat._scan
1751 testfdt = plat._fdt.GetNode('/some-bus/test')
1752 self.assertEqual(1, testfdt.seq)
1753 i2c = plat._fdt.GetNode('/i2c')
1754
1755 # For now this uclass is not compiled in, so no sequence is assigned
1756 self.assertEqual(4, i2c.seq)
1757 spl = plat._fdt.GetNode('/spl-test')
1758 self.assertEqual(0, spl.seq)
50aae3e6
SG
1759
1760 def test_process_root(self):
1761 """Test assignment of sequence numnbers"""
1762 dtb_file = get_dtb_file('dtoc_test_simple.dts')
1763 output = tools.GetOutputFilename('output')
1764
1765 # Take a copy before messing with it
1766 scan = copy_scan()
1767 plat = dtb_platdata.DtbPlatdata(scan, dtb_file, False)
1768 plat.scan_dtb()
1769 root = plat._fdt.GetRoot()
1770
1771 plat.scan_tree(False)
1772 self.assertNotIn(root, plat._valid_nodes)
1773
1774 plat.scan_tree(True)
1775 self.assertIn(root, plat._valid_nodes)
1776 self.assertEqual('root_driver',
1777 scan.get_normalized_compat_name(root)[0])
426d12f4
SG
1778
1779 def test_simple_inst(self):
1780 """Test output from some simple nodes with instantiate enabled"""
ea74c951 1781 dtb_file = get_dtb_file('dtoc_test_inst.dts')
426d12f4
SG
1782 output = tools.GetOutputFilename('output')
1783
1784 self.run_test(['decl'], dtb_file, output, True)
1785 with open(output) as infile:
1786 data = infile.read()
1787
1788 self._check_strings(self.decl_text_inst, data)
4b91be2f 1789
ea74c951
SG
1790 self.run_test(['uclass'], dtb_file, output, True)
1791 with open(output) as infile:
1792 data = infile.read()
1793
1794 self._check_strings(UCLASS_HEADER_COMMON + self.uclass_text_inst, data)
1795
d392d32f
SG
1796 self.run_test(['device'], dtb_file, output, True)
1797 with open(output) as infile:
1798 data = infile.read()
1799
1800 self._check_strings(self.device_text_inst, data)
1801
ea74c951 1802 def test_inst_no_hdr(self):
d392d32f 1803 """Test dealing with a struct tsssshat has no header"""
ea74c951
SG
1804 dtb_file = get_dtb_file('dtoc_test_inst.dts')
1805 output = tools.GetOutputFilename('output')
1806
1807 # Run it once to set everything up
1808 plat = self.run_test(['decl'], dtb_file, output, True)
1809 scan = plat._scan
1810
1811 # Restart the output file and delete any record of the uclass' struct
1812 plat.setup_output(Ftype.SOURCE, output)
1813 del scan._structs['dm_test_uc_priv']
1814
1815 # Now generate the uclasses, which should provide a warning
1816 with test_util.capture_sys_output() as (stdout, _):
1817 plat.generate_uclasses()
1818 self.assertEqual(
1819 'Warning: Cannot find header file for struct dm_test_uc_priv',
1820 stdout.getvalue().strip())
da393412
SG
1821
1822 def test_missing_props(self):
1823 """Test detection of a parent node with no properties"""
1824 dtb_file = get_dtb_file('dtoc_test_noprops.dts', capture_stderr=True)
1825 output = tools.GetOutputFilename('output')
1826 with self.assertRaises(ValueError) as exc:
1827 self.run_test(['struct'], dtb_file, output)
1828 self.assertIn("Parent node '/i2c@0' has no properties - do you need",
1829 str(exc.exception))
1830
1831 def test_single_reg(self):
1832 """Test detection of a parent node with no properties"""
1833 dtb_file = get_dtb_file('dtoc_test_single_reg.dts')
1834 output = tools.GetOutputFilename('output')
1835 self.run_test(['struct'], dtb_file, output)
1c56469c
SG
1836
1837 def test_missing_parent(self):
1838 """Test detection of a parent node with no properties"""
1839 dtb_file = get_dtb_file('dtoc_test_noparent.dts', capture_stderr=True)
1840 output = tools.GetOutputFilename('output')
1841 with self.assertRaises(ValueError) as exc:
1842 self.run_test(['device'], dtb_file, output, instantiate=True)
1843 self.assertIn("Node '/i2c@0/spl-test/pmic@9' requires parent node "
1844 "'/i2c@0/spl-test' but it is not in the valid list",
1845 str(exc.exception))
This page took 0.461642 seconds and 4 git commands to generate.