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