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