1# 2# Copyright (c) 2012 The Chromium OS Authors. 3# 4# SPDX-License-Identifier: GPL-2.0+ 5# 6 7"""Tests for the dtb_platdata module 8 9This includes unit tests for some functions and functional tests for 10""" 11 12import collections 13import os 14import struct 15import unittest 16 17import dtb_platdata 18from dtb_platdata import conv_name_to_c 19from dtb_platdata import get_compat_name 20from dtb_platdata import get_value 21from dtb_platdata import tab_to 22import fdt 23import fdt_util 24import tools 25 26our_path = os.path.dirname(os.path.realpath(__file__)) 27 28 29def get_dtb_file(dts_fname): 30 """Compile a .dts file to a .dtb 31 32 Args: 33 dts_fname: Filename of .dts file in the current directory 34 35 Returns: 36 Filename of compiled file in output directory 37 """ 38 return fdt_util.EnsureCompiled(os.path.join(our_path, dts_fname)) 39 40 41class TestDtoc(unittest.TestCase): 42 """Tests for dtoc""" 43 @classmethod 44 def setUpClass(cls): 45 tools.PrepareOutputDir(None) 46 47 @classmethod 48 def tearDownClass(cls): 49 tools._RemoveOutputDir() 50 51 def test_name(self): 52 """Test conversion of device tree names to C identifiers""" 53 self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12')) 54 self.assertEqual('vendor_clock_frequency', 55 conv_name_to_c('vendor,clock-frequency')) 56 self.assertEqual('rockchip_rk3399_sdhci_5_1', 57 conv_name_to_c('rockchip,rk3399-sdhci-5.1')) 58 59 def test_tab_to(self): 60 """Test operation of tab_to() function""" 61 self.assertEqual('fred ', tab_to(0, 'fred')) 62 self.assertEqual('fred\t', tab_to(1, 'fred')) 63 self.assertEqual('fred was here ', tab_to(1, 'fred was here')) 64 self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here')) 65 self.assertEqual('exactly8 ', tab_to(1, 'exactly8')) 66 self.assertEqual('exactly8\t', tab_to(2, 'exactly8')) 67 68 def test_get_value(self): 69 """Test operation of get_value() function""" 70 self.assertEqual('0x45', 71 get_value(fdt.TYPE_INT, struct.pack('>I', 0x45))) 72 self.assertEqual('0x45', 73 get_value(fdt.TYPE_BYTE, struct.pack('<I', 0x45))) 74 self.assertEqual('0x0', 75 get_value(fdt.TYPE_BYTE, struct.pack('>I', 0x45))) 76 self.assertEqual('"test"', get_value(fdt.TYPE_STRING, 'test')) 77 self.assertEqual('true', get_value(fdt.TYPE_BOOL, None)) 78 79 def test_get_compat_name(self): 80 """Test operation of get_compat_name() function""" 81 Prop = collections.namedtuple('Prop', ['value']) 82 Node = collections.namedtuple('Node', ['props']) 83 84 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1']) 85 node = Node({'compatible': prop}) 86 self.assertEqual(('rockchip_rk3399_sdhci_5_1', ['arasan_sdhci_5_1']), 87 get_compat_name(node)) 88 89 prop = Prop(['rockchip,rk3399-sdhci-5.1']) 90 node = Node({'compatible': prop}) 91 self.assertEqual(('rockchip_rk3399_sdhci_5_1', []), 92 get_compat_name(node)) 93 94 prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third']) 95 node = Node({'compatible': prop}) 96 self.assertEqual(('rockchip_rk3399_sdhci_5_1', 97 ['arasan_sdhci_5_1', 'third']), 98 get_compat_name(node)) 99 100 def test_empty_file(self): 101 """Test output from a device tree file with no nodes""" 102 dtb_file = get_dtb_file('dtoc_test_empty.dts') 103 output = tools.GetOutputFilename('output') 104 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 105 with open(output) as infile: 106 lines = infile.read().splitlines() 107 self.assertEqual(['#include <stdbool.h>', '#include <libfdt.h>'], lines) 108 109 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 110 with open(output) as infile: 111 lines = infile.read().splitlines() 112 self.assertEqual(['#include <common.h>', '#include <dm.h>', 113 '#include <dt-structs.h>', ''], lines) 114 115 def test_simple(self): 116 """Test output from some simple nodes with various types of data""" 117 dtb_file = get_dtb_file('dtoc_test_simple.dts') 118 output = tools.GetOutputFilename('output') 119 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 120 with open(output) as infile: 121 data = infile.read() 122 self.assertEqual('''#include <stdbool.h> 123#include <libfdt.h> 124struct dtd_sandbox_spl_test { 125\tbool\t\tboolval; 126\tunsigned char\tbytearray[3]; 127\tunsigned char\tbyteval; 128\tfdt32_t\t\tintarray[4]; 129\tfdt32_t\t\tintval; 130\tunsigned char\tlongbytearray[9]; 131\tconst char *\tstringarray[3]; 132\tconst char *\tstringval; 133}; 134struct dtd_sandbox_spl_test_2 { 135}; 136''', data) 137 138 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 139 with open(output) as infile: 140 data = infile.read() 141 self.assertEqual('''#include <common.h> 142#include <dm.h> 143#include <dt-structs.h> 144 145static struct dtd_sandbox_spl_test dtv_spl_test = { 146\t.bytearray\t\t= {0x6, 0x0, 0x0}, 147\t.byteval\t\t= 0x5, 148\t.intval\t\t\t= 0x1, 149\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 150\t\t0x11}, 151\t.stringval\t\t= "message", 152\t.boolval\t\t= true, 153\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0}, 154\t.stringarray\t\t= {"multi-word", "message", ""}, 155}; 156U_BOOT_DEVICE(spl_test) = { 157\t.name\t\t= "sandbox_spl_test", 158\t.platdata\t= &dtv_spl_test, 159\t.platdata_size\t= sizeof(dtv_spl_test), 160}; 161 162static struct dtd_sandbox_spl_test dtv_spl_test2 = { 163\t.bytearray\t\t= {0x1, 0x23, 0x34}, 164\t.byteval\t\t= 0x8, 165\t.intval\t\t\t= 0x3, 166\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 167\t\t0x0}, 168\t.stringval\t\t= "message2", 169\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0}, 170\t.stringarray\t\t= {"another", "multi-word", "message"}, 171}; 172U_BOOT_DEVICE(spl_test2) = { 173\t.name\t\t= "sandbox_spl_test", 174\t.platdata\t= &dtv_spl_test2, 175\t.platdata_size\t= sizeof(dtv_spl_test2), 176}; 177 178static struct dtd_sandbox_spl_test dtv_spl_test3 = { 179\t.stringarray\t\t= {"one", "", ""}, 180}; 181U_BOOT_DEVICE(spl_test3) = { 182\t.name\t\t= "sandbox_spl_test", 183\t.platdata\t= &dtv_spl_test3, 184\t.platdata_size\t= sizeof(dtv_spl_test3), 185}; 186 187static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = { 188}; 189U_BOOT_DEVICE(spl_test4) = { 190\t.name\t\t= "sandbox_spl_test_2", 191\t.platdata\t= &dtv_spl_test4, 192\t.platdata_size\t= sizeof(dtv_spl_test4), 193}; 194 195''', data) 196 197 def test_phandle(self): 198 """Test output from a node containing a phandle reference""" 199 dtb_file = get_dtb_file('dtoc_test_phandle.dts') 200 output = tools.GetOutputFilename('output') 201 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 202 with open(output) as infile: 203 data = infile.read() 204 self.assertEqual('''#include <stdbool.h> 205#include <libfdt.h> 206struct dtd_source { 207\tstruct phandle_2_cell clocks[1]; 208}; 209struct dtd_target { 210\tfdt32_t\t\tintval; 211}; 212''', data) 213 214 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 215 with open(output) as infile: 216 data = infile.read() 217 self.assertEqual('''#include <common.h> 218#include <dm.h> 219#include <dt-structs.h> 220 221static struct dtd_target dtv_phandle_target = { 222\t.intval\t\t\t= 0x1, 223}; 224U_BOOT_DEVICE(phandle_target) = { 225\t.name\t\t= "target", 226\t.platdata\t= &dtv_phandle_target, 227\t.platdata_size\t= sizeof(dtv_phandle_target), 228}; 229 230static struct dtd_source dtv_phandle_source = { 231\t.clocks\t\t\t= {{&dtv_phandle_target, 1}}, 232}; 233U_BOOT_DEVICE(phandle_source) = { 234\t.name\t\t= "source", 235\t.platdata\t= &dtv_phandle_source, 236\t.platdata_size\t= sizeof(dtv_phandle_source), 237}; 238 239''', data) 240 241 def test_aliases(self): 242 """Test output from a node with multiple compatible strings""" 243 dtb_file = get_dtb_file('dtoc_test_aliases.dts') 244 output = tools.GetOutputFilename('output') 245 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 246 with open(output) as infile: 247 data = infile.read() 248 self.assertEqual('''#include <stdbool.h> 249#include <libfdt.h> 250struct dtd_compat1 { 251\tfdt32_t\t\tintval; 252}; 253#define dtd_compat2_1_fred dtd_compat1 254#define dtd_compat3 dtd_compat1 255''', data) 256 257 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 258 with open(output) as infile: 259 data = infile.read() 260 self.assertEqual('''#include <common.h> 261#include <dm.h> 262#include <dt-structs.h> 263 264static struct dtd_compat1 dtv_spl_test = { 265\t.intval\t\t\t= 0x1, 266}; 267U_BOOT_DEVICE(spl_test) = { 268\t.name\t\t= "compat1", 269\t.platdata\t= &dtv_spl_test, 270\t.platdata_size\t= sizeof(dtv_spl_test), 271}; 272 273''', data) 274