]>
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 | |
a32eb7dc | 13 | import copy |
10cbd3b7 | 14 | import glob |
c0791928 SG |
15 | import os |
16 | import struct | |
17 | import unittest | |
18 | ||
ea74c951 | 19 | from dtb_platdata import Ftype |
c0791928 SG |
20 | from dtb_platdata import get_value |
21 | from dtb_platdata import tab_to | |
67b5ec54 | 22 | from dtoc import dtb_platdata |
bf776679 SG |
23 | from dtoc import fdt |
24 | from dtoc import fdt_util | |
a32eb7dc | 25 | from dtoc import src_scan |
a542a70c SG |
26 | from dtoc.src_scan import conv_name_to_c |
27 | from dtoc.src_scan import get_compat_name | |
bf776679 SG |
28 | from patman import test_util |
29 | from patman import tools | |
c0791928 | 30 | |
67b5ec54 | 31 | OUR_PATH = os.path.dirname(os.path.realpath(__file__)) |
c0791928 SG |
32 | |
33 | ||
aab660fe SG |
34 | HEADER = '''/* |
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 |
44 | DECL_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 | 52 | C_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 | 60 | C_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 |
69 | UCLASS_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) |
78 | saved_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 | |
84 | def 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 |
98 | def 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 | ||
106 | def 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 |
111 | class 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 |
240 | extern U_BOOT_DRIVER(sandbox_i2c); |
241 | extern U_BOOT_DRIVER(sandbox_pmic); | |
242 | extern U_BOOT_DRIVER(sandbox_spl_test); | |
243 | extern U_BOOT_DRIVER(sandbox_spl_test); | |
244 | extern U_BOOT_DRIVER(sandbox_spl_test); | |
426d12f4 SG |
245 | |
246 | /* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */ | |
cff7dcf3 SG |
247 | extern UCLASS_DRIVER(i2c); |
248 | extern UCLASS_DRIVER(misc); | |
249 | extern 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 |
256 | extern U_BOOT_DRIVER(sandbox_i2c); |
257 | extern U_BOOT_DRIVER(root_driver); | |
258 | extern U_BOOT_DRIVER(denx_u_boot_test_bus); | |
259 | extern U_BOOT_DRIVER(sandbox_spl_test); | |
260 | extern U_BOOT_DRIVER(sandbox_spl_test); | |
261 | extern U_BOOT_DRIVER(denx_u_boot_fdt_test); | |
262 | extern U_BOOT_DRIVER(denx_u_boot_fdt_test); | |
426d12f4 SG |
263 | |
264 | /* device declarations - these allow DM_DEVICE_REF() to be used */ | |
cff7dcf3 SG |
265 | extern DM_DEVICE_INST(i2c); |
266 | extern DM_DEVICE_INST(root); | |
267 | extern DM_DEVICE_INST(some_bus); | |
268 | extern DM_DEVICE_INST(spl_test); | |
269 | extern DM_DEVICE_INST(spl_test3); | |
270 | extern DM_DEVICE_INST(test); | |
271 | extern DM_DEVICE_INST(test0); | |
426d12f4 SG |
272 | |
273 | /* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */ | |
cff7dcf3 SG |
274 | extern UCLASS_DRIVER(i2c); |
275 | extern UCLASS_DRIVER(misc); | |
276 | extern UCLASS_DRIVER(root); | |
277 | extern UCLASS_DRIVER(testbus); | |
278 | extern UCLASS_DRIVER(testfdt); | |
426d12f4 SG |
279 | |
280 | /* uclass declarations - needed for DM_UCLASS_REF() */ | |
cff7dcf3 SG |
281 | extern DM_UCLASS_INST(i2c); |
282 | extern DM_UCLASS_INST(misc); | |
283 | extern DM_UCLASS_INST(root); | |
284 | extern DM_UCLASS_INST(testbus); | |
285 | extern DM_UCLASS_INST(testfdt); | |
426d12f4 | 286 | ''' |
de846cbb | 287 | struct_text = HEADER + ''' |
f38161c5 | 288 | struct dtd_sandbox_i2c { |
5ec741fd | 289 | }; |
f38161c5 | 290 | struct dtd_sandbox_pmic { |
5ec741fd | 291 | \tbool\t\tlow_power; |
3e200caf | 292 | \tfdt32_t\t\treg[1]; |
5ec741fd | 293 | }; |
c0791928 | 294 | struct 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 | 326 | static struct dtd_sandbox_i2c dtv_i2c_at_0 = { |
1b27273e | 327 | }; |
20e442ab | 328 | U_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 | 339 | static 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 | 343 | U_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 | 354 | static 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 | 367 | U_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 | 378 | static 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 | 389 | U_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 | 400 | static 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 | 406 | U_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 | ||
443 | struct list_head uclass_head = { | |
444 | .prev = &DM_UCLASS_REF(testfdt)->sibling_node, | |
445 | .next = &DM_UCLASS_REF(i2c)->sibling_node, | |
446 | }; | |
447 | ||
448 | DM_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 | ||
460 | DM_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 | ||
472 | DM_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 | ||
484 | DM_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> | |
497 | u8 _testfdt_priv_[sizeof(struct dm_test_uc_priv)] | |
498 | __attribute__ ((section (".priv_data"))); | |
499 | DM_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 | */ | |
543 | static struct dtd_sandbox_i2c dtv_i2c = { | |
544 | \t.intval\t\t\t= 0x3, | |
545 | }; | |
546 | ||
547 | #include <asm/i2c.h> | |
548 | u8 _sandbox_i2c_priv_i2c[sizeof(struct sandbox_i2c_priv)] | |
549 | \t__attribute__ ((section (".priv_data"))); | |
550 | #include <i2c.h> | |
551 | u8 _sandbox_i2c_uc_priv_i2c[sizeof(struct dm_i2c_bus)] | |
552 | \t__attribute__ ((section (".priv_data"))); | |
553 | ||
554 | DM_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 | */ | |
580 | static struct dtd_root_driver dtv_root = { | |
581 | }; | |
582 | ||
583 | DM_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> | |
605 | struct 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> | |
614 | u8 _denx_u_boot_test_bus_priv_some_bus[sizeof(struct dm_test_priv)] | |
615 | \t__attribute__ ((section (".priv_data"))); | |
616 | #include <dm/test.h> | |
617 | u8 _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 | ||
621 | DM_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 | */ | |
648 | static struct dtd_sandbox_spl_test dtv_spl_test = { | |
649 | \t.boolval\t\t= true, | |
650 | \t.intval\t\t\t= 0x1, | |
651 | }; | |
652 | ||
653 | DM_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 | */ | |
677 | static struct dtd_sandbox_spl_test dtv_spl_test3 = { | |
678 | \t.longbytearray\t\t= {0x90a0b0c, 0xd0e0f10}, | |
679 | \t.stringarray\t\t= "one", | |
680 | }; | |
681 | ||
682 | DM_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> | |
708 | struct 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> | |
717 | u8 _denx_u_boot_fdt_test_priv_test[sizeof(struct dm_test_priv)] | |
718 | \t__attribute__ ((section (".priv_data"))); | |
719 | #include <dm/test.h> | |
720 | u8 _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> | |
723 | u8 _denx_u_boot_fdt_test_parent_priv_test[sizeof(struct dm_test_parent_data)] | |
724 | \t__attribute__ ((section (".priv_data"))); | |
725 | ||
726 | DM_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> | |
757 | struct 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> | |
763 | u8 _denx_u_boot_fdt_test_priv_test0[sizeof(struct dm_test_priv)] | |
764 | \t__attribute__ ((section (".priv_data"))); | |
765 | #include <dm/test.h> | |
766 | u8 _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> | |
769 | u8 _denx_u_boot_fdt_test_parent_priv_test0[sizeof(struct dm_test_parent_data)] | |
770 | \t__attribute__ ((section (".priv_data"))); | |
771 | ||
772 | DM_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 |
835 | struct 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 | 859 | static 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 | 864 | U_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 |
884 | struct 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 | 905 | static struct dtd_invalid dtv_spl_test = { |
361e7335 | 906 | }; |
20e442ab | 907 | U_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 | 924 | struct dtd_source { |
634eba4b | 925 | \tstruct phandle_2_arg clocks[4]; |
c0791928 SG |
926 | }; |
927 | struct 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 | 950 | static struct dtd_target dtv_phandle2_target = { |
634eba4b SG |
951 | \t.intval\t\t\t= 0x1, |
952 | }; | |
20e442ab | 953 | U_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 | 961 | static struct dtd_target dtv_phandle3_target = { |
634eba4b SG |
962 | \t.intval\t\t\t= 0x2, |
963 | }; | |
20e442ab | 964 | U_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 | 972 | static 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 | 979 | U_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 | 987 | static struct dtd_source dtv_phandle_source2 = { |
760b7170 | 988 | \t.clocks\t\t\t= { |
8a38abfc | 989 | \t\t\t{4, {}},}, |
760b7170 | 990 | }; |
20e442ab | 991 | U_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 */ |
999 | static struct dtd_target dtv_phandle_target = { | |
1000 | \t.intval\t\t\t= 0x0, | |
1001 | }; | |
1002 | U_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 |
1019 | struct dtd_source { |
1020 | \tstruct phandle_0_arg clocks[1]; | |
1021 | }; | |
1022 | struct 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 | 1046 | static struct dtd_source dtv_phandle_source2 = { |
8512ea2e | 1047 | \t.clocks\t\t\t= { |
8a38abfc | 1048 | \t\t\t{1, {}},}, |
8512ea2e | 1049 | }; |
20e442ab | 1050 | U_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 */ |
1058 | static struct dtd_target dtv_phandle_target = { | |
1059 | }; | |
1060 | U_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 |
1093 | static struct dtd_target dtv_phandle2_target = { |
1094 | \t.intval\t\t\t= 0x1, | |
1095 | }; | |
20e442ab | 1096 | U_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 |
1104 | static struct dtd_target dtv_phandle3_target = { |
1105 | \t.intval\t\t\t= 0x2, | |
1106 | }; | |
20e442ab | 1107 | U_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 |
1115 | static 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 | 1122 | U_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 |
1130 | static struct dtd_source dtv_phandle_source2 = { |
1131 | \t.cd_gpios\t\t= { | |
8a38abfc | 1132 | \t\t\t{4, {}},}, |
6c3fc50e | 1133 | }; |
20e442ab | 1134 | U_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 */ | |
1142 | static struct dtd_target dtv_phandle_target = { | |
1143 | \t.intval\t\t\t= 0x0, | |
1144 | }; | |
1145 | U_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 |
1182 | struct dtd_test1 { |
1183 | \tfdt64_t\t\treg[2]; | |
1184 | }; | |
1185 | struct dtd_test2 { | |
1186 | \tfdt64_t\t\treg[2]; | |
1187 | }; | |
1188 | struct 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 | 1209 | static struct dtd_test1 dtv_test1 = { |
c20ee0ed SG |
1210 | \t.reg\t\t\t= {0x1234, 0x5678}, |
1211 | }; | |
20e442ab | 1212 | U_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 | 1220 | static struct dtd_test2 dtv_test2 = { |
c20ee0ed SG |
1221 | \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654}, |
1222 | }; | |
20e442ab | 1223 | U_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 | 1231 | static struct dtd_test3 dtv_test3 = { |
c20ee0ed SG |
1232 | \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3}, |
1233 | }; | |
20e442ab | 1234 | U_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 |
1251 | struct dtd_test1 { |
1252 | \tfdt32_t\t\treg[2]; | |
1253 | }; | |
1254 | struct 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 | 1274 | static struct dtd_test1 dtv_test1 = { |
c20ee0ed SG |
1275 | \t.reg\t\t\t= {0x1234, 0x5678}, |
1276 | }; | |
20e442ab | 1277 | U_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 | 1285 | static struct dtd_test2 dtv_test2 = { |
c20ee0ed SG |
1286 | \t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3}, |
1287 | }; | |
20e442ab | 1288 | U_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 |
1305 | struct dtd_test1 { |
1306 | \tfdt64_t\t\treg[2]; | |
1307 | }; | |
1308 | struct dtd_test2 { | |
1309 | \tfdt64_t\t\treg[2]; | |
1310 | }; | |
1311 | struct 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 | 1332 | static struct dtd_test1 dtv_test1 = { |
c20ee0ed SG |
1333 | \t.reg\t\t\t= {0x123400000000, 0x5678}, |
1334 | }; | |
20e442ab | 1335 | U_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 | 1343 | static struct dtd_test2 dtv_test2 = { |
c20ee0ed SG |
1344 | \t.reg\t\t\t= {0x1234567890123456, 0x98765432}, |
1345 | }; | |
20e442ab | 1346 | U_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 | 1354 | static struct dtd_test3 dtv_test3 = { |
c20ee0ed SG |
1355 | \t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3}, |
1356 | }; | |
20e442ab | 1357 | U_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 |
1374 | struct dtd_test1 { |
1375 | \tfdt64_t\t\treg[2]; | |
1376 | }; | |
1377 | struct dtd_test2 { | |
1378 | \tfdt64_t\t\treg[2]; | |
1379 | }; | |
1380 | struct 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 | 1401 | static struct dtd_test1 dtv_test1 = { |
c20ee0ed SG |
1402 | \t.reg\t\t\t= {0x1234, 0x567800000000}, |
1403 | }; | |
20e442ab | 1404 | U_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 | 1412 | static struct dtd_test2 dtv_test2 = { |
c20ee0ed SG |
1413 | \t.reg\t\t\t= {0x12345678, 0x9876543210987654}, |
1414 | }; | |
20e442ab | 1415 | U_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 | 1423 | static struct dtd_test3 dtv_test3 = { |
c20ee0ed SG |
1424 | \t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3}, |
1425 | }; | |
20e442ab | 1426 | U_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 |
1464 | struct 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 | 1488 | static struct dtd_sandbox_spl_test dtv_spl_test = { |
8512ea2e SG |
1489 | \t.intval\t\t\t= 0x1, |
1490 | }; | |
20e442ab | 1491 | U_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 | 1502 | static struct dtd_sandbox_spl_test dtv_spl_test2 = { |
8512ea2e SG |
1503 | \t.intarray\t\t= 0x5, |
1504 | }; | |
20e442ab | 1505 | U_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)) |