blob: 8e8dd847c1094a3ef5114a15593742319fd406f8 [file] [log] [blame]
Simon Glass3c19dc82019-10-31 07:42:55 -06001#!/usr/bin/env python3
Tom Rini83d290c2018-05-06 17:58:06 -04002# SPDX-License-Identifier: GPL-2.0+
Simon Glassc0791922017-06-18 22:09:06 -06003# Copyright (c) 2012 The Chromium OS Authors.
4#
Simon Glassc0791922017-06-18 22:09:06 -06005
6"""Tests for the dtb_platdata module
7
Simon Glass3def0cf2018-07-06 10:27:20 -06008This includes unit tests for some functions and functional tests for the dtoc
9tool.
Simon Glassc0791922017-06-18 22:09:06 -060010"""
11
12import collections
Simon Glass10cbd3b2020-12-28 20:34:52 -070013import glob
Simon Glassc0791922017-06-18 22:09:06 -060014import os
Simon Glass1e0f3f42020-12-28 20:35:03 -070015import shutil
Simon Glassc0791922017-06-18 22:09:06 -060016import struct
Walter Lozano6c74d1b2020-07-28 19:06:23 -030017import tempfile
Simon Glassc0791922017-06-18 22:09:06 -060018import unittest
Simon Glass1e0f3f42020-12-28 20:35:03 -070019from unittest import mock
Simon Glassc0791922017-06-18 22:09:06 -060020
Simon Glassc0791922017-06-18 22:09:06 -060021from dtb_platdata import get_value
22from dtb_platdata import tab_to
Simon Glass67b5ec52020-12-28 20:34:47 -070023from dtoc import dtb_platdata
Simon Glassbf776672020-04-17 18:09:04 -060024from dtoc import fdt
25from dtoc import fdt_util
Simon Glassa542a702020-12-28 20:35:06 -070026from dtoc import src_scan
27from dtoc.src_scan import conv_name_to_c
28from dtoc.src_scan import get_compat_name
Simon Glassbf776672020-04-17 18:09:04 -060029from patman import test_util
30from patman import tools
Simon Glassc0791922017-06-18 22:09:06 -060031
Simon Glass67b5ec52020-12-28 20:34:47 -070032OUR_PATH = os.path.dirname(os.path.realpath(__file__))
Simon Glassc0791922017-06-18 22:09:06 -060033
34
Simon Glassaab660f2017-11-12 21:52:17 -070035HEADER = '''/*
36 * DO NOT MODIFY
37 *
Simon Glassd1055d62020-12-28 20:35:00 -070038 * Defines the structs used to hold devicetree data.
39 * This was generated by dtoc from a .dtb (device tree binary) file.
Simon Glassaab660f2017-11-12 21:52:17 -070040 */
41
42#include <stdbool.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090043#include <linux/libfdt.h>'''
Simon Glassaab660f2017-11-12 21:52:17 -070044
45C_HEADER = '''/*
46 * DO NOT MODIFY
47 *
Simon Glassd1055d62020-12-28 20:35:00 -070048 * Declares the U_BOOT_DRIVER() records and platform data.
49 * This was generated by dtoc from a .dtb (device tree binary) file.
Simon Glassaab660f2017-11-12 21:52:17 -070050 */
51
Simon Glass20e442a2020-12-28 20:34:54 -070052/* Allow use of U_BOOT_DRVINFO() in this file */
Simon Glassf31fa992020-12-28 20:35:01 -070053#define DT_PLAT_C
Simon Glasscb43ac12020-10-03 11:31:41 -060054
Simon Glassaab660f2017-11-12 21:52:17 -070055#include <common.h>
56#include <dm.h>
57#include <dt-structs.h>
58'''
59
Simon Glass67b5ec52020-12-28 20:34:47 -070060# This is a test so is allowed to access private things in the module it is
61# testing
62# pylint: disable=W0212
Simon Glassfe57c782018-07-06 10:27:37 -060063
64def get_dtb_file(dts_fname, capture_stderr=False):
Simon Glassc0791922017-06-18 22:09:06 -060065 """Compile a .dts file to a .dtb
66
67 Args:
Simon Glass67b5ec52020-12-28 20:34:47 -070068 dts_fname (str): Filename of .dts file in the current directory
69 capture_stderr (bool): True to capture and discard stderr output
Simon Glassc0791922017-06-18 22:09:06 -060070
71 Returns:
Simon Glass67b5ec52020-12-28 20:34:47 -070072 str: Filename of compiled file in output directory
Simon Glassc0791922017-06-18 22:09:06 -060073 """
Simon Glass67b5ec52020-12-28 20:34:47 -070074 return fdt_util.EnsureCompiled(os.path.join(OUR_PATH, dts_fname),
Simon Glassfe57c782018-07-06 10:27:37 -060075 capture_stderr=capture_stderr)
Simon Glassc0791922017-06-18 22:09:06 -060076
77
78class TestDtoc(unittest.TestCase):
79 """Tests for dtoc"""
80 @classmethod
81 def setUpClass(cls):
82 tools.PrepareOutputDir(None)
Simon Glassf02d0eb2020-07-07 21:32:06 -060083 cls.maxDiff = None
Simon Glassc0791922017-06-18 22:09:06 -060084
85 @classmethod
86 def tearDownClass(cls):
Simon Glass67b5ec52020-12-28 20:34:47 -070087 tools.FinaliseOutputDir()
Simon Glassc0791922017-06-18 22:09:06 -060088
Simon Glass67b5ec52020-12-28 20:34:47 -070089 @staticmethod
90 def _write_python_string(fname, data):
Simon Glass57f0bc42018-07-06 10:27:25 -060091 """Write a string with tabs expanded as done in this Python file
92
93 Args:
Simon Glass67b5ec52020-12-28 20:34:47 -070094 fname (str): Filename to write to
95 data (str): Raw string to convert
Simon Glass57f0bc42018-07-06 10:27:25 -060096 """
97 data = data.replace('\t', '\\t')
Simon Glass67b5ec52020-12-28 20:34:47 -070098 with open(fname, 'w') as fout:
99 fout.write(data)
Simon Glass57f0bc42018-07-06 10:27:25 -0600100
Simon Glass67b5ec52020-12-28 20:34:47 -0700101 def _check_strings(self, expected, actual):
Simon Glass57f0bc42018-07-06 10:27:25 -0600102 """Check that a string matches its expected value
103
104 If the strings do not match, they are written to the /tmp directory in
105 the same Python format as is used here in the test. This allows for
106 easy comparison and update of the tests.
107
108 Args:
Simon Glass67b5ec52020-12-28 20:34:47 -0700109 expected (str): Expected string
110 actual (str): Actual string
Simon Glass57f0bc42018-07-06 10:27:25 -0600111 """
112 if expected != actual:
Simon Glass67b5ec52020-12-28 20:34:47 -0700113 self._write_python_string('/tmp/binman.expected', expected)
114 self._write_python_string('/tmp/binman.actual', actual)
Simon Glass90a81322019-05-17 22:00:31 -0600115 print('Failures written to /tmp/binman.{expected,actual}')
Simon Glass67b5ec52020-12-28 20:34:47 -0700116 self.assertEqual(expected, actual)
Simon Glass57f0bc42018-07-06 10:27:25 -0600117
Simon Glass67b5ec52020-12-28 20:34:47 -0700118 @staticmethod
119 def run_test(args, dtb_file, output):
120 """Run a test using dtoc
Walter Lozano361e7332020-06-25 01:10:08 -0300121
Simon Glass67b5ec52020-12-28 20:34:47 -0700122 Args:
123 args (list of str): List of arguments for dtoc
124 dtb_file (str): Filename of .dtb file
125 output (str): Filename of output file
126 """
Simon Glass192c1112020-12-28 20:34:50 -0700127 dtb_platdata.run_steps(args, dtb_file, False, output, [], True)
Walter Lozano361e7332020-06-25 01:10:08 -0300128
Simon Glassc0791922017-06-18 22:09:06 -0600129 def test_name(self):
130 """Test conversion of device tree names to C identifiers"""
131 self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
132 self.assertEqual('vendor_clock_frequency',
133 conv_name_to_c('vendor,clock-frequency'))
134 self.assertEqual('rockchip_rk3399_sdhci_5_1',
135 conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
136
137 def test_tab_to(self):
138 """Test operation of tab_to() function"""
139 self.assertEqual('fred ', tab_to(0, 'fred'))
140 self.assertEqual('fred\t', tab_to(1, 'fred'))
141 self.assertEqual('fred was here ', tab_to(1, 'fred was here'))
142 self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here'))
143 self.assertEqual('exactly8 ', tab_to(1, 'exactly8'))
144 self.assertEqual('exactly8\t', tab_to(2, 'exactly8'))
145
146 def test_get_value(self):
147 """Test operation of get_value() function"""
148 self.assertEqual('0x45',
Simon Glass5ea9dcc2020-11-08 20:36:17 -0700149 get_value(fdt.Type.INT, struct.pack('>I', 0x45)))
Simon Glassc0791922017-06-18 22:09:06 -0600150 self.assertEqual('0x45',
Simon Glass5ea9dcc2020-11-08 20:36:17 -0700151 get_value(fdt.Type.BYTE, struct.pack('<I', 0x45)))
Simon Glassc0791922017-06-18 22:09:06 -0600152 self.assertEqual('0x0',
Simon Glass5ea9dcc2020-11-08 20:36:17 -0700153 get_value(fdt.Type.BYTE, struct.pack('>I', 0x45)))
154 self.assertEqual('"test"', get_value(fdt.Type.STRING, 'test'))
155 self.assertEqual('true', get_value(fdt.Type.BOOL, None))
Simon Glassc0791922017-06-18 22:09:06 -0600156
157 def test_get_compat_name(self):
158 """Test operation of get_compat_name() function"""
159 Prop = collections.namedtuple('Prop', ['value'])
160 Node = collections.namedtuple('Node', ['props'])
161
162 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1'])
163 node = Node({'compatible': prop})
Walter Lozanodcb3ed62020-07-23 00:22:03 -0300164 self.assertEqual((['rockchip_rk3399_sdhci_5_1', 'arasan_sdhci_5_1']),
Simon Glassc0791922017-06-18 22:09:06 -0600165 get_compat_name(node))
166
167 prop = Prop(['rockchip,rk3399-sdhci-5.1'])
168 node = Node({'compatible': prop})
Walter Lozanodcb3ed62020-07-23 00:22:03 -0300169 self.assertEqual((['rockchip_rk3399_sdhci_5_1']),
Simon Glassc0791922017-06-18 22:09:06 -0600170 get_compat_name(node))
171
172 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third'])
173 node = Node({'compatible': prop})
Walter Lozanodcb3ed62020-07-23 00:22:03 -0300174 self.assertEqual((['rockchip_rk3399_sdhci_5_1',
Simon Glass67b5ec52020-12-28 20:34:47 -0700175 'arasan_sdhci_5_1', 'third']),
Simon Glassc0791922017-06-18 22:09:06 -0600176 get_compat_name(node))
177
178 def test_empty_file(self):
179 """Test output from a device tree file with no nodes"""
180 dtb_file = get_dtb_file('dtoc_test_empty.dts')
181 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300182 self.run_test(['struct'], dtb_file, output)
Simon Glassc0791922017-06-18 22:09:06 -0600183 with open(output) as infile:
184 lines = infile.read().splitlines()
Simon Glassaab660f2017-11-12 21:52:17 -0700185 self.assertEqual(HEADER.splitlines(), lines)
Simon Glassc0791922017-06-18 22:09:06 -0600186
Walter Lozano361e7332020-06-25 01:10:08 -0300187 self.run_test(['platdata'], dtb_file, output)
Simon Glassc0791922017-06-18 22:09:06 -0600188 with open(output) as infile:
189 lines = infile.read().splitlines()
Simon Glassd960f0d2020-12-28 20:35:05 -0700190 self.assertEqual(C_HEADER.splitlines() + [''], lines)
Simon Glassc0791922017-06-18 22:09:06 -0600191
Simon Glassde846cb2020-12-28 20:34:49 -0700192 struct_text = HEADER + '''
Simon Glass5ec741f2017-08-29 14:15:51 -0600193struct dtd_sandbox_i2c_test {
194};
195struct dtd_sandbox_pmic_test {
196\tbool\t\tlow_power;
197\tfdt64_t\t\treg[2];
198};
Simon Glassc0791922017-06-18 22:09:06 -0600199struct dtd_sandbox_spl_test {
Simon Glassf02d0eb2020-07-07 21:32:06 -0600200\tconst char * acpi_name;
Simon Glassc0791922017-06-18 22:09:06 -0600201\tbool\t\tboolval;
202\tunsigned char\tbytearray[3];
203\tunsigned char\tbyteval;
204\tfdt32_t\t\tintarray[4];
205\tfdt32_t\t\tintval;
206\tunsigned char\tlongbytearray[9];
Simon Glass2a2d91d2018-07-06 10:27:28 -0600207\tunsigned char\tnotstring[5];
Simon Glassc0791922017-06-18 22:09:06 -0600208\tconst char *\tstringarray[3];
209\tconst char *\tstringval;
210};
Simon Glassde846cb2020-12-28 20:34:49 -0700211'''
Simon Glassc0791922017-06-18 22:09:06 -0600212
Simon Glassde846cb2020-12-28 20:34:49 -0700213 platdata_text = C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600214/* Node /i2c@0 index 0 */
215static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
216};
Simon Glass20e442a2020-12-28 20:34:54 -0700217U_BOOT_DRVINFO(i2c_at_0) = {
Simon Glass1b272732020-10-03 11:31:25 -0600218\t.name\t\t= "sandbox_i2c_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700219\t.plat\t= &dtv_i2c_at_0,
Simon Glass4f500862020-12-03 16:55:19 -0700220\t.plat_size\t= sizeof(dtv_i2c_at_0),
Simon Glasse41651f2020-10-03 11:31:35 -0600221\t.parent_idx\t= -1,
Simon Glass1b272732020-10-03 11:31:25 -0600222};
223
224/* Node /i2c@0/pmic@9 index 1 */
225static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
226\t.low_power\t\t= true,
227\t.reg\t\t\t= {0x9, 0x0},
228};
Simon Glass20e442a2020-12-28 20:34:54 -0700229U_BOOT_DRVINFO(pmic_at_9) = {
Simon Glass1b272732020-10-03 11:31:25 -0600230\t.name\t\t= "sandbox_pmic_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700231\t.plat\t= &dtv_pmic_at_9,
Simon Glass4f500862020-12-03 16:55:19 -0700232\t.plat_size\t= sizeof(dtv_pmic_at_9),
Simon Glasse41651f2020-10-03 11:31:35 -0600233\t.parent_idx\t= 0,
Simon Glass1b272732020-10-03 11:31:25 -0600234};
235
236/* Node /spl-test index 2 */
Walter Lozano51f12632020-06-25 01:10:13 -0300237static struct dtd_sandbox_spl_test dtv_spl_test = {
Simon Glass1953ce72019-05-17 22:00:32 -0600238\t.boolval\t\t= true,
Simon Glassc0791922017-06-18 22:09:06 -0600239\t.bytearray\t\t= {0x6, 0x0, 0x0},
240\t.byteval\t\t= 0x5,
Simon Glass1953ce72019-05-17 22:00:32 -0600241\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
Simon Glassc0791922017-06-18 22:09:06 -0600242\t.intval\t\t\t= 0x1,
Simon Glass21d54ac2017-08-29 14:15:49 -0600243\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
244\t\t0x11},
Simon Glass1953ce72019-05-17 22:00:32 -0600245\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
Simon Glassc0791922017-06-18 22:09:06 -0600246\t.stringarray\t\t= {"multi-word", "message", ""},
Simon Glass1953ce72019-05-17 22:00:32 -0600247\t.stringval\t\t= "message",
Simon Glassc0791922017-06-18 22:09:06 -0600248};
Simon Glass20e442a2020-12-28 20:34:54 -0700249U_BOOT_DRVINFO(spl_test) = {
Simon Glassc0791922017-06-18 22:09:06 -0600250\t.name\t\t= "sandbox_spl_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700251\t.plat\t= &dtv_spl_test,
Simon Glass4f500862020-12-03 16:55:19 -0700252\t.plat_size\t= sizeof(dtv_spl_test),
Simon Glasse41651f2020-10-03 11:31:35 -0600253\t.parent_idx\t= -1,
Simon Glassc0791922017-06-18 22:09:06 -0600254};
255
Simon Glass1b272732020-10-03 11:31:25 -0600256/* Node /spl-test2 index 3 */
Walter Lozano51f12632020-06-25 01:10:13 -0300257static struct dtd_sandbox_spl_test dtv_spl_test2 = {
Simon Glassf02d0eb2020-07-07 21:32:06 -0600258\t.acpi_name\t\t= "\\\\_SB.GPO0",
Simon Glassc0791922017-06-18 22:09:06 -0600259\t.bytearray\t\t= {0x1, 0x23, 0x34},
260\t.byteval\t\t= 0x8,
Simon Glass1953ce72019-05-17 22:00:32 -0600261\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
Simon Glassc0791922017-06-18 22:09:06 -0600262\t.intval\t\t\t= 0x3,
Simon Glasse144caf2020-10-03 11:31:27 -0600263\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0x0, 0x0, 0x0, 0x0,
Simon Glass21d54ac2017-08-29 14:15:49 -0600264\t\t0x0},
Simon Glassc0791922017-06-18 22:09:06 -0600265\t.stringarray\t\t= {"another", "multi-word", "message"},
Simon Glass1953ce72019-05-17 22:00:32 -0600266\t.stringval\t\t= "message2",
Simon Glassc0791922017-06-18 22:09:06 -0600267};
Simon Glass20e442a2020-12-28 20:34:54 -0700268U_BOOT_DRVINFO(spl_test2) = {
Simon Glassc0791922017-06-18 22:09:06 -0600269\t.name\t\t= "sandbox_spl_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700270\t.plat\t= &dtv_spl_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700271\t.plat_size\t= sizeof(dtv_spl_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600272\t.parent_idx\t= -1,
Simon Glassc0791922017-06-18 22:09:06 -0600273};
274
Simon Glass1b272732020-10-03 11:31:25 -0600275/* Node /spl-test3 index 4 */
Walter Lozano51f12632020-06-25 01:10:13 -0300276static struct dtd_sandbox_spl_test dtv_spl_test3 = {
Simon Glasse144caf2020-10-03 11:31:27 -0600277\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
278\t\t0x0},
Simon Glassc0791922017-06-18 22:09:06 -0600279\t.stringarray\t\t= {"one", "", ""},
280};
Simon Glass20e442a2020-12-28 20:34:54 -0700281U_BOOT_DRVINFO(spl_test3) = {
Simon Glassc0791922017-06-18 22:09:06 -0600282\t.name\t\t= "sandbox_spl_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700283\t.plat\t= &dtv_spl_test3,
Simon Glass4f500862020-12-03 16:55:19 -0700284\t.plat_size\t= sizeof(dtv_spl_test3),
Simon Glasse41651f2020-10-03 11:31:35 -0600285\t.parent_idx\t= -1,
Simon Glassc0791922017-06-18 22:09:06 -0600286};
287
Simon Glassd960f0d2020-12-28 20:35:05 -0700288'''
Simon Glassde846cb2020-12-28 20:34:49 -0700289
290 def test_simple(self):
291 """Test output from some simple nodes with various types of data"""
292 dtb_file = get_dtb_file('dtoc_test_simple.dts')
293 output = tools.GetOutputFilename('output')
294 self.run_test(['struct'], dtb_file, output)
295 with open(output) as infile:
296 data = infile.read()
297
298 self._check_strings(self.struct_text, data)
299
300 self.run_test(['platdata'], dtb_file, output)
301 with open(output) as infile:
302 data = infile.read()
303
304 self._check_strings(self.platdata_text, data)
Simon Glassc0791922017-06-18 22:09:06 -0600305
Simon Glass10cbd3b2020-12-28 20:34:52 -0700306 # Try the 'all' command
307 self.run_test(['all'], dtb_file, output)
308 data = tools.ReadFile(output, binary=False)
309 self._check_strings(self.platdata_text + self.struct_text, data)
310
Walter Lozanodac82282020-07-03 08:07:17 -0300311 def test_driver_alias(self):
312 """Test output from a device tree file with a driver alias"""
313 dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
314 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300315 self.run_test(['struct'], dtb_file, output)
Walter Lozanodac82282020-07-03 08:07:17 -0300316 with open(output) as infile:
317 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700318 self._check_strings(HEADER + '''
Walter Lozanodac82282020-07-03 08:07:17 -0300319struct dtd_sandbox_gpio {
320\tconst char *\tgpio_bank_name;
321\tbool\t\tgpio_controller;
322\tfdt32_t\t\tsandbox_gpio_count;
323};
Walter Lozanodac82282020-07-03 08:07:17 -0300324''', data)
325
Walter Lozano361e7332020-06-25 01:10:08 -0300326 self.run_test(['platdata'], dtb_file, output)
Walter Lozanodac82282020-07-03 08:07:17 -0300327 with open(output) as infile:
328 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700329 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600330/* Node /gpios@0 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300331static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
Walter Lozanodac82282020-07-03 08:07:17 -0300332\t.gpio_bank_name\t\t= "a",
333\t.gpio_controller\t= true,
334\t.sandbox_gpio_count\t= 0x14,
335};
Simon Glass20e442a2020-12-28 20:34:54 -0700336U_BOOT_DRVINFO(gpios_at_0) = {
Walter Lozanodac82282020-07-03 08:07:17 -0300337\t.name\t\t= "sandbox_gpio",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700338\t.plat\t= &dtv_gpios_at_0,
Simon Glass4f500862020-12-03 16:55:19 -0700339\t.plat_size\t= sizeof(dtv_gpios_at_0),
Simon Glasse41651f2020-10-03 11:31:35 -0600340\t.parent_idx\t= -1,
Walter Lozanodac82282020-07-03 08:07:17 -0300341};
342
343''', data)
344
Walter Lozano361e7332020-06-25 01:10:08 -0300345 def test_invalid_driver(self):
346 """Test output from a device tree file with an invalid driver"""
347 dtb_file = get_dtb_file('dtoc_test_invalid_driver.dts')
348 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700349 with test_util.capture_sys_output() as _:
Simon Glass192c1112020-12-28 20:34:50 -0700350 dtb_platdata.run_steps(['struct'], dtb_file, False, output, [])
Walter Lozano361e7332020-06-25 01:10:08 -0300351 with open(output) as infile:
352 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700353 self._check_strings(HEADER + '''
Walter Lozano361e7332020-06-25 01:10:08 -0300354struct dtd_invalid {
355};
356''', data)
357
Simon Glass67b5ec52020-12-28 20:34:47 -0700358 with test_util.capture_sys_output() as _:
Simon Glass192c1112020-12-28 20:34:50 -0700359 dtb_platdata.run_steps(['platdata'], dtb_file, False, output, [])
Walter Lozano361e7332020-06-25 01:10:08 -0300360 with open(output) as infile:
361 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700362 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600363/* Node /spl-test index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300364static struct dtd_invalid dtv_spl_test = {
Walter Lozano361e7332020-06-25 01:10:08 -0300365};
Simon Glass20e442a2020-12-28 20:34:54 -0700366U_BOOT_DRVINFO(spl_test) = {
Walter Lozano361e7332020-06-25 01:10:08 -0300367\t.name\t\t= "invalid",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700368\t.plat\t= &dtv_spl_test,
Simon Glass4f500862020-12-03 16:55:19 -0700369\t.plat_size\t= sizeof(dtv_spl_test),
Simon Glasse41651f2020-10-03 11:31:35 -0600370\t.parent_idx\t= -1,
Walter Lozano361e7332020-06-25 01:10:08 -0300371};
372
373''', data)
374
Simon Glassc0791922017-06-18 22:09:06 -0600375 def test_phandle(self):
376 """Test output from a node containing a phandle reference"""
377 dtb_file = get_dtb_file('dtoc_test_phandle.dts')
378 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300379 self.run_test(['struct'], dtb_file, output)
Simon Glassc0791922017-06-18 22:09:06 -0600380 with open(output) as infile:
381 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700382 self._check_strings(HEADER + '''
Simon Glassc0791922017-06-18 22:09:06 -0600383struct dtd_source {
Simon Glass634eba42017-08-29 14:15:59 -0600384\tstruct phandle_2_arg clocks[4];
Simon Glassc0791922017-06-18 22:09:06 -0600385};
386struct dtd_target {
387\tfdt32_t\t\tintval;
388};
389''', data)
390
Walter Lozano361e7332020-06-25 01:10:08 -0300391 self.run_test(['platdata'], dtb_file, output)
Simon Glassc0791922017-06-18 22:09:06 -0600392 with open(output) as infile:
393 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700394 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600395/* Node /phandle2-target index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300396static struct dtd_target dtv_phandle2_target = {
Simon Glass634eba42017-08-29 14:15:59 -0600397\t.intval\t\t\t= 0x1,
398};
Simon Glass20e442a2020-12-28 20:34:54 -0700399U_BOOT_DRVINFO(phandle2_target) = {
Simon Glass634eba42017-08-29 14:15:59 -0600400\t.name\t\t= "target",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700401\t.plat\t= &dtv_phandle2_target,
Simon Glass4f500862020-12-03 16:55:19 -0700402\t.plat_size\t= sizeof(dtv_phandle2_target),
Simon Glasse41651f2020-10-03 11:31:35 -0600403\t.parent_idx\t= -1,
Simon Glass634eba42017-08-29 14:15:59 -0600404};
405
Simon Glass1b272732020-10-03 11:31:25 -0600406/* Node /phandle3-target index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300407static struct dtd_target dtv_phandle3_target = {
Simon Glass634eba42017-08-29 14:15:59 -0600408\t.intval\t\t\t= 0x2,
409};
Simon Glass20e442a2020-12-28 20:34:54 -0700410U_BOOT_DRVINFO(phandle3_target) = {
Simon Glass634eba42017-08-29 14:15:59 -0600411\t.name\t\t= "target",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700412\t.plat\t= &dtv_phandle3_target,
Simon Glass4f500862020-12-03 16:55:19 -0700413\t.plat_size\t= sizeof(dtv_phandle3_target),
Simon Glasse41651f2020-10-03 11:31:35 -0600414\t.parent_idx\t= -1,
Simon Glass634eba42017-08-29 14:15:59 -0600415};
416
Simon Glass1b272732020-10-03 11:31:25 -0600417/* Node /phandle-source index 2 */
Walter Lozano51f12632020-06-25 01:10:13 -0300418static struct dtd_source dtv_phandle_source = {
Simon Glass35d50372017-08-29 14:15:57 -0600419\t.clocks\t\t\t= {
Simon Glass8a38abf2020-10-03 11:31:40 -0600420\t\t\t{4, {}},
421\t\t\t{0, {11}},
422\t\t\t{1, {12, 13}},
423\t\t\t{4, {}},},
Simon Glassc0791922017-06-18 22:09:06 -0600424};
Simon Glass20e442a2020-12-28 20:34:54 -0700425U_BOOT_DRVINFO(phandle_source) = {
Simon Glassc0791922017-06-18 22:09:06 -0600426\t.name\t\t= "source",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700427\t.plat\t= &dtv_phandle_source,
Simon Glass4f500862020-12-03 16:55:19 -0700428\t.plat_size\t= sizeof(dtv_phandle_source),
Simon Glasse41651f2020-10-03 11:31:35 -0600429\t.parent_idx\t= -1,
Simon Glassc0791922017-06-18 22:09:06 -0600430};
431
Simon Glass1b272732020-10-03 11:31:25 -0600432/* Node /phandle-source2 index 3 */
Walter Lozano51f12632020-06-25 01:10:13 -0300433static struct dtd_source dtv_phandle_source2 = {
Simon Glass760b7172018-07-06 10:27:31 -0600434\t.clocks\t\t\t= {
Simon Glass8a38abf2020-10-03 11:31:40 -0600435\t\t\t{4, {}},},
Simon Glass760b7172018-07-06 10:27:31 -0600436};
Simon Glass20e442a2020-12-28 20:34:54 -0700437U_BOOT_DRVINFO(phandle_source2) = {
Simon Glass760b7172018-07-06 10:27:31 -0600438\t.name\t\t= "source",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700439\t.plat\t= &dtv_phandle_source2,
Simon Glass4f500862020-12-03 16:55:19 -0700440\t.plat_size\t= sizeof(dtv_phandle_source2),
Simon Glasse41651f2020-10-03 11:31:35 -0600441\t.parent_idx\t= -1,
Simon Glass760b7172018-07-06 10:27:31 -0600442};
443
Simon Glass9eca08d2020-12-28 20:35:04 -0700444/* Node /phandle-target index 4 */
445static struct dtd_target dtv_phandle_target = {
446\t.intval\t\t\t= 0x0,
447};
448U_BOOT_DRVINFO(phandle_target) = {
449\t.name\t\t= "target",
450\t.plat\t= &dtv_phandle_target,
451\t.plat_size\t= sizeof(dtv_phandle_target),
452\t.parent_idx\t= -1,
453};
454
Simon Glassc0791922017-06-18 22:09:06 -0600455''', data)
456
Simon Glass8512ea22018-07-06 10:27:35 -0600457 def test_phandle_single(self):
458 """Test output from a node containing a phandle reference"""
459 dtb_file = get_dtb_file('dtoc_test_phandle_single.dts')
460 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300461 self.run_test(['struct'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600462 with open(output) as infile:
463 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700464 self._check_strings(HEADER + '''
Simon Glass8512ea22018-07-06 10:27:35 -0600465struct dtd_source {
466\tstruct phandle_0_arg clocks[1];
467};
468struct dtd_target {
469\tfdt32_t\t\tintval;
470};
471''', data)
472
473 def test_phandle_reorder(self):
474 """Test that phandle targets are generated before their references"""
475 dtb_file = get_dtb_file('dtoc_test_phandle_reorder.dts')
476 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300477 self.run_test(['platdata'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600478 with open(output) as infile:
479 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700480 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600481/* Node /phandle-source2 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300482static struct dtd_source dtv_phandle_source2 = {
Simon Glass8512ea22018-07-06 10:27:35 -0600483\t.clocks\t\t\t= {
Simon Glass8a38abf2020-10-03 11:31:40 -0600484\t\t\t{1, {}},},
Simon Glass8512ea22018-07-06 10:27:35 -0600485};
Simon Glass20e442a2020-12-28 20:34:54 -0700486U_BOOT_DRVINFO(phandle_source2) = {
Simon Glass8512ea22018-07-06 10:27:35 -0600487\t.name\t\t= "source",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700488\t.plat\t= &dtv_phandle_source2,
Simon Glass4f500862020-12-03 16:55:19 -0700489\t.plat_size\t= sizeof(dtv_phandle_source2),
Simon Glasse41651f2020-10-03 11:31:35 -0600490\t.parent_idx\t= -1,
Simon Glass8512ea22018-07-06 10:27:35 -0600491};
492
Simon Glass9eca08d2020-12-28 20:35:04 -0700493/* Node /phandle-target index 1 */
494static struct dtd_target dtv_phandle_target = {
495};
496U_BOOT_DRVINFO(phandle_target) = {
497\t.name\t\t= "target",
498\t.plat\t= &dtv_phandle_target,
499\t.plat_size\t= sizeof(dtv_phandle_target),
500\t.parent_idx\t= -1,
501};
502
Simon Glass8512ea22018-07-06 10:27:35 -0600503''', data)
504
Walter Lozano6c3fc502020-06-25 01:10:17 -0300505 def test_phandle_cd_gpio(self):
506 """Test that phandle targets are generated when unsing cd-gpios"""
507 dtb_file = get_dtb_file('dtoc_test_phandle_cd_gpios.dts')
508 output = tools.GetOutputFilename('output')
Simon Glass192c1112020-12-28 20:34:50 -0700509 dtb_platdata.run_steps(['platdata'], dtb_file, False, output, [], True)
Walter Lozano6c3fc502020-06-25 01:10:17 -0300510 with open(output) as infile:
511 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700512 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600513/* Node /phandle2-target index 0 */
Walter Lozano6c3fc502020-06-25 01:10:17 -0300514static struct dtd_target dtv_phandle2_target = {
515\t.intval\t\t\t= 0x1,
516};
Simon Glass20e442a2020-12-28 20:34:54 -0700517U_BOOT_DRVINFO(phandle2_target) = {
Walter Lozano6c3fc502020-06-25 01:10:17 -0300518\t.name\t\t= "target",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700519\t.plat\t= &dtv_phandle2_target,
Simon Glass4f500862020-12-03 16:55:19 -0700520\t.plat_size\t= sizeof(dtv_phandle2_target),
Simon Glasse41651f2020-10-03 11:31:35 -0600521\t.parent_idx\t= -1,
Walter Lozano6c3fc502020-06-25 01:10:17 -0300522};
523
Simon Glass1b272732020-10-03 11:31:25 -0600524/* Node /phandle3-target index 1 */
Walter Lozano6c3fc502020-06-25 01:10:17 -0300525static struct dtd_target dtv_phandle3_target = {
526\t.intval\t\t\t= 0x2,
527};
Simon Glass20e442a2020-12-28 20:34:54 -0700528U_BOOT_DRVINFO(phandle3_target) = {
Walter Lozano6c3fc502020-06-25 01:10:17 -0300529\t.name\t\t= "target",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700530\t.plat\t= &dtv_phandle3_target,
Simon Glass4f500862020-12-03 16:55:19 -0700531\t.plat_size\t= sizeof(dtv_phandle3_target),
Simon Glasse41651f2020-10-03 11:31:35 -0600532\t.parent_idx\t= -1,
Walter Lozano6c3fc502020-06-25 01:10:17 -0300533};
534
Simon Glass1b272732020-10-03 11:31:25 -0600535/* Node /phandle-source index 2 */
Walter Lozano6c3fc502020-06-25 01:10:17 -0300536static struct dtd_source dtv_phandle_source = {
537\t.cd_gpios\t\t= {
Simon Glass8a38abf2020-10-03 11:31:40 -0600538\t\t\t{4, {}},
539\t\t\t{0, {11}},
540\t\t\t{1, {12, 13}},
541\t\t\t{4, {}},},
Walter Lozano6c3fc502020-06-25 01:10:17 -0300542};
Simon Glass20e442a2020-12-28 20:34:54 -0700543U_BOOT_DRVINFO(phandle_source) = {
Walter Lozano6c3fc502020-06-25 01:10:17 -0300544\t.name\t\t= "source",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700545\t.plat\t= &dtv_phandle_source,
Simon Glass4f500862020-12-03 16:55:19 -0700546\t.plat_size\t= sizeof(dtv_phandle_source),
Simon Glasse41651f2020-10-03 11:31:35 -0600547\t.parent_idx\t= -1,
Walter Lozano6c3fc502020-06-25 01:10:17 -0300548};
549
Simon Glass1b272732020-10-03 11:31:25 -0600550/* Node /phandle-source2 index 3 */
Walter Lozano6c3fc502020-06-25 01:10:17 -0300551static struct dtd_source dtv_phandle_source2 = {
552\t.cd_gpios\t\t= {
Simon Glass8a38abf2020-10-03 11:31:40 -0600553\t\t\t{4, {}},},
Walter Lozano6c3fc502020-06-25 01:10:17 -0300554};
Simon Glass20e442a2020-12-28 20:34:54 -0700555U_BOOT_DRVINFO(phandle_source2) = {
Walter Lozano6c3fc502020-06-25 01:10:17 -0300556\t.name\t\t= "source",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700557\t.plat\t= &dtv_phandle_source2,
Simon Glass4f500862020-12-03 16:55:19 -0700558\t.plat_size\t= sizeof(dtv_phandle_source2),
Simon Glasse41651f2020-10-03 11:31:35 -0600559\t.parent_idx\t= -1,
Walter Lozano6c3fc502020-06-25 01:10:17 -0300560};
561
Simon Glass9eca08d2020-12-28 20:35:04 -0700562/* Node /phandle-target index 4 */
563static struct dtd_target dtv_phandle_target = {
564\t.intval\t\t\t= 0x0,
565};
566U_BOOT_DRVINFO(phandle_target) = {
567\t.name\t\t= "target",
568\t.plat\t= &dtv_phandle_target,
569\t.plat_size\t= sizeof(dtv_phandle_target),
570\t.parent_idx\t= -1,
571};
572
Walter Lozano6c3fc502020-06-25 01:10:17 -0300573''', data)
574
Simon Glass8512ea22018-07-06 10:27:35 -0600575 def test_phandle_bad(self):
576 """Test a node containing an invalid phandle fails"""
Simon Glass4b4bc062018-10-01 21:12:43 -0600577 dtb_file = get_dtb_file('dtoc_test_phandle_bad.dts',
578 capture_stderr=True)
Simon Glass8512ea22018-07-06 10:27:35 -0600579 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700580 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300581 self.run_test(['struct'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600582 self.assertIn("Cannot parse 'clocks' in node 'phandle-source'",
Simon Glass67b5ec52020-12-28 20:34:47 -0700583 str(exc.exception))
Simon Glass8512ea22018-07-06 10:27:35 -0600584
585 def test_phandle_bad2(self):
586 """Test a phandle target missing its #*-cells property"""
Simon Glass4b4bc062018-10-01 21:12:43 -0600587 dtb_file = get_dtb_file('dtoc_test_phandle_bad2.dts',
588 capture_stderr=True)
Simon Glass8512ea22018-07-06 10:27:35 -0600589 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700590 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300591 self.run_test(['struct'], dtb_file, output)
Walter Lozanoad340172020-06-25 01:10:16 -0300592 self.assertIn("Node 'phandle-target' has no cells property",
Simon Glass67b5ec52020-12-28 20:34:47 -0700593 str(exc.exception))
Simon Glass8512ea22018-07-06 10:27:35 -0600594
Simon Glassc20ee0e2017-08-29 14:15:50 -0600595 def test_addresses64(self):
596 """Test output from a node with a 'reg' property with na=2, ns=2"""
597 dtb_file = get_dtb_file('dtoc_test_addr64.dts')
598 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300599 self.run_test(['struct'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600600 with open(output) as infile:
601 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700602 self._check_strings(HEADER + '''
Simon Glassc20ee0e2017-08-29 14:15:50 -0600603struct dtd_test1 {
604\tfdt64_t\t\treg[2];
605};
606struct dtd_test2 {
607\tfdt64_t\t\treg[2];
608};
609struct dtd_test3 {
610\tfdt64_t\t\treg[4];
611};
612''', data)
613
Walter Lozano361e7332020-06-25 01:10:08 -0300614 self.run_test(['platdata'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600615 with open(output) as infile:
616 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700617 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600618/* Node /test1 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300619static struct dtd_test1 dtv_test1 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600620\t.reg\t\t\t= {0x1234, 0x5678},
621};
Simon Glass20e442a2020-12-28 20:34:54 -0700622U_BOOT_DRVINFO(test1) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600623\t.name\t\t= "test1",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700624\t.plat\t= &dtv_test1,
Simon Glass4f500862020-12-03 16:55:19 -0700625\t.plat_size\t= sizeof(dtv_test1),
Simon Glasse41651f2020-10-03 11:31:35 -0600626\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600627};
628
Simon Glass1b272732020-10-03 11:31:25 -0600629/* Node /test2 index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300630static struct dtd_test2 dtv_test2 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600631\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
632};
Simon Glass20e442a2020-12-28 20:34:54 -0700633U_BOOT_DRVINFO(test2) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600634\t.name\t\t= "test2",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700635\t.plat\t= &dtv_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700636\t.plat_size\t= sizeof(dtv_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600637\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600638};
639
Simon Glass1b272732020-10-03 11:31:25 -0600640/* Node /test3 index 2 */
Walter Lozano51f12632020-06-25 01:10:13 -0300641static struct dtd_test3 dtv_test3 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600642\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
643};
Simon Glass20e442a2020-12-28 20:34:54 -0700644U_BOOT_DRVINFO(test3) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600645\t.name\t\t= "test3",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700646\t.plat\t= &dtv_test3,
Simon Glass4f500862020-12-03 16:55:19 -0700647\t.plat_size\t= sizeof(dtv_test3),
Simon Glasse41651f2020-10-03 11:31:35 -0600648\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600649};
650
Simon Glassd960f0d2020-12-28 20:35:05 -0700651''', data)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600652
653 def test_addresses32(self):
654 """Test output from a node with a 'reg' property with na=1, ns=1"""
655 dtb_file = get_dtb_file('dtoc_test_addr32.dts')
656 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300657 self.run_test(['struct'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600658 with open(output) as infile:
659 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700660 self._check_strings(HEADER + '''
Simon Glassc20ee0e2017-08-29 14:15:50 -0600661struct dtd_test1 {
662\tfdt32_t\t\treg[2];
663};
664struct dtd_test2 {
665\tfdt32_t\t\treg[4];
666};
667''', data)
668
Walter Lozano361e7332020-06-25 01:10:08 -0300669 self.run_test(['platdata'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600670 with open(output) as infile:
671 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700672 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600673/* Node /test1 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300674static struct dtd_test1 dtv_test1 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600675\t.reg\t\t\t= {0x1234, 0x5678},
676};
Simon Glass20e442a2020-12-28 20:34:54 -0700677U_BOOT_DRVINFO(test1) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600678\t.name\t\t= "test1",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700679\t.plat\t= &dtv_test1,
Simon Glass4f500862020-12-03 16:55:19 -0700680\t.plat_size\t= sizeof(dtv_test1),
Simon Glasse41651f2020-10-03 11:31:35 -0600681\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600682};
683
Simon Glass1b272732020-10-03 11:31:25 -0600684/* Node /test2 index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300685static struct dtd_test2 dtv_test2 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600686\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
687};
Simon Glass20e442a2020-12-28 20:34:54 -0700688U_BOOT_DRVINFO(test2) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600689\t.name\t\t= "test2",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700690\t.plat\t= &dtv_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700691\t.plat_size\t= sizeof(dtv_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600692\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600693};
694
Simon Glassd960f0d2020-12-28 20:35:05 -0700695''', data)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600696
697 def test_addresses64_32(self):
698 """Test output from a node with a 'reg' property with na=2, ns=1"""
699 dtb_file = get_dtb_file('dtoc_test_addr64_32.dts')
700 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300701 self.run_test(['struct'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600702 with open(output) as infile:
703 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700704 self._check_strings(HEADER + '''
Simon Glassc20ee0e2017-08-29 14:15:50 -0600705struct dtd_test1 {
706\tfdt64_t\t\treg[2];
707};
708struct dtd_test2 {
709\tfdt64_t\t\treg[2];
710};
711struct dtd_test3 {
712\tfdt64_t\t\treg[4];
713};
714''', data)
715
Walter Lozano361e7332020-06-25 01:10:08 -0300716 self.run_test(['platdata'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600717 with open(output) as infile:
718 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700719 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600720/* Node /test1 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300721static struct dtd_test1 dtv_test1 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600722\t.reg\t\t\t= {0x123400000000, 0x5678},
723};
Simon Glass20e442a2020-12-28 20:34:54 -0700724U_BOOT_DRVINFO(test1) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600725\t.name\t\t= "test1",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700726\t.plat\t= &dtv_test1,
Simon Glass4f500862020-12-03 16:55:19 -0700727\t.plat_size\t= sizeof(dtv_test1),
Simon Glasse41651f2020-10-03 11:31:35 -0600728\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600729};
730
Simon Glass1b272732020-10-03 11:31:25 -0600731/* Node /test2 index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300732static struct dtd_test2 dtv_test2 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600733\t.reg\t\t\t= {0x1234567890123456, 0x98765432},
734};
Simon Glass20e442a2020-12-28 20:34:54 -0700735U_BOOT_DRVINFO(test2) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600736\t.name\t\t= "test2",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700737\t.plat\t= &dtv_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700738\t.plat_size\t= sizeof(dtv_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600739\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600740};
741
Simon Glass1b272732020-10-03 11:31:25 -0600742/* Node /test3 index 2 */
Walter Lozano51f12632020-06-25 01:10:13 -0300743static struct dtd_test3 dtv_test3 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600744\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
745};
Simon Glass20e442a2020-12-28 20:34:54 -0700746U_BOOT_DRVINFO(test3) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600747\t.name\t\t= "test3",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700748\t.plat\t= &dtv_test3,
Simon Glass4f500862020-12-03 16:55:19 -0700749\t.plat_size\t= sizeof(dtv_test3),
Simon Glasse41651f2020-10-03 11:31:35 -0600750\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600751};
752
Simon Glassd960f0d2020-12-28 20:35:05 -0700753''', data)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600754
755 def test_addresses32_64(self):
756 """Test output from a node with a 'reg' property with na=1, ns=2"""
757 dtb_file = get_dtb_file('dtoc_test_addr32_64.dts')
758 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300759 self.run_test(['struct'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600760 with open(output) as infile:
761 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700762 self._check_strings(HEADER + '''
Simon Glassc20ee0e2017-08-29 14:15:50 -0600763struct dtd_test1 {
764\tfdt64_t\t\treg[2];
765};
766struct dtd_test2 {
767\tfdt64_t\t\treg[2];
768};
769struct dtd_test3 {
770\tfdt64_t\t\treg[4];
771};
772''', data)
773
Walter Lozano361e7332020-06-25 01:10:08 -0300774 self.run_test(['platdata'], dtb_file, output)
Simon Glassc20ee0e2017-08-29 14:15:50 -0600775 with open(output) as infile:
776 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700777 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600778/* Node /test1 index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300779static struct dtd_test1 dtv_test1 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600780\t.reg\t\t\t= {0x1234, 0x567800000000},
781};
Simon Glass20e442a2020-12-28 20:34:54 -0700782U_BOOT_DRVINFO(test1) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600783\t.name\t\t= "test1",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700784\t.plat\t= &dtv_test1,
Simon Glass4f500862020-12-03 16:55:19 -0700785\t.plat_size\t= sizeof(dtv_test1),
Simon Glasse41651f2020-10-03 11:31:35 -0600786\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600787};
788
Simon Glass1b272732020-10-03 11:31:25 -0600789/* Node /test2 index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300790static struct dtd_test2 dtv_test2 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600791\t.reg\t\t\t= {0x12345678, 0x9876543210987654},
792};
Simon Glass20e442a2020-12-28 20:34:54 -0700793U_BOOT_DRVINFO(test2) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600794\t.name\t\t= "test2",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700795\t.plat\t= &dtv_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700796\t.plat_size\t= sizeof(dtv_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600797\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600798};
799
Simon Glass1b272732020-10-03 11:31:25 -0600800/* Node /test3 index 2 */
Walter Lozano51f12632020-06-25 01:10:13 -0300801static struct dtd_test3 dtv_test3 = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600802\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
803};
Simon Glass20e442a2020-12-28 20:34:54 -0700804U_BOOT_DRVINFO(test3) = {
Simon Glassc20ee0e2017-08-29 14:15:50 -0600805\t.name\t\t= "test3",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700806\t.plat\t= &dtv_test3,
Simon Glass4f500862020-12-03 16:55:19 -0700807\t.plat_size\t= sizeof(dtv_test3),
Simon Glasse41651f2020-10-03 11:31:35 -0600808\t.parent_idx\t= -1,
Simon Glassc20ee0e2017-08-29 14:15:50 -0600809};
810
Simon Glassd960f0d2020-12-28 20:35:05 -0700811''', data)
Simon Glass8512ea22018-07-06 10:27:35 -0600812
813 def test_bad_reg(self):
814 """Test that a reg property with an invalid type generates an error"""
Simon Glassfe57c782018-07-06 10:27:37 -0600815 # Capture stderr since dtc will emit warnings for this file
816 dtb_file = get_dtb_file('dtoc_test_bad_reg.dts', capture_stderr=True)
Simon Glass8512ea22018-07-06 10:27:35 -0600817 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700818 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300819 self.run_test(['struct'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600820 self.assertIn("Node 'spl-test' reg property is not an int",
Simon Glass67b5ec52020-12-28 20:34:47 -0700821 str(exc.exception))
Simon Glass8512ea22018-07-06 10:27:35 -0600822
823 def test_bad_reg2(self):
824 """Test that a reg property with an invalid cell count is detected"""
Simon Glassfe57c782018-07-06 10:27:37 -0600825 # Capture stderr since dtc will emit warnings for this file
826 dtb_file = get_dtb_file('dtoc_test_bad_reg2.dts', capture_stderr=True)
Simon Glass8512ea22018-07-06 10:27:35 -0600827 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700828 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300829 self.run_test(['struct'], dtb_file, output)
Simon Glass67b5ec52020-12-28 20:34:47 -0700830 self.assertIn(
831 "Node 'spl-test' reg property has 3 cells which is not a multiple of na + ns = 1 + 1)",
832 str(exc.exception))
Simon Glass8512ea22018-07-06 10:27:35 -0600833
834 def test_add_prop(self):
835 """Test that a subequent node can add a new property to a struct"""
836 dtb_file = get_dtb_file('dtoc_test_add_prop.dts')
837 output = tools.GetOutputFilename('output')
Walter Lozano361e7332020-06-25 01:10:08 -0300838 self.run_test(['struct'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600839 with open(output) as infile:
840 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700841 self._check_strings(HEADER + '''
Simon Glass8512ea22018-07-06 10:27:35 -0600842struct dtd_sandbox_spl_test {
843\tfdt32_t\t\tintarray;
844\tfdt32_t\t\tintval;
845};
846''', data)
847
Walter Lozano361e7332020-06-25 01:10:08 -0300848 self.run_test(['platdata'], dtb_file, output)
Simon Glass8512ea22018-07-06 10:27:35 -0600849 with open(output) as infile:
850 data = infile.read()
Simon Glass67b5ec52020-12-28 20:34:47 -0700851 self._check_strings(C_HEADER + '''
Simon Glass1b272732020-10-03 11:31:25 -0600852/* Node /spl-test index 0 */
Walter Lozano51f12632020-06-25 01:10:13 -0300853static struct dtd_sandbox_spl_test dtv_spl_test = {
Simon Glass8512ea22018-07-06 10:27:35 -0600854\t.intval\t\t\t= 0x1,
855};
Simon Glass20e442a2020-12-28 20:34:54 -0700856U_BOOT_DRVINFO(spl_test) = {
Simon Glass8512ea22018-07-06 10:27:35 -0600857\t.name\t\t= "sandbox_spl_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700858\t.plat\t= &dtv_spl_test,
Simon Glass4f500862020-12-03 16:55:19 -0700859\t.plat_size\t= sizeof(dtv_spl_test),
Simon Glasse41651f2020-10-03 11:31:35 -0600860\t.parent_idx\t= -1,
Simon Glass8512ea22018-07-06 10:27:35 -0600861};
862
Simon Glass1b272732020-10-03 11:31:25 -0600863/* Node /spl-test2 index 1 */
Walter Lozano51f12632020-06-25 01:10:13 -0300864static struct dtd_sandbox_spl_test dtv_spl_test2 = {
Simon Glass8512ea22018-07-06 10:27:35 -0600865\t.intarray\t\t= 0x5,
866};
Simon Glass20e442a2020-12-28 20:34:54 -0700867U_BOOT_DRVINFO(spl_test2) = {
Simon Glass8512ea22018-07-06 10:27:35 -0600868\t.name\t\t= "sandbox_spl_test",
Simon Glasscaa4daa2020-12-03 16:55:18 -0700869\t.plat\t= &dtv_spl_test2,
Simon Glass4f500862020-12-03 16:55:19 -0700870\t.plat_size\t= sizeof(dtv_spl_test2),
Simon Glasse41651f2020-10-03 11:31:35 -0600871\t.parent_idx\t= -1,
Simon Glass8512ea22018-07-06 10:27:35 -0600872};
873
Simon Glassd960f0d2020-12-28 20:35:05 -0700874''', data)
Simon Glass8512ea22018-07-06 10:27:35 -0600875
Simon Glass67b5ec52020-12-28 20:34:47 -0700876 def test_stdout(self):
Simon Glass8512ea22018-07-06 10:27:35 -0600877 """Test output to stdout"""
878 dtb_file = get_dtb_file('dtoc_test_simple.dts')
Simon Glassde846cb2020-12-28 20:34:49 -0700879 with test_util.capture_sys_output() as (stdout, _):
Simon Glassf62cea02020-12-28 20:34:48 -0700880 self.run_test(['struct'], dtb_file, None)
Simon Glassde846cb2020-12-28 20:34:49 -0700881 self._check_strings(self.struct_text, stdout.getvalue())
Simon Glass8512ea22018-07-06 10:27:35 -0600882
Simon Glassbe44f272020-12-28 20:34:51 -0700883 def test_multi_to_file(self):
884 """Test output of multiple pieces to a single file"""
885 dtb_file = get_dtb_file('dtoc_test_simple.dts')
886 output = tools.GetOutputFilename('output')
Simon Glass10cbd3b2020-12-28 20:34:52 -0700887 self.run_test(['all'], dtb_file, output)
Simon Glassbe44f272020-12-28 20:34:51 -0700888 data = tools.ReadFile(output, binary=False)
Simon Glass10cbd3b2020-12-28 20:34:52 -0700889 self._check_strings(self.platdata_text + self.struct_text, data)
Simon Glassbe44f272020-12-28 20:34:51 -0700890
Simon Glass67b5ec52020-12-28 20:34:47 -0700891 def test_no_command(self):
Simon Glass8512ea22018-07-06 10:27:35 -0600892 """Test running dtoc without a command"""
Simon Glass67b5ec52020-12-28 20:34:47 -0700893 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300894 self.run_test([], '', '')
Simon Glass8512ea22018-07-06 10:27:35 -0600895 self.assertIn("Please specify a command: struct, platdata",
Simon Glass67b5ec52020-12-28 20:34:47 -0700896 str(exc.exception))
Simon Glass8512ea22018-07-06 10:27:35 -0600897
Simon Glass67b5ec52020-12-28 20:34:47 -0700898 def test_bad_command(self):
Simon Glass8512ea22018-07-06 10:27:35 -0600899 """Test running dtoc with an invalid command"""
900 dtb_file = get_dtb_file('dtoc_test_simple.dts')
901 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700902 with self.assertRaises(ValueError) as exc:
Walter Lozano361e7332020-06-25 01:10:08 -0300903 self.run_test(['invalid-cmd'], dtb_file, output)
Simon Glass10cbd3b2020-12-28 20:34:52 -0700904 self.assertIn("Unknown command 'invalid-cmd': (use: platdata, struct)",
Simon Glass67b5ec52020-12-28 20:34:47 -0700905 str(exc.exception))
Walter Lozano6c74d1b2020-07-28 19:06:23 -0300906
Simon Glass67b5ec52020-12-28 20:34:47 -0700907 @staticmethod
908 def test_scan_drivers():
Walter Lozano6c74d1b2020-07-28 19:06:23 -0300909 """Test running dtoc with additional drivers to scan"""
910 dtb_file = get_dtb_file('dtoc_test_simple.dts')
911 output = tools.GetOutputFilename('output')
Simon Glass67b5ec52020-12-28 20:34:47 -0700912 with test_util.capture_sys_output() as _:
913 dtb_platdata.run_steps(
Simon Glass192c1112020-12-28 20:34:50 -0700914 ['struct'], dtb_file, False, output, [], True,
Simon Glass67b5ec52020-12-28 20:34:47 -0700915 [None, '', 'tools/dtoc/dtoc_test_scan_drivers.cxx'])
Walter Lozano6c74d1b2020-07-28 19:06:23 -0300916
Simon Glass67b5ec52020-12-28 20:34:47 -0700917 @staticmethod
918 def test_unicode_error():
Walter Lozano6c74d1b2020-07-28 19:06:23 -0300919 """Test running dtoc with an invalid unicode file
920
921 To be able to perform this test without adding a weird text file which
922 would produce issues when using checkpatch.pl or patman, generate the
923 file at runtime and then process it.
924 """
925 dtb_file = get_dtb_file('dtoc_test_simple.dts')
926 output = tools.GetOutputFilename('output')
927 driver_fn = '/tmp/' + next(tempfile._get_candidate_names())
Simon Glass67b5ec52020-12-28 20:34:47 -0700928 with open(driver_fn, 'wb+') as fout:
929 fout.write(b'\x81')
Walter Lozano6c74d1b2020-07-28 19:06:23 -0300930
Simon Glass67b5ec52020-12-28 20:34:47 -0700931 with test_util.capture_sys_output() as _:
Simon Glass192c1112020-12-28 20:34:50 -0700932 dtb_platdata.run_steps(['struct'], dtb_file, False, output, [],
933 True, [driver_fn])
Simon Glass7d637c12020-12-23 08:11:23 -0700934
Simon Glass67b5ec52020-12-28 20:34:47 -0700935 def test_driver(self):
Simon Glass7d637c12020-12-23 08:11:23 -0700936 """Test the Driver class"""
Simon Glassa542a702020-12-28 20:35:06 -0700937 drv1 = src_scan.Driver('fred')
938 drv2 = src_scan.Driver('mary')
939 drv3 = src_scan.Driver('fred')
Simon Glass7d637c12020-12-23 08:11:23 -0700940 self.assertEqual("Driver(name='fred')", str(drv1))
941 self.assertEqual(drv1, drv3)
942 self.assertNotEqual(drv1, drv2)
943 self.assertNotEqual(drv2, drv3)
Simon Glass10cbd3b2020-12-28 20:34:52 -0700944
945 def test_output_conflict(self):
946 """Test a conflict between and output dirs and output file"""
947 with self.assertRaises(ValueError) as exc:
948 dtb_platdata.run_steps(['all'], None, False, 'out', ['cdir'], True)
949 self.assertIn("Must specify either output or output_dirs, not both",
950 str(exc.exception))
951
952 def test_output_dirs(self):
953 """Test outputting files to a directory"""
954 # Remove the directory so that files from other tests are not there
955 tools._RemoveOutputDir()
956 tools.PrepareOutputDir(None)
957
958 # This should create the .dts and .dtb in the output directory
959 dtb_file = get_dtb_file('dtoc_test_simple.dts')
960 outdir = tools.GetOutputDir()
961 fnames = glob.glob(outdir + '/*')
962 self.assertEqual(2, len(fnames))
963
964 dtb_platdata.run_steps(['all'], dtb_file, False, None, [outdir], True)
965 fnames = glob.glob(outdir + '/*')
966 self.assertEqual(4, len(fnames))
967
968 leafs = set(os.path.basename(fname) for fname in fnames)
969 self.assertEqual(
Simon Glassf31fa992020-12-28 20:35:01 -0700970 {'dt-structs-gen.h', 'source.dts', 'dt-plat.c', 'source.dtb'},
Simon Glass10cbd3b2020-12-28 20:34:52 -0700971 leafs)
Simon Glass1e0f3f42020-12-28 20:35:03 -0700972
973 def test_scan_dirs(self):
974 """Test scanning of source directories"""
975 def add_file(fname):
976 pathname = os.path.join(indir, fname)
977 dirname = os.path.dirname(pathname)
978 os.makedirs(dirname, exist_ok=True)
979 tools.WriteFile(pathname, '', binary=False)
980 fname_list.append(pathname)
981
982 try:
983 outdir = tools.GetOutputDir()
984 indir = tempfile.mkdtemp(prefix='dtoc.')
985 dtb_file = get_dtb_file('dtoc_test_simple.dts')
986
987 fname_list = []
988 add_file('fname.c')
989 add_file('dir/fname2.c')
990
991 # Mock out scan_driver and check that it is called with the
992 # expected files
Simon Glassa542a702020-12-28 20:35:06 -0700993 with mock.patch.object(src_scan.Scanner, "scan_driver") as mocked:
Simon Glass1e0f3f42020-12-28 20:35:03 -0700994 dtb_platdata.run_steps(['all'], dtb_file, False, None, [outdir],
995 True, basedir=indir)
996 self.assertEqual(2, len(mocked.mock_calls))
997 self.assertEqual(mock.call(fname_list[0]),
998 mocked.mock_calls[0])
999 self.assertEqual(mock.call(fname_list[1]),
1000 mocked.mock_calls[1])
1001 finally:
1002 shutil.rmtree(indir)