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, 0x11}, 150\t.stringval\t\t= "message", 151\t.boolval\t\t= true, 152\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0}, 153\t.stringarray\t\t= {"multi-word", "message", ""}, 154}; 155U_BOOT_DEVICE(spl_test) = { 156\t.name\t\t= "sandbox_spl_test", 157\t.platdata\t= &dtv_spl_test, 158\t.platdata_size\t= sizeof(dtv_spl_test), 159}; 160 161static struct dtd_sandbox_spl_test dtv_spl_test2 = { 162\t.bytearray\t\t= {0x1, 0x23, 0x34}, 163\t.byteval\t\t= 0x8, 164\t.intval\t\t\t= 0x3, 165\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 166\t.stringval\t\t= "message2", 167\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0}, 168\t.stringarray\t\t= {"another", "multi-word", "message"}, 169}; 170U_BOOT_DEVICE(spl_test2) = { 171\t.name\t\t= "sandbox_spl_test", 172\t.platdata\t= &dtv_spl_test2, 173\t.platdata_size\t= sizeof(dtv_spl_test2), 174}; 175 176static struct dtd_sandbox_spl_test dtv_spl_test3 = { 177\t.stringarray\t\t= {"one", "", ""}, 178}; 179U_BOOT_DEVICE(spl_test3) = { 180\t.name\t\t= "sandbox_spl_test", 181\t.platdata\t= &dtv_spl_test3, 182\t.platdata_size\t= sizeof(dtv_spl_test3), 183}; 184 185static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = { 186}; 187U_BOOT_DEVICE(spl_test4) = { 188\t.name\t\t= "sandbox_spl_test_2", 189\t.platdata\t= &dtv_spl_test4, 190\t.platdata_size\t= sizeof(dtv_spl_test4), 191}; 192 193''', data) 194 195 def test_phandle(self): 196 """Test output from a node containing a phandle reference""" 197 dtb_file = get_dtb_file('dtoc_test_phandle.dts') 198 output = tools.GetOutputFilename('output') 199 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 200 with open(output) as infile: 201 data = infile.read() 202 self.assertEqual('''#include <stdbool.h> 203#include <libfdt.h> 204struct dtd_source { 205\tstruct phandle_2_cell clocks[1]; 206}; 207struct dtd_target { 208\tfdt32_t\t\tintval; 209}; 210''', data) 211 212 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 213 with open(output) as infile: 214 data = infile.read() 215 self.assertEqual('''#include <common.h> 216#include <dm.h> 217#include <dt-structs.h> 218 219static struct dtd_target dtv_phandle_target = { 220\t.intval\t\t\t= 0x1, 221}; 222U_BOOT_DEVICE(phandle_target) = { 223\t.name\t\t= "target", 224\t.platdata\t= &dtv_phandle_target, 225\t.platdata_size\t= sizeof(dtv_phandle_target), 226}; 227 228static struct dtd_source dtv_phandle_source = { 229\t.clocks\t\t\t= {{&dtv_phandle_target, 1}}, 230}; 231U_BOOT_DEVICE(phandle_source) = { 232\t.name\t\t= "source", 233\t.platdata\t= &dtv_phandle_source, 234\t.platdata_size\t= sizeof(dtv_phandle_source), 235}; 236 237''', data) 238 239 def test_aliases(self): 240 """Test output from a node with multiple compatible strings""" 241 dtb_file = get_dtb_file('dtoc_test_aliases.dts') 242 output = tools.GetOutputFilename('output') 243 dtb_platdata.run_steps(['struct'], dtb_file, False, output) 244 with open(output) as infile: 245 data = infile.read() 246 self.assertEqual('''#include <stdbool.h> 247#include <libfdt.h> 248struct dtd_compat1 { 249\tfdt32_t\t\tintval; 250}; 251#define dtd_compat2_1_fred dtd_compat1 252#define dtd_compat3 dtd_compat1 253''', data) 254 255 dtb_platdata.run_steps(['platdata'], dtb_file, False, output) 256 with open(output) as infile: 257 data = infile.read() 258 self.assertEqual('''#include <common.h> 259#include <dm.h> 260#include <dt-structs.h> 261 262static struct dtd_compat1 dtv_spl_test = { 263\t.intval\t\t\t= 0x1, 264}; 265U_BOOT_DEVICE(spl_test) = { 266\t.name\t\t= "compat1", 267\t.platdata\t= &dtv_spl_test, 268\t.platdata_size\t= sizeof(dtv_spl_test), 269}; 270 271''', data) 272