183d290c5STom Rini# SPDX-License-Identifier: GPL-2.0+ 2680e3312SSimon Glass# Copyright (c) 2016 Google, Inc 3680e3312SSimon Glass# Written by Simon Glass <sjg@chromium.org> 4680e3312SSimon Glass# 5680e3312SSimon Glass# To run a single test, change to this directory, and: 6680e3312SSimon Glass# 7680e3312SSimon Glass# python -m unittest func_test.TestFunctional.testHelp 8680e3312SSimon Glass 9e0e5df93SSimon Glassimport hashlib 10680e3312SSimon Glassfrom optparse import OptionParser 11680e3312SSimon Glassimport os 12680e3312SSimon Glassimport shutil 13680e3312SSimon Glassimport struct 14680e3312SSimon Glassimport sys 15680e3312SSimon Glassimport tempfile 16680e3312SSimon Glassimport unittest 17680e3312SSimon Glass 18680e3312SSimon Glassimport binman 19680e3312SSimon Glassimport cmdline 20680e3312SSimon Glassimport command 21680e3312SSimon Glassimport control 2219790632SSimon Glassimport elf 23680e3312SSimon Glassimport fdt 24680e3312SSimon Glassimport fdt_util 2511e36cceSSimon Glassimport fmap_util 26fd8d1f79SSimon Glassimport test_util 27c55a50f5SSimon Glassimport state 28680e3312SSimon Glassimport tools 29680e3312SSimon Glassimport tout 30680e3312SSimon Glass 31680e3312SSimon Glass# Contents of test files, corresponding to different entry types 32680e3312SSimon GlassU_BOOT_DATA = '1234' 33680e3312SSimon GlassU_BOOT_IMG_DATA = 'img' 34f689890dSSimon GlassU_BOOT_SPL_DATA = '56780123456789abcde' 35b8ef5b6bSSimon GlassU_BOOT_TPL_DATA = 'tpl' 36680e3312SSimon GlassBLOB_DATA = '89' 37680e3312SSimon GlassME_DATA = '0abcd' 38680e3312SSimon GlassVGA_DATA = 'vga' 39680e3312SSimon GlassU_BOOT_DTB_DATA = 'udtb' 4047419eaeSSimon GlassU_BOOT_SPL_DTB_DATA = 'spldtb' 41b8ef5b6bSSimon GlassU_BOOT_TPL_DTB_DATA = 'tpldtb' 42680e3312SSimon GlassX86_START16_DATA = 'start16' 438772213eSSimon GlassX86_START16_SPL_DATA = 'start16spl' 4435b384cbSSimon GlassX86_START16_TPL_DATA = 'start16tpl' 459d368f32SJagdish GediyaPPC_MPC85XX_BR_DATA = 'ppcmpc85xxbr' 46680e3312SSimon GlassU_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here' 476b187df7SSimon GlassU_BOOT_SPL_NODTB_DATA = 'splnodtb with microcode pointer somewhere in here' 48f0253635SSimon GlassU_BOOT_TPL_NODTB_DATA = 'tplnodtb with microcode pointer somewhere in here' 49680e3312SSimon GlassFSP_DATA = 'fsp' 50680e3312SSimon GlassCMC_DATA = 'cmc' 51680e3312SSimon GlassVBT_DATA = 'vbt' 52ca4f4ff7SSimon GlassMRC_DATA = 'mrc' 53bb74837cSSimon GlassTEXT_DATA = 'text' 54bb74837cSSimon GlassTEXT_DATA2 = 'text2' 55bb74837cSSimon GlassTEXT_DATA3 = 'text3' 56ec127af0SSimon GlassCROS_EC_RW_DATA = 'ecrw' 570ef87aa3SSimon GlassGBB_DATA = 'gbbd' 580ef87aa3SSimon GlassBMPBLK_DATA = 'bmp' 5924d0d3c3SSimon GlassVBLOCK_DATA = 'vblk' 600a98b28bSSimon GlassFILES_DATA = ("sorry I'm late\nOh, don't bother apologising, I'm " + 610a98b28bSSimon Glass "sorry you're alive\n") 6283d73c2fSSimon GlassCOMPRESS_DATA = 'data to compress' 63*3ae192c2SSimon GlassREFCODE_DATA = 'refcode' 64ec127af0SSimon Glass 65680e3312SSimon Glass 66680e3312SSimon Glassclass TestFunctional(unittest.TestCase): 67680e3312SSimon Glass """Functional tests for binman 68680e3312SSimon Glass 69680e3312SSimon Glass Most of these use a sample .dts file to build an image and then check 70680e3312SSimon Glass that it looks correct. The sample files are in the test/ subdirectory 71680e3312SSimon Glass and are numbered. 72680e3312SSimon Glass 73680e3312SSimon Glass For each entry type a very small test file is created using fixed 74680e3312SSimon Glass string contents. This makes it easy to test that things look right, and 75680e3312SSimon Glass debug problems. 76680e3312SSimon Glass 77680e3312SSimon Glass In some cases a 'real' file must be used - these are also supplied in 78680e3312SSimon Glass the test/ diurectory. 79680e3312SSimon Glass """ 80680e3312SSimon Glass @classmethod 81680e3312SSimon Glass def setUpClass(self): 824d5994f9SSimon Glass global entry 834d5994f9SSimon Glass import entry 844d5994f9SSimon Glass 85680e3312SSimon Glass # Handle the case where argv[0] is 'python' 86680e3312SSimon Glass self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) 87680e3312SSimon Glass self._binman_pathname = os.path.join(self._binman_dir, 'binman') 88680e3312SSimon Glass 89680e3312SSimon Glass # Create a temporary directory for input files 90680e3312SSimon Glass self._indir = tempfile.mkdtemp(prefix='binmant.') 91680e3312SSimon Glass 92680e3312SSimon Glass # Create some test files 93680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA) 94680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot.img', U_BOOT_IMG_DATA) 95680e3312SSimon Glass TestFunctional._MakeInputFile('spl/u-boot-spl.bin', U_BOOT_SPL_DATA) 96b8ef5b6bSSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-tpl.bin', U_BOOT_TPL_DATA) 97680e3312SSimon Glass TestFunctional._MakeInputFile('blobfile', BLOB_DATA) 98680e3312SSimon Glass TestFunctional._MakeInputFile('me.bin', ME_DATA) 99680e3312SSimon Glass TestFunctional._MakeInputFile('vga.bin', VGA_DATA) 100b8ef5b6bSSimon Glass self._ResetDtbs() 101680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) 1029d368f32SJagdish Gediya TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA) 1038772213eSSimon Glass TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', 1048772213eSSimon Glass X86_START16_SPL_DATA) 10535b384cbSSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin', 10635b384cbSSimon Glass X86_START16_TPL_DATA) 107680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) 1086b187df7SSimon Glass TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin', 1096b187df7SSimon Glass U_BOOT_SPL_NODTB_DATA) 110f0253635SSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-tpl-nodtb.bin', 111f0253635SSimon Glass U_BOOT_TPL_NODTB_DATA) 112680e3312SSimon Glass TestFunctional._MakeInputFile('fsp.bin', FSP_DATA) 113680e3312SSimon Glass TestFunctional._MakeInputFile('cmc.bin', CMC_DATA) 114680e3312SSimon Glass TestFunctional._MakeInputFile('vbt.bin', VBT_DATA) 115ca4f4ff7SSimon Glass TestFunctional._MakeInputFile('mrc.bin', MRC_DATA) 116ec127af0SSimon Glass TestFunctional._MakeInputFile('ecrw.bin', CROS_EC_RW_DATA) 1170ef87aa3SSimon Glass TestFunctional._MakeInputDir('devkeys') 1180ef87aa3SSimon Glass TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) 119*3ae192c2SSimon Glass TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) 120680e3312SSimon Glass 121680e3312SSimon Glass # ELF file with a '_dt_ucode_base_size' symbol 122680e3312SSimon Glass with open(self.TestFile('u_boot_ucode_ptr')) as fd: 123680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 124680e3312SSimon Glass 125680e3312SSimon Glass # Intel flash descriptor file 126680e3312SSimon Glass with open(self.TestFile('descriptor.bin')) as fd: 127680e3312SSimon Glass TestFunctional._MakeInputFile('descriptor.bin', fd.read()) 128680e3312SSimon Glass 1290a98b28bSSimon Glass shutil.copytree(self.TestFile('files'), 1300a98b28bSSimon Glass os.path.join(self._indir, 'files')) 1310a98b28bSSimon Glass 13283d73c2fSSimon Glass TestFunctional._MakeInputFile('compress', COMPRESS_DATA) 13383d73c2fSSimon Glass 134680e3312SSimon Glass @classmethod 135680e3312SSimon Glass def tearDownClass(self): 136680e3312SSimon Glass """Remove the temporary input directory and its contents""" 137680e3312SSimon Glass if self._indir: 138680e3312SSimon Glass shutil.rmtree(self._indir) 139680e3312SSimon Glass self._indir = None 140680e3312SSimon Glass 141680e3312SSimon Glass def setUp(self): 142680e3312SSimon Glass # Enable this to turn on debugging output 143680e3312SSimon Glass # tout.Init(tout.DEBUG) 144680e3312SSimon Glass command.test_result = None 145680e3312SSimon Glass 146680e3312SSimon Glass def tearDown(self): 147680e3312SSimon Glass """Remove the temporary output directory""" 148680e3312SSimon Glass tools._FinaliseForTest() 149680e3312SSimon Glass 150b8ef5b6bSSimon Glass @classmethod 151b8ef5b6bSSimon Glass def _ResetDtbs(self): 152b8ef5b6bSSimon Glass TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) 153b8ef5b6bSSimon Glass TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA) 154b8ef5b6bSSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA) 155b8ef5b6bSSimon Glass 156680e3312SSimon Glass def _RunBinman(self, *args, **kwargs): 157680e3312SSimon Glass """Run binman using the command line 158680e3312SSimon Glass 159680e3312SSimon Glass Args: 160680e3312SSimon Glass Arguments to pass, as a list of strings 161680e3312SSimon Glass kwargs: Arguments to pass to Command.RunPipe() 162680e3312SSimon Glass """ 163680e3312SSimon Glass result = command.RunPipe([[self._binman_pathname] + list(args)], 164680e3312SSimon Glass capture=True, capture_stderr=True, raise_on_error=False) 165680e3312SSimon Glass if result.return_code and kwargs.get('raise_on_error', True): 166680e3312SSimon Glass raise Exception("Error running '%s': %s" % (' '.join(args), 167680e3312SSimon Glass result.stdout + result.stderr)) 168680e3312SSimon Glass return result 169680e3312SSimon Glass 170680e3312SSimon Glass def _DoBinman(self, *args): 171680e3312SSimon Glass """Run binman using directly (in the same process) 172680e3312SSimon Glass 173680e3312SSimon Glass Args: 174680e3312SSimon Glass Arguments to pass, as a list of strings 175680e3312SSimon Glass Returns: 176680e3312SSimon Glass Return value (0 for success) 177680e3312SSimon Glass """ 1787fe9173bSSimon Glass args = list(args) 1797fe9173bSSimon Glass if '-D' in sys.argv: 1807fe9173bSSimon Glass args = args + ['-D'] 1817fe9173bSSimon Glass (options, args) = cmdline.ParseArgs(args) 182680e3312SSimon Glass options.pager = 'binman-invalid-pager' 183680e3312SSimon Glass options.build_dir = self._indir 184680e3312SSimon Glass 185680e3312SSimon Glass # For testing, you can force an increase in verbosity here 186680e3312SSimon Glass # options.verbosity = tout.DEBUG 187680e3312SSimon Glass return control.Binman(options, args) 188680e3312SSimon Glass 18953af22a9SSimon Glass def _DoTestFile(self, fname, debug=False, map=False, update_dtb=False, 19093d17413SSimon Glass entry_args=None, images=None, use_real_dtb=False): 191680e3312SSimon Glass """Run binman with a given test file 192680e3312SSimon Glass 193680e3312SSimon Glass Args: 194741f2d62SSimon Glass fname: Device-tree source filename to use (e.g. 005_simple.dts) 1957ae5f315SSimon Glass debug: True to enable debugging output 1963b0c3821SSimon Glass map: True to output map files for the images 1973ab9598dSSimon Glass update_dtb: Update the offset and size of each entry in the device 19816b8d6b7SSimon Glass tree before packing it into the image 1990bfa7b09SSimon Glass entry_args: Dict of entry args to supply to binman 2000bfa7b09SSimon Glass key: arg name 2010bfa7b09SSimon Glass value: value of that arg 2020bfa7b09SSimon Glass images: List of image names to build 203680e3312SSimon Glass """ 2047fe9173bSSimon Glass args = ['-p', '-I', self._indir, '-d', self.TestFile(fname)] 2057fe9173bSSimon Glass if debug: 2067fe9173bSSimon Glass args.append('-D') 2073b0c3821SSimon Glass if map: 2083b0c3821SSimon Glass args.append('-m') 20916b8d6b7SSimon Glass if update_dtb: 21016b8d6b7SSimon Glass args.append('-up') 21193d17413SSimon Glass if not use_real_dtb: 21293d17413SSimon Glass args.append('--fake-dtb') 21353af22a9SSimon Glass if entry_args: 21453af22a9SSimon Glass for arg, value in entry_args.iteritems(): 21553af22a9SSimon Glass args.append('-a%s=%s' % (arg, value)) 2160bfa7b09SSimon Glass if images: 2170bfa7b09SSimon Glass for image in images: 2180bfa7b09SSimon Glass args += ['-i', image] 2197fe9173bSSimon Glass return self._DoBinman(*args) 220680e3312SSimon Glass 221680e3312SSimon Glass def _SetupDtb(self, fname, outfile='u-boot.dtb'): 222680e3312SSimon Glass """Set up a new test device-tree file 223680e3312SSimon Glass 224680e3312SSimon Glass The given file is compiled and set up as the device tree to be used 225680e3312SSimon Glass for ths test. 226680e3312SSimon Glass 227680e3312SSimon Glass Args: 228680e3312SSimon Glass fname: Filename of .dts file to read 2297ae5f315SSimon Glass outfile: Output filename for compiled device-tree binary 230680e3312SSimon Glass 231680e3312SSimon Glass Returns: 2327ae5f315SSimon Glass Contents of device-tree binary 233680e3312SSimon Glass """ 234e0e6275fSSimon Glass tools.PrepareOutputDir(None) 235680e3312SSimon Glass dtb = fdt_util.EnsureCompiled(self.TestFile(fname)) 236680e3312SSimon Glass with open(dtb) as fd: 237680e3312SSimon Glass data = fd.read() 238680e3312SSimon Glass TestFunctional._MakeInputFile(outfile, data) 239e0e6275fSSimon Glass tools.FinaliseOutputDir() 240680e3312SSimon Glass return data 241680e3312SSimon Glass 2426ed45ba0SSimon Glass def _GetDtbContentsForSplTpl(self, dtb_data, name): 2436ed45ba0SSimon Glass """Create a version of the main DTB for SPL or SPL 2446ed45ba0SSimon Glass 2456ed45ba0SSimon Glass For testing we don't actually have different versions of the DTB. With 2466ed45ba0SSimon Glass U-Boot we normally run fdtgrep to remove unwanted nodes, but for tests 2476ed45ba0SSimon Glass we don't normally have any unwanted nodes. 2486ed45ba0SSimon Glass 2496ed45ba0SSimon Glass We still want the DTBs for SPL and TPL to be different though, since 2506ed45ba0SSimon Glass otherwise it is confusing to know which one we are looking at. So add 2516ed45ba0SSimon Glass an 'spl' or 'tpl' property to the top-level node. 2526ed45ba0SSimon Glass """ 2536ed45ba0SSimon Glass dtb = fdt.Fdt.FromData(dtb_data) 2546ed45ba0SSimon Glass dtb.Scan() 2556ed45ba0SSimon Glass dtb.GetNode('/binman').AddZeroProp(name) 2566ed45ba0SSimon Glass dtb.Sync(auto_resize=True) 2576ed45ba0SSimon Glass dtb.Pack() 2586ed45ba0SSimon Glass return dtb.GetContents() 2596ed45ba0SSimon Glass 26016b8d6b7SSimon Glass def _DoReadFileDtb(self, fname, use_real_dtb=False, map=False, 2616ed45ba0SSimon Glass update_dtb=False, entry_args=None, reset_dtbs=True): 262680e3312SSimon Glass """Run binman and return the resulting image 263680e3312SSimon Glass 264680e3312SSimon Glass This runs binman with a given test file and then reads the resulting 265680e3312SSimon Glass output file. It is a shortcut function since most tests need to do 266680e3312SSimon Glass these steps. 267680e3312SSimon Glass 268680e3312SSimon Glass Raises an assertion failure if binman returns a non-zero exit code. 269680e3312SSimon Glass 270680e3312SSimon Glass Args: 271741f2d62SSimon Glass fname: Device-tree source filename to use (e.g. 005_simple.dts) 272680e3312SSimon Glass use_real_dtb: True to use the test file as the contents of 273680e3312SSimon Glass the u-boot-dtb entry. Normally this is not needed and the 274680e3312SSimon Glass test contents (the U_BOOT_DTB_DATA string) can be used. 275680e3312SSimon Glass But in some test we need the real contents. 2763b0c3821SSimon Glass map: True to output map files for the images 2773ab9598dSSimon Glass update_dtb: Update the offset and size of each entry in the device 27816b8d6b7SSimon Glass tree before packing it into the image 279680e3312SSimon Glass 280680e3312SSimon Glass Returns: 281680e3312SSimon Glass Tuple: 282680e3312SSimon Glass Resulting image contents 283680e3312SSimon Glass Device tree contents 2843b0c3821SSimon Glass Map data showing contents of image (or None if none) 285ea6922e3SSimon Glass Output device tree binary filename ('u-boot.dtb' path) 286680e3312SSimon Glass """ 287680e3312SSimon Glass dtb_data = None 288680e3312SSimon Glass # Use the compiled test file as the u-boot-dtb input 289680e3312SSimon Glass if use_real_dtb: 290680e3312SSimon Glass dtb_data = self._SetupDtb(fname) 2916ed45ba0SSimon Glass infile = os.path.join(self._indir, 'u-boot.dtb') 2926ed45ba0SSimon Glass 2936ed45ba0SSimon Glass # For testing purposes, make a copy of the DT for SPL and TPL. Add 2946ed45ba0SSimon Glass # a node indicating which it is, so aid verification. 2956ed45ba0SSimon Glass for name in ['spl', 'tpl']: 2966ed45ba0SSimon Glass dtb_fname = '%s/u-boot-%s.dtb' % (name, name) 2976ed45ba0SSimon Glass outfile = os.path.join(self._indir, dtb_fname) 2986ed45ba0SSimon Glass TestFunctional._MakeInputFile(dtb_fname, 2996ed45ba0SSimon Glass self._GetDtbContentsForSplTpl(dtb_data, name)) 300680e3312SSimon Glass 301680e3312SSimon Glass try: 30253af22a9SSimon Glass retcode = self._DoTestFile(fname, map=map, update_dtb=update_dtb, 3036ed45ba0SSimon Glass entry_args=entry_args, use_real_dtb=use_real_dtb) 304680e3312SSimon Glass self.assertEqual(0, retcode) 3056ed45ba0SSimon Glass out_dtb_fname = tools.GetOutputFilename('u-boot.dtb.out') 306680e3312SSimon Glass 307680e3312SSimon Glass # Find the (only) image, read it and return its contents 308680e3312SSimon Glass image = control.images['image'] 30916b8d6b7SSimon Glass image_fname = tools.GetOutputFilename('image.bin') 31016b8d6b7SSimon Glass self.assertTrue(os.path.exists(image_fname)) 3113b0c3821SSimon Glass if map: 3123b0c3821SSimon Glass map_fname = tools.GetOutputFilename('image.map') 3133b0c3821SSimon Glass with open(map_fname) as fd: 3143b0c3821SSimon Glass map_data = fd.read() 3153b0c3821SSimon Glass else: 3163b0c3821SSimon Glass map_data = None 31716b8d6b7SSimon Glass with open(image_fname) as fd: 31816b8d6b7SSimon Glass return fd.read(), dtb_data, map_data, out_dtb_fname 319680e3312SSimon Glass finally: 320680e3312SSimon Glass # Put the test file back 3216ed45ba0SSimon Glass if reset_dtbs and use_real_dtb: 322b8ef5b6bSSimon Glass self._ResetDtbs() 323680e3312SSimon Glass 324680e3312SSimon Glass def _DoReadFile(self, fname, use_real_dtb=False): 3257ae5f315SSimon Glass """Helper function which discards the device-tree binary 3267ae5f315SSimon Glass 3277ae5f315SSimon Glass Args: 328741f2d62SSimon Glass fname: Device-tree source filename to use (e.g. 005_simple.dts) 3297ae5f315SSimon Glass use_real_dtb: True to use the test file as the contents of 3307ae5f315SSimon Glass the u-boot-dtb entry. Normally this is not needed and the 3317ae5f315SSimon Glass test contents (the U_BOOT_DTB_DATA string) can be used. 3327ae5f315SSimon Glass But in some test we need the real contents. 333ea6922e3SSimon Glass 334ea6922e3SSimon Glass Returns: 335ea6922e3SSimon Glass Resulting image contents 3367ae5f315SSimon Glass """ 337680e3312SSimon Glass return self._DoReadFileDtb(fname, use_real_dtb)[0] 338680e3312SSimon Glass 339680e3312SSimon Glass @classmethod 340680e3312SSimon Glass def _MakeInputFile(self, fname, contents): 341680e3312SSimon Glass """Create a new test input file, creating directories as needed 342680e3312SSimon Glass 343680e3312SSimon Glass Args: 3443ab9598dSSimon Glass fname: Filename to create 345680e3312SSimon Glass contents: File contents to write in to the file 346680e3312SSimon Glass Returns: 347680e3312SSimon Glass Full pathname of file created 348680e3312SSimon Glass """ 349680e3312SSimon Glass pathname = os.path.join(self._indir, fname) 350680e3312SSimon Glass dirname = os.path.dirname(pathname) 351680e3312SSimon Glass if dirname and not os.path.exists(dirname): 352680e3312SSimon Glass os.makedirs(dirname) 353680e3312SSimon Glass with open(pathname, 'wb') as fd: 354680e3312SSimon Glass fd.write(contents) 355680e3312SSimon Glass return pathname 356680e3312SSimon Glass 357680e3312SSimon Glass @classmethod 3580ef87aa3SSimon Glass def _MakeInputDir(self, dirname): 3590ef87aa3SSimon Glass """Create a new test input directory, creating directories as needed 3600ef87aa3SSimon Glass 3610ef87aa3SSimon Glass Args: 3620ef87aa3SSimon Glass dirname: Directory name to create 3630ef87aa3SSimon Glass 3640ef87aa3SSimon Glass Returns: 3650ef87aa3SSimon Glass Full pathname of directory created 3660ef87aa3SSimon Glass """ 3670ef87aa3SSimon Glass pathname = os.path.join(self._indir, dirname) 3680ef87aa3SSimon Glass if not os.path.exists(pathname): 3690ef87aa3SSimon Glass os.makedirs(pathname) 3700ef87aa3SSimon Glass return pathname 3710ef87aa3SSimon Glass 3720ef87aa3SSimon Glass @classmethod 37311ae93eeSSimon Glass def _SetupSplElf(self, src_fname='bss_data'): 37411ae93eeSSimon Glass """Set up an ELF file with a '_dt_ucode_base_size' symbol 37511ae93eeSSimon Glass 37611ae93eeSSimon Glass Args: 37711ae93eeSSimon Glass Filename of ELF file to use as SPL 37811ae93eeSSimon Glass """ 37911ae93eeSSimon Glass with open(self.TestFile(src_fname)) as fd: 38011ae93eeSSimon Glass TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) 38111ae93eeSSimon Glass 38211ae93eeSSimon Glass @classmethod 383680e3312SSimon Glass def TestFile(self, fname): 384680e3312SSimon Glass return os.path.join(self._binman_dir, 'test', fname) 385680e3312SSimon Glass 386680e3312SSimon Glass def AssertInList(self, grep_list, target): 387680e3312SSimon Glass """Assert that at least one of a list of things is in a target 388680e3312SSimon Glass 389680e3312SSimon Glass Args: 390680e3312SSimon Glass grep_list: List of strings to check 391680e3312SSimon Glass target: Target string 392680e3312SSimon Glass """ 393680e3312SSimon Glass for grep in grep_list: 394680e3312SSimon Glass if grep in target: 395680e3312SSimon Glass return 396680e3312SSimon Glass self.fail("Error: '%' not found in '%s'" % (grep_list, target)) 397680e3312SSimon Glass 398680e3312SSimon Glass def CheckNoGaps(self, entries): 399680e3312SSimon Glass """Check that all entries fit together without gaps 400680e3312SSimon Glass 401680e3312SSimon Glass Args: 402680e3312SSimon Glass entries: List of entries to check 403680e3312SSimon Glass """ 4043ab9598dSSimon Glass offset = 0 405680e3312SSimon Glass for entry in entries.values(): 4063ab9598dSSimon Glass self.assertEqual(offset, entry.offset) 4073ab9598dSSimon Glass offset += entry.size 408680e3312SSimon Glass 409680e3312SSimon Glass def GetFdtLen(self, dtb): 4107ae5f315SSimon Glass """Get the totalsize field from a device-tree binary 411680e3312SSimon Glass 412680e3312SSimon Glass Args: 4137ae5f315SSimon Glass dtb: Device-tree binary contents 414680e3312SSimon Glass 415680e3312SSimon Glass Returns: 4167ae5f315SSimon Glass Total size of device-tree binary, from the header 417680e3312SSimon Glass """ 418680e3312SSimon Glass return struct.unpack('>L', dtb[4:8])[0] 419680e3312SSimon Glass 420cee02e6fSSimon Glass def _GetPropTree(self, dtb, prop_names): 42116b8d6b7SSimon Glass def AddNode(node, path): 42216b8d6b7SSimon Glass if node.name != '/': 42316b8d6b7SSimon Glass path += '/' + node.name 42416b8d6b7SSimon Glass for subnode in node.subnodes: 42516b8d6b7SSimon Glass for prop in subnode.props.values(): 426cee02e6fSSimon Glass if prop.name in prop_names: 42716b8d6b7SSimon Glass prop_path = path + '/' + subnode.name + ':' + prop.name 42816b8d6b7SSimon Glass tree[prop_path[len('/binman/'):]] = fdt_util.fdt32_to_cpu( 42916b8d6b7SSimon Glass prop.value) 43016b8d6b7SSimon Glass AddNode(subnode, path) 43116b8d6b7SSimon Glass 43216b8d6b7SSimon Glass tree = {} 43316b8d6b7SSimon Glass AddNode(dtb.GetRoot(), '') 43416b8d6b7SSimon Glass return tree 43516b8d6b7SSimon Glass 436680e3312SSimon Glass def testRun(self): 437680e3312SSimon Glass """Test a basic run with valid args""" 438680e3312SSimon Glass result = self._RunBinman('-h') 439680e3312SSimon Glass 440680e3312SSimon Glass def testFullHelp(self): 441680e3312SSimon Glass """Test that the full help is displayed with -H""" 442680e3312SSimon Glass result = self._RunBinman('-H') 443680e3312SSimon Glass help_file = os.path.join(self._binman_dir, 'README') 4443759df0cSTom Rini # Remove possible extraneous strings 4453759df0cSTom Rini extra = '::::::::::::::\n' + help_file + '\n::::::::::::::\n' 4463759df0cSTom Rini gothelp = result.stdout.replace(extra, '') 4473759df0cSTom Rini self.assertEqual(len(gothelp), os.path.getsize(help_file)) 448680e3312SSimon Glass self.assertEqual(0, len(result.stderr)) 449680e3312SSimon Glass self.assertEqual(0, result.return_code) 450680e3312SSimon Glass 451680e3312SSimon Glass def testFullHelpInternal(self): 452680e3312SSimon Glass """Test that the full help is displayed with -H""" 453680e3312SSimon Glass try: 454680e3312SSimon Glass command.test_result = command.CommandResult() 455680e3312SSimon Glass result = self._DoBinman('-H') 456680e3312SSimon Glass help_file = os.path.join(self._binman_dir, 'README') 457680e3312SSimon Glass finally: 458680e3312SSimon Glass command.test_result = None 459680e3312SSimon Glass 460680e3312SSimon Glass def testHelp(self): 461680e3312SSimon Glass """Test that the basic help is displayed with -h""" 462680e3312SSimon Glass result = self._RunBinman('-h') 463680e3312SSimon Glass self.assertTrue(len(result.stdout) > 200) 464680e3312SSimon Glass self.assertEqual(0, len(result.stderr)) 465680e3312SSimon Glass self.assertEqual(0, result.return_code) 466680e3312SSimon Glass 467680e3312SSimon Glass def testBoard(self): 468680e3312SSimon Glass """Test that we can run it with a specific board""" 469741f2d62SSimon Glass self._SetupDtb('005_simple.dts', 'sandbox/u-boot.dtb') 470680e3312SSimon Glass TestFunctional._MakeInputFile('sandbox/u-boot.bin', U_BOOT_DATA) 471680e3312SSimon Glass result = self._DoBinman('-b', 'sandbox') 472680e3312SSimon Glass self.assertEqual(0, result) 473680e3312SSimon Glass 474680e3312SSimon Glass def testNeedBoard(self): 475680e3312SSimon Glass """Test that we get an error when no board ius supplied""" 476680e3312SSimon Glass with self.assertRaises(ValueError) as e: 477680e3312SSimon Glass result = self._DoBinman() 478680e3312SSimon Glass self.assertIn("Must provide a board to process (use -b <board>)", 479680e3312SSimon Glass str(e.exception)) 480680e3312SSimon Glass 481680e3312SSimon Glass def testMissingDt(self): 4827ae5f315SSimon Glass """Test that an invalid device-tree file generates an error""" 483680e3312SSimon Glass with self.assertRaises(Exception) as e: 484680e3312SSimon Glass self._RunBinman('-d', 'missing_file') 485680e3312SSimon Glass # We get one error from libfdt, and a different one from fdtget. 486680e3312SSimon Glass self.AssertInList(["Couldn't open blob from 'missing_file'", 487680e3312SSimon Glass 'No such file or directory'], str(e.exception)) 488680e3312SSimon Glass 489680e3312SSimon Glass def testBrokenDt(self): 4907ae5f315SSimon Glass """Test that an invalid device-tree source file generates an error 491680e3312SSimon Glass 492680e3312SSimon Glass Since this is a source file it should be compiled and the error 493680e3312SSimon Glass will come from the device-tree compiler (dtc). 494680e3312SSimon Glass """ 495680e3312SSimon Glass with self.assertRaises(Exception) as e: 496741f2d62SSimon Glass self._RunBinman('-d', self.TestFile('001_invalid.dts')) 497680e3312SSimon Glass self.assertIn("FATAL ERROR: Unable to parse input tree", 498680e3312SSimon Glass str(e.exception)) 499680e3312SSimon Glass 500680e3312SSimon Glass def testMissingNode(self): 501680e3312SSimon Glass """Test that a device tree without a 'binman' node generates an error""" 502680e3312SSimon Glass with self.assertRaises(Exception) as e: 503741f2d62SSimon Glass self._DoBinman('-d', self.TestFile('002_missing_node.dts')) 504680e3312SSimon Glass self.assertIn("does not have a 'binman' node", str(e.exception)) 505680e3312SSimon Glass 506680e3312SSimon Glass def testEmpty(self): 507680e3312SSimon Glass """Test that an empty binman node works OK (i.e. does nothing)""" 508741f2d62SSimon Glass result = self._RunBinman('-d', self.TestFile('003_empty.dts')) 509680e3312SSimon Glass self.assertEqual(0, len(result.stderr)) 510680e3312SSimon Glass self.assertEqual(0, result.return_code) 511680e3312SSimon Glass 512680e3312SSimon Glass def testInvalidEntry(self): 513680e3312SSimon Glass """Test that an invalid entry is flagged""" 514680e3312SSimon Glass with self.assertRaises(Exception) as e: 515680e3312SSimon Glass result = self._RunBinman('-d', 516741f2d62SSimon Glass self.TestFile('004_invalid_entry.dts')) 517680e3312SSimon Glass self.assertIn("Unknown entry type 'not-a-valid-type' in node " 518680e3312SSimon Glass "'/binman/not-a-valid-type'", str(e.exception)) 519680e3312SSimon Glass 520680e3312SSimon Glass def testSimple(self): 521680e3312SSimon Glass """Test a simple binman with a single file""" 522741f2d62SSimon Glass data = self._DoReadFile('005_simple.dts') 523680e3312SSimon Glass self.assertEqual(U_BOOT_DATA, data) 524680e3312SSimon Glass 5257fe9173bSSimon Glass def testSimpleDebug(self): 5267fe9173bSSimon Glass """Test a simple binman run with debugging enabled""" 527741f2d62SSimon Glass data = self._DoTestFile('005_simple.dts', debug=True) 5287fe9173bSSimon Glass 529680e3312SSimon Glass def testDual(self): 530680e3312SSimon Glass """Test that we can handle creating two images 531680e3312SSimon Glass 532680e3312SSimon Glass This also tests image padding. 533680e3312SSimon Glass """ 534741f2d62SSimon Glass retcode = self._DoTestFile('006_dual_image.dts') 535680e3312SSimon Glass self.assertEqual(0, retcode) 536680e3312SSimon Glass 537680e3312SSimon Glass image = control.images['image1'] 538680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), image._size) 539680e3312SSimon Glass fname = tools.GetOutputFilename('image1.bin') 540680e3312SSimon Glass self.assertTrue(os.path.exists(fname)) 541680e3312SSimon Glass with open(fname) as fd: 542680e3312SSimon Glass data = fd.read() 543680e3312SSimon Glass self.assertEqual(U_BOOT_DATA, data) 544680e3312SSimon Glass 545680e3312SSimon Glass image = control.images['image2'] 546680e3312SSimon Glass self.assertEqual(3 + len(U_BOOT_DATA) + 5, image._size) 547680e3312SSimon Glass fname = tools.GetOutputFilename('image2.bin') 548680e3312SSimon Glass self.assertTrue(os.path.exists(fname)) 549680e3312SSimon Glass with open(fname) as fd: 550680e3312SSimon Glass data = fd.read() 551680e3312SSimon Glass self.assertEqual(U_BOOT_DATA, data[3:7]) 552680e3312SSimon Glass self.assertEqual(chr(0) * 3, data[:3]) 553680e3312SSimon Glass self.assertEqual(chr(0) * 5, data[7:]) 554680e3312SSimon Glass 555680e3312SSimon Glass def testBadAlign(self): 556680e3312SSimon Glass """Test that an invalid alignment value is detected""" 557680e3312SSimon Glass with self.assertRaises(ValueError) as e: 558741f2d62SSimon Glass self._DoTestFile('007_bad_align.dts') 559680e3312SSimon Glass self.assertIn("Node '/binman/u-boot': Alignment 23 must be a power " 560680e3312SSimon Glass "of two", str(e.exception)) 561680e3312SSimon Glass 562680e3312SSimon Glass def testPackSimple(self): 563680e3312SSimon Glass """Test that packing works as expected""" 564741f2d62SSimon Glass retcode = self._DoTestFile('008_pack.dts') 565680e3312SSimon Glass self.assertEqual(0, retcode) 566680e3312SSimon Glass self.assertIn('image', control.images) 567680e3312SSimon Glass image = control.images['image'] 5688f1da50cSSimon Glass entries = image.GetEntries() 569680e3312SSimon Glass self.assertEqual(5, len(entries)) 570680e3312SSimon Glass 571680e3312SSimon Glass # First u-boot 572680e3312SSimon Glass self.assertIn('u-boot', entries) 573680e3312SSimon Glass entry = entries['u-boot'] 5743ab9598dSSimon Glass self.assertEqual(0, entry.offset) 575680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 576680e3312SSimon Glass 577680e3312SSimon Glass # Second u-boot, aligned to 16-byte boundary 578680e3312SSimon Glass self.assertIn('u-boot-align', entries) 579680e3312SSimon Glass entry = entries['u-boot-align'] 5803ab9598dSSimon Glass self.assertEqual(16, entry.offset) 581680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 582680e3312SSimon Glass 583680e3312SSimon Glass # Third u-boot, size 23 bytes 584680e3312SSimon Glass self.assertIn('u-boot-size', entries) 585680e3312SSimon Glass entry = entries['u-boot-size'] 5863ab9598dSSimon Glass self.assertEqual(20, entry.offset) 587680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.contents_size) 588680e3312SSimon Glass self.assertEqual(23, entry.size) 589680e3312SSimon Glass 590680e3312SSimon Glass # Fourth u-boot, placed immediate after the above 591680e3312SSimon Glass self.assertIn('u-boot-next', entries) 592680e3312SSimon Glass entry = entries['u-boot-next'] 5933ab9598dSSimon Glass self.assertEqual(43, entry.offset) 594680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 595680e3312SSimon Glass 5963ab9598dSSimon Glass # Fifth u-boot, placed at a fixed offset 597680e3312SSimon Glass self.assertIn('u-boot-fixed', entries) 598680e3312SSimon Glass entry = entries['u-boot-fixed'] 5993ab9598dSSimon Glass self.assertEqual(61, entry.offset) 600680e3312SSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 601680e3312SSimon Glass 602680e3312SSimon Glass self.assertEqual(65, image._size) 603680e3312SSimon Glass 604680e3312SSimon Glass def testPackExtra(self): 605680e3312SSimon Glass """Test that extra packing feature works as expected""" 606741f2d62SSimon Glass retcode = self._DoTestFile('009_pack_extra.dts') 607680e3312SSimon Glass 608680e3312SSimon Glass self.assertEqual(0, retcode) 609680e3312SSimon Glass self.assertIn('image', control.images) 610680e3312SSimon Glass image = control.images['image'] 6118f1da50cSSimon Glass entries = image.GetEntries() 612680e3312SSimon Glass self.assertEqual(5, len(entries)) 613680e3312SSimon Glass 614680e3312SSimon Glass # First u-boot with padding before and after 615680e3312SSimon Glass self.assertIn('u-boot', entries) 616680e3312SSimon Glass entry = entries['u-boot'] 6173ab9598dSSimon Glass self.assertEqual(0, entry.offset) 618680e3312SSimon Glass self.assertEqual(3, entry.pad_before) 619680e3312SSimon Glass self.assertEqual(3 + 5 + len(U_BOOT_DATA), entry.size) 620680e3312SSimon Glass 621680e3312SSimon Glass # Second u-boot has an aligned size, but it has no effect 622680e3312SSimon Glass self.assertIn('u-boot-align-size-nop', entries) 623680e3312SSimon Glass entry = entries['u-boot-align-size-nop'] 6243ab9598dSSimon Glass self.assertEqual(12, entry.offset) 625680e3312SSimon Glass self.assertEqual(4, entry.size) 626680e3312SSimon Glass 627680e3312SSimon Glass # Third u-boot has an aligned size too 628680e3312SSimon Glass self.assertIn('u-boot-align-size', entries) 629680e3312SSimon Glass entry = entries['u-boot-align-size'] 6303ab9598dSSimon Glass self.assertEqual(16, entry.offset) 631680e3312SSimon Glass self.assertEqual(32, entry.size) 632680e3312SSimon Glass 633680e3312SSimon Glass # Fourth u-boot has an aligned end 634680e3312SSimon Glass self.assertIn('u-boot-align-end', entries) 635680e3312SSimon Glass entry = entries['u-boot-align-end'] 6363ab9598dSSimon Glass self.assertEqual(48, entry.offset) 637680e3312SSimon Glass self.assertEqual(16, entry.size) 638680e3312SSimon Glass 639680e3312SSimon Glass # Fifth u-boot immediately afterwards 640680e3312SSimon Glass self.assertIn('u-boot-align-both', entries) 641680e3312SSimon Glass entry = entries['u-boot-align-both'] 6423ab9598dSSimon Glass self.assertEqual(64, entry.offset) 643680e3312SSimon Glass self.assertEqual(64, entry.size) 644680e3312SSimon Glass 645680e3312SSimon Glass self.CheckNoGaps(entries) 646680e3312SSimon Glass self.assertEqual(128, image._size) 647680e3312SSimon Glass 648680e3312SSimon Glass def testPackAlignPowerOf2(self): 649680e3312SSimon Glass """Test that invalid entry alignment is detected""" 650680e3312SSimon Glass with self.assertRaises(ValueError) as e: 651741f2d62SSimon Glass self._DoTestFile('010_pack_align_power2.dts') 652680e3312SSimon Glass self.assertIn("Node '/binman/u-boot': Alignment 5 must be a power " 653680e3312SSimon Glass "of two", str(e.exception)) 654680e3312SSimon Glass 655680e3312SSimon Glass def testPackAlignSizePowerOf2(self): 656680e3312SSimon Glass """Test that invalid entry size alignment is detected""" 657680e3312SSimon Glass with self.assertRaises(ValueError) as e: 658741f2d62SSimon Glass self._DoTestFile('011_pack_align_size_power2.dts') 659680e3312SSimon Glass self.assertIn("Node '/binman/u-boot': Alignment size 55 must be a " 660680e3312SSimon Glass "power of two", str(e.exception)) 661680e3312SSimon Glass 662680e3312SSimon Glass def testPackInvalidAlign(self): 6633ab9598dSSimon Glass """Test detection of an offset that does not match its alignment""" 664680e3312SSimon Glass with self.assertRaises(ValueError) as e: 665741f2d62SSimon Glass self._DoTestFile('012_pack_inv_align.dts') 6663ab9598dSSimon Glass self.assertIn("Node '/binman/u-boot': Offset 0x5 (5) does not match " 667680e3312SSimon Glass "align 0x4 (4)", str(e.exception)) 668680e3312SSimon Glass 669680e3312SSimon Glass def testPackInvalidSizeAlign(self): 670680e3312SSimon Glass """Test that invalid entry size alignment is detected""" 671680e3312SSimon Glass with self.assertRaises(ValueError) as e: 672741f2d62SSimon Glass self._DoTestFile('013_pack_inv_size_align.dts') 673680e3312SSimon Glass self.assertIn("Node '/binman/u-boot': Size 0x5 (5) does not match " 674680e3312SSimon Glass "align-size 0x4 (4)", str(e.exception)) 675680e3312SSimon Glass 676680e3312SSimon Glass def testPackOverlap(self): 677680e3312SSimon Glass """Test that overlapping regions are detected""" 678680e3312SSimon Glass with self.assertRaises(ValueError) as e: 679741f2d62SSimon Glass self._DoTestFile('014_pack_overlap.dts') 6803ab9598dSSimon Glass self.assertIn("Node '/binman/u-boot-align': Offset 0x3 (3) overlaps " 681680e3312SSimon Glass "with previous entry '/binman/u-boot' ending at 0x4 (4)", 682680e3312SSimon Glass str(e.exception)) 683680e3312SSimon Glass 684680e3312SSimon Glass def testPackEntryOverflow(self): 685680e3312SSimon Glass """Test that entries that overflow their size are detected""" 686680e3312SSimon Glass with self.assertRaises(ValueError) as e: 687741f2d62SSimon Glass self._DoTestFile('015_pack_overflow.dts') 688680e3312SSimon Glass self.assertIn("Node '/binman/u-boot': Entry contents size is 0x4 (4) " 689680e3312SSimon Glass "but entry size is 0x3 (3)", str(e.exception)) 690680e3312SSimon Glass 691680e3312SSimon Glass def testPackImageOverflow(self): 692680e3312SSimon Glass """Test that entries which overflow the image size are detected""" 693680e3312SSimon Glass with self.assertRaises(ValueError) as e: 694741f2d62SSimon Glass self._DoTestFile('016_pack_image_overflow.dts') 6958f1da50cSSimon Glass self.assertIn("Section '/binman': contents size 0x4 (4) exceeds section " 696680e3312SSimon Glass "size 0x3 (3)", str(e.exception)) 697680e3312SSimon Glass 698680e3312SSimon Glass def testPackImageSize(self): 699680e3312SSimon Glass """Test that the image size can be set""" 700741f2d62SSimon Glass retcode = self._DoTestFile('017_pack_image_size.dts') 701680e3312SSimon Glass self.assertEqual(0, retcode) 702680e3312SSimon Glass self.assertIn('image', control.images) 703680e3312SSimon Glass image = control.images['image'] 704680e3312SSimon Glass self.assertEqual(7, image._size) 705680e3312SSimon Glass 706680e3312SSimon Glass def testPackImageSizeAlign(self): 707680e3312SSimon Glass """Test that image size alignemnt works as expected""" 708741f2d62SSimon Glass retcode = self._DoTestFile('018_pack_image_align.dts') 709680e3312SSimon Glass self.assertEqual(0, retcode) 710680e3312SSimon Glass self.assertIn('image', control.images) 711680e3312SSimon Glass image = control.images['image'] 712680e3312SSimon Glass self.assertEqual(16, image._size) 713680e3312SSimon Glass 714680e3312SSimon Glass def testPackInvalidImageAlign(self): 715680e3312SSimon Glass """Test that invalid image alignment is detected""" 716680e3312SSimon Glass with self.assertRaises(ValueError) as e: 717741f2d62SSimon Glass self._DoTestFile('019_pack_inv_image_align.dts') 7188f1da50cSSimon Glass self.assertIn("Section '/binman': Size 0x7 (7) does not match " 719680e3312SSimon Glass "align-size 0x8 (8)", str(e.exception)) 720680e3312SSimon Glass 721680e3312SSimon Glass def testPackAlignPowerOf2(self): 722680e3312SSimon Glass """Test that invalid image alignment is detected""" 723680e3312SSimon Glass with self.assertRaises(ValueError) as e: 724741f2d62SSimon Glass self._DoTestFile('020_pack_inv_image_align_power2.dts') 7258f1da50cSSimon Glass self.assertIn("Section '/binman': Alignment size 131 must be a power of " 726680e3312SSimon Glass "two", str(e.exception)) 727680e3312SSimon Glass 728680e3312SSimon Glass def testImagePadByte(self): 729680e3312SSimon Glass """Test that the image pad byte can be specified""" 73011ae93eeSSimon Glass self._SetupSplElf() 731741f2d62SSimon Glass data = self._DoReadFile('021_image_pad.dts') 732f689890dSSimon Glass self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 1) + U_BOOT_DATA, data) 733680e3312SSimon Glass 734680e3312SSimon Glass def testImageName(self): 735680e3312SSimon Glass """Test that image files can be named""" 736741f2d62SSimon Glass retcode = self._DoTestFile('022_image_name.dts') 737680e3312SSimon Glass self.assertEqual(0, retcode) 738680e3312SSimon Glass image = control.images['image1'] 739680e3312SSimon Glass fname = tools.GetOutputFilename('test-name') 740680e3312SSimon Glass self.assertTrue(os.path.exists(fname)) 741680e3312SSimon Glass 742680e3312SSimon Glass image = control.images['image2'] 743680e3312SSimon Glass fname = tools.GetOutputFilename('test-name.xx') 744680e3312SSimon Glass self.assertTrue(os.path.exists(fname)) 745680e3312SSimon Glass 746680e3312SSimon Glass def testBlobFilename(self): 747680e3312SSimon Glass """Test that generic blobs can be provided by filename""" 748741f2d62SSimon Glass data = self._DoReadFile('023_blob.dts') 749680e3312SSimon Glass self.assertEqual(BLOB_DATA, data) 750680e3312SSimon Glass 751680e3312SSimon Glass def testPackSorted(self): 752680e3312SSimon Glass """Test that entries can be sorted""" 75311ae93eeSSimon Glass self._SetupSplElf() 754741f2d62SSimon Glass data = self._DoReadFile('024_sorted.dts') 755f689890dSSimon Glass self.assertEqual(chr(0) * 1 + U_BOOT_SPL_DATA + chr(0) * 2 + 756680e3312SSimon Glass U_BOOT_DATA, data) 757680e3312SSimon Glass 7583ab9598dSSimon Glass def testPackZeroOffset(self): 7593ab9598dSSimon Glass """Test that an entry at offset 0 is not given a new offset""" 760680e3312SSimon Glass with self.assertRaises(ValueError) as e: 761741f2d62SSimon Glass self._DoTestFile('025_pack_zero_size.dts') 7623ab9598dSSimon Glass self.assertIn("Node '/binman/u-boot-spl': Offset 0x0 (0) overlaps " 763680e3312SSimon Glass "with previous entry '/binman/u-boot' ending at 0x4 (4)", 764680e3312SSimon Glass str(e.exception)) 765680e3312SSimon Glass 766680e3312SSimon Glass def testPackUbootDtb(self): 767680e3312SSimon Glass """Test that a device tree can be added to U-Boot""" 768741f2d62SSimon Glass data = self._DoReadFile('026_pack_u_boot_dtb.dts') 769680e3312SSimon Glass self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA, data) 770680e3312SSimon Glass 771680e3312SSimon Glass def testPackX86RomNoSize(self): 772680e3312SSimon Glass """Test that the end-at-4gb property requires a size property""" 773680e3312SSimon Glass with self.assertRaises(ValueError) as e: 774741f2d62SSimon Glass self._DoTestFile('027_pack_4gb_no_size.dts') 7758f1da50cSSimon Glass self.assertIn("Section '/binman': Section size must be provided when " 776680e3312SSimon Glass "using end-at-4gb", str(e.exception)) 777680e3312SSimon Glass 77894b57db0SJagdish Gediya def test4gbAndSkipAtStartTogether(self): 77994b57db0SJagdish Gediya """Test that the end-at-4gb and skip-at-size property can't be used 78094b57db0SJagdish Gediya together""" 78194b57db0SJagdish Gediya with self.assertRaises(ValueError) as e: 78294b57db0SJagdish Gediya self._DoTestFile('80_4gb_and_skip_at_start_together.dts') 78394b57db0SJagdish Gediya self.assertIn("Section '/binman': Provide either 'end-at-4gb' or " 78494b57db0SJagdish Gediya "'skip-at-start'", str(e.exception)) 78594b57db0SJagdish Gediya 786680e3312SSimon Glass def testPackX86RomOutside(self): 7873ab9598dSSimon Glass """Test that the end-at-4gb property checks for offset boundaries""" 788680e3312SSimon Glass with self.assertRaises(ValueError) as e: 789741f2d62SSimon Glass self._DoTestFile('028_pack_4gb_outside.dts') 7903ab9598dSSimon Glass self.assertIn("Node '/binman/u-boot': Offset 0x0 (0) is outside " 7918f1da50cSSimon Glass "the section starting at 0xffffffe0 (4294967264)", 792680e3312SSimon Glass str(e.exception)) 793680e3312SSimon Glass 794680e3312SSimon Glass def testPackX86Rom(self): 795680e3312SSimon Glass """Test that a basic x86 ROM can be created""" 79611ae93eeSSimon Glass self._SetupSplElf() 797741f2d62SSimon Glass data = self._DoReadFile('029_x86-rom.dts') 798f689890dSSimon Glass self.assertEqual(U_BOOT_DATA + chr(0) * 7 + U_BOOT_SPL_DATA + 799f689890dSSimon Glass chr(0) * 2, data) 800680e3312SSimon Glass 801680e3312SSimon Glass def testPackX86RomMeNoDesc(self): 802680e3312SSimon Glass """Test that an invalid Intel descriptor entry is detected""" 803680e3312SSimon Glass TestFunctional._MakeInputFile('descriptor.bin', '') 804680e3312SSimon Glass with self.assertRaises(ValueError) as e: 805741f2d62SSimon Glass self._DoTestFile('031_x86-rom-me.dts') 806680e3312SSimon Glass self.assertIn("Node '/binman/intel-descriptor': Cannot find FD " 807680e3312SSimon Glass "signature", str(e.exception)) 808680e3312SSimon Glass 809680e3312SSimon Glass def testPackX86RomBadDesc(self): 810680e3312SSimon Glass """Test that the Intel requires a descriptor entry""" 811680e3312SSimon Glass with self.assertRaises(ValueError) as e: 812741f2d62SSimon Glass self._DoTestFile('030_x86-rom-me-no-desc.dts') 8133ab9598dSSimon Glass self.assertIn("Node '/binman/intel-me': No offset set with " 8143ab9598dSSimon Glass "offset-unset: should another entry provide this correct " 8153ab9598dSSimon Glass "offset?", str(e.exception)) 816680e3312SSimon Glass 817680e3312SSimon Glass def testPackX86RomMe(self): 818680e3312SSimon Glass """Test that an x86 ROM with an ME region can be created""" 819741f2d62SSimon Glass data = self._DoReadFile('031_x86-rom-me.dts') 820680e3312SSimon Glass self.assertEqual(ME_DATA, data[0x1000:0x1000 + len(ME_DATA)]) 821680e3312SSimon Glass 822680e3312SSimon Glass def testPackVga(self): 823680e3312SSimon Glass """Test that an image with a VGA binary can be created""" 824741f2d62SSimon Glass data = self._DoReadFile('032_intel-vga.dts') 825680e3312SSimon Glass self.assertEqual(VGA_DATA, data[:len(VGA_DATA)]) 826680e3312SSimon Glass 827680e3312SSimon Glass def testPackStart16(self): 828680e3312SSimon Glass """Test that an image with an x86 start16 region can be created""" 829741f2d62SSimon Glass data = self._DoReadFile('033_x86-start16.dts') 830680e3312SSimon Glass self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)]) 831680e3312SSimon Glass 8329d368f32SJagdish Gediya def testPackPowerpcMpc85xxBootpgResetvec(self): 8339d368f32SJagdish Gediya """Test that an image with powerpc-mpc85xx-bootpg-resetvec can be 8349d368f32SJagdish Gediya created""" 8359d368f32SJagdish Gediya data = self._DoReadFile('81_powerpc_mpc85xx_bootpg_resetvec.dts') 8369d368f32SJagdish Gediya self.assertEqual(PPC_MPC85XX_BR_DATA, data[:len(PPC_MPC85XX_BR_DATA)]) 8379d368f32SJagdish Gediya 838736bb0aeSSimon Glass def _RunMicrocodeTest(self, dts_fname, nodtb_data, ucode_second=False): 839adc57011SSimon Glass """Handle running a test for insertion of microcode 840adc57011SSimon Glass 841adc57011SSimon Glass Args: 842adc57011SSimon Glass dts_fname: Name of test .dts file 843adc57011SSimon Glass nodtb_data: Data that we expect in the first section 844736bb0aeSSimon Glass ucode_second: True if the microsecond entry is second instead of 845736bb0aeSSimon Glass third 846adc57011SSimon Glass 847adc57011SSimon Glass Returns: 848adc57011SSimon Glass Tuple: 849adc57011SSimon Glass Contents of first region (U-Boot or SPL) 8503ab9598dSSimon Glass Offset and size components of microcode pointer, as inserted 851adc57011SSimon Glass in the above (two 4-byte words) 852adc57011SSimon Glass """ 8536b187df7SSimon Glass data = self._DoReadFile(dts_fname, True) 854680e3312SSimon Glass 855680e3312SSimon Glass # Now check the device tree has no microcode 856736bb0aeSSimon Glass if ucode_second: 857736bb0aeSSimon Glass ucode_content = data[len(nodtb_data):] 858736bb0aeSSimon Glass ucode_pos = len(nodtb_data) 859736bb0aeSSimon Glass dtb_with_ucode = ucode_content[16:] 860736bb0aeSSimon Glass fdt_len = self.GetFdtLen(dtb_with_ucode) 861736bb0aeSSimon Glass else: 862adc57011SSimon Glass dtb_with_ucode = data[len(nodtb_data):] 863adc57011SSimon Glass fdt_len = self.GetFdtLen(dtb_with_ucode) 864adc57011SSimon Glass ucode_content = dtb_with_ucode[fdt_len:] 865adc57011SSimon Glass ucode_pos = len(nodtb_data) + fdt_len 866680e3312SSimon Glass fname = tools.GetOutputFilename('test.dtb') 867680e3312SSimon Glass with open(fname, 'wb') as fd: 868adc57011SSimon Glass fd.write(dtb_with_ucode) 869680e3312SSimon Glass dtb = fdt.FdtScan(fname) 870680e3312SSimon Glass ucode = dtb.GetNode('/microcode') 871680e3312SSimon Glass self.assertTrue(ucode) 872680e3312SSimon Glass for node in ucode.subnodes: 873680e3312SSimon Glass self.assertFalse(node.props.get('data')) 874680e3312SSimon Glass 875680e3312SSimon Glass # Check that the microcode appears immediately after the Fdt 876680e3312SSimon Glass # This matches the concatenation of the data properties in 8778772213eSSimon Glass # the /microcode/update@xxx nodes in 34_x86_ucode.dts. 878680e3312SSimon Glass ucode_data = struct.pack('>4L', 0x12345678, 0x12345679, 0xabcd0000, 879680e3312SSimon Glass 0x78235609) 880adc57011SSimon Glass self.assertEqual(ucode_data, ucode_content[:len(ucode_data)]) 881680e3312SSimon Glass 882680e3312SSimon Glass # Check that the microcode pointer was inserted. It should match the 8833ab9598dSSimon Glass # expected offset and size 884680e3312SSimon Glass pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos, 885680e3312SSimon Glass len(ucode_data)) 886736bb0aeSSimon Glass u_boot = data[:len(nodtb_data)] 887736bb0aeSSimon Glass return u_boot, pos_and_size 8886b187df7SSimon Glass 8896b187df7SSimon Glass def testPackUbootMicrocode(self): 8906b187df7SSimon Glass """Test that x86 microcode can be handled correctly 8916b187df7SSimon Glass 8926b187df7SSimon Glass We expect to see the following in the image, in order: 8936b187df7SSimon Glass u-boot-nodtb.bin with a microcode pointer inserted at the correct 8946b187df7SSimon Glass place 8956b187df7SSimon Glass u-boot.dtb with the microcode removed 8966b187df7SSimon Glass the microcode 8976b187df7SSimon Glass """ 898741f2d62SSimon Glass first, pos_and_size = self._RunMicrocodeTest('034_x86_ucode.dts', 8996b187df7SSimon Glass U_BOOT_NODTB_DATA) 900680e3312SSimon Glass self.assertEqual('nodtb with microcode' + pos_and_size + 901680e3312SSimon Glass ' somewhere in here', first) 902680e3312SSimon Glass 903680e3312SSimon Glass def _RunPackUbootSingleMicrocode(self): 904680e3312SSimon Glass """Test that x86 microcode can be handled correctly 905680e3312SSimon Glass 906680e3312SSimon Glass We expect to see the following in the image, in order: 907680e3312SSimon Glass u-boot-nodtb.bin with a microcode pointer inserted at the correct 908680e3312SSimon Glass place 909680e3312SSimon Glass u-boot.dtb with the microcode 910680e3312SSimon Glass an empty microcode region 911680e3312SSimon Glass """ 912680e3312SSimon Glass # We need the libfdt library to run this test since only that allows 913680e3312SSimon Glass # finding the offset of a property. This is required by 914680e3312SSimon Glass # Entry_u_boot_dtb_with_ucode.ObtainContents(). 915741f2d62SSimon Glass data = self._DoReadFile('035_x86_single_ucode.dts', True) 916680e3312SSimon Glass 917680e3312SSimon Glass second = data[len(U_BOOT_NODTB_DATA):] 918680e3312SSimon Glass 919680e3312SSimon Glass fdt_len = self.GetFdtLen(second) 920680e3312SSimon Glass third = second[fdt_len:] 921680e3312SSimon Glass second = second[:fdt_len] 922680e3312SSimon Glass 923680e3312SSimon Glass ucode_data = struct.pack('>2L', 0x12345678, 0x12345679) 924680e3312SSimon Glass self.assertIn(ucode_data, second) 925680e3312SSimon Glass ucode_pos = second.find(ucode_data) + len(U_BOOT_NODTB_DATA) 926680e3312SSimon Glass 927680e3312SSimon Glass # Check that the microcode pointer was inserted. It should match the 9283ab9598dSSimon Glass # expected offset and size 929680e3312SSimon Glass pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos, 930680e3312SSimon Glass len(ucode_data)) 931680e3312SSimon Glass first = data[:len(U_BOOT_NODTB_DATA)] 932680e3312SSimon Glass self.assertEqual('nodtb with microcode' + pos_and_size + 933680e3312SSimon Glass ' somewhere in here', first) 934680e3312SSimon Glass 935680e3312SSimon Glass def testPackUbootSingleMicrocode(self): 936680e3312SSimon Glass """Test that x86 microcode can be handled correctly with fdt_normal. 937680e3312SSimon Glass """ 938680e3312SSimon Glass self._RunPackUbootSingleMicrocode() 939680e3312SSimon Glass 940680e3312SSimon Glass def testUBootImg(self): 941680e3312SSimon Glass """Test that u-boot.img can be put in a file""" 942741f2d62SSimon Glass data = self._DoReadFile('036_u_boot_img.dts') 943680e3312SSimon Glass self.assertEqual(U_BOOT_IMG_DATA, data) 944680e3312SSimon Glass 945680e3312SSimon Glass def testNoMicrocode(self): 946680e3312SSimon Glass """Test that a missing microcode region is detected""" 947680e3312SSimon Glass with self.assertRaises(ValueError) as e: 948741f2d62SSimon Glass self._DoReadFile('037_x86_no_ucode.dts', True) 949680e3312SSimon Glass self.assertIn("Node '/binman/u-boot-dtb-with-ucode': No /microcode " 950680e3312SSimon Glass "node found in ", str(e.exception)) 951680e3312SSimon Glass 952680e3312SSimon Glass def testMicrocodeWithoutNode(self): 953680e3312SSimon Glass """Test that a missing u-boot-dtb-with-ucode node is detected""" 954680e3312SSimon Glass with self.assertRaises(ValueError) as e: 955741f2d62SSimon Glass self._DoReadFile('038_x86_ucode_missing_node.dts', True) 956680e3312SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot find " 957680e3312SSimon Glass "microcode region u-boot-dtb-with-ucode", str(e.exception)) 958680e3312SSimon Glass 959680e3312SSimon Glass def testMicrocodeWithoutNode2(self): 960680e3312SSimon Glass """Test that a missing u-boot-ucode node is detected""" 961680e3312SSimon Glass with self.assertRaises(ValueError) as e: 962741f2d62SSimon Glass self._DoReadFile('039_x86_ucode_missing_node2.dts', True) 963680e3312SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot find " 964680e3312SSimon Glass "microcode region u-boot-ucode", str(e.exception)) 965680e3312SSimon Glass 966680e3312SSimon Glass def testMicrocodeWithoutPtrInElf(self): 967680e3312SSimon Glass """Test that a U-Boot binary without the microcode symbol is detected""" 968680e3312SSimon Glass # ELF file without a '_dt_ucode_base_size' symbol 969680e3312SSimon Glass try: 970680e3312SSimon Glass with open(self.TestFile('u_boot_no_ucode_ptr')) as fd: 971680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 972680e3312SSimon Glass 973680e3312SSimon Glass with self.assertRaises(ValueError) as e: 974680e3312SSimon Glass self._RunPackUbootSingleMicrocode() 975680e3312SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot locate " 976680e3312SSimon Glass "_dt_ucode_base_size symbol in u-boot", str(e.exception)) 977680e3312SSimon Glass 978680e3312SSimon Glass finally: 979680e3312SSimon Glass # Put the original file back 980680e3312SSimon Glass with open(self.TestFile('u_boot_ucode_ptr')) as fd: 981680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 982680e3312SSimon Glass 983680e3312SSimon Glass def testMicrocodeNotInImage(self): 984680e3312SSimon Glass """Test that microcode must be placed within the image""" 985680e3312SSimon Glass with self.assertRaises(ValueError) as e: 986741f2d62SSimon Glass self._DoReadFile('040_x86_ucode_not_in_image.dts', True) 987680e3312SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Microcode " 988680e3312SSimon Glass "pointer _dt_ucode_base_size at fffffe14 is outside the " 98925ac0e61SSimon Glass "section ranging from 00000000 to 0000002e", str(e.exception)) 990680e3312SSimon Glass 991680e3312SSimon Glass def testWithoutMicrocode(self): 992680e3312SSimon Glass """Test that we can cope with an image without microcode (e.g. qemu)""" 993680e3312SSimon Glass with open(self.TestFile('u_boot_no_ucode_ptr')) as fd: 994680e3312SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 995741f2d62SSimon Glass data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True) 996680e3312SSimon Glass 997680e3312SSimon Glass # Now check the device tree has no microcode 998680e3312SSimon Glass self.assertEqual(U_BOOT_NODTB_DATA, data[:len(U_BOOT_NODTB_DATA)]) 999680e3312SSimon Glass second = data[len(U_BOOT_NODTB_DATA):] 1000680e3312SSimon Glass 1001680e3312SSimon Glass fdt_len = self.GetFdtLen(second) 1002680e3312SSimon Glass self.assertEqual(dtb, second[:fdt_len]) 1003680e3312SSimon Glass 1004680e3312SSimon Glass used_len = len(U_BOOT_NODTB_DATA) + fdt_len 1005680e3312SSimon Glass third = data[used_len:] 1006680e3312SSimon Glass self.assertEqual(chr(0) * (0x200 - used_len), third) 1007680e3312SSimon Glass 1008680e3312SSimon Glass def testUnknownPosSize(self): 1009680e3312SSimon Glass """Test that microcode must be placed within the image""" 1010680e3312SSimon Glass with self.assertRaises(ValueError) as e: 1011741f2d62SSimon Glass self._DoReadFile('041_unknown_pos_size.dts', True) 10123ab9598dSSimon Glass self.assertIn("Section '/binman': Unable to set offset/size for unknown " 1013680e3312SSimon Glass "entry 'invalid-entry'", str(e.exception)) 1014680e3312SSimon Glass 1015680e3312SSimon Glass def testPackFsp(self): 1016680e3312SSimon Glass """Test that an image with a FSP binary can be created""" 1017741f2d62SSimon Glass data = self._DoReadFile('042_intel-fsp.dts') 1018680e3312SSimon Glass self.assertEqual(FSP_DATA, data[:len(FSP_DATA)]) 1019680e3312SSimon Glass 1020680e3312SSimon Glass def testPackCmc(self): 1021680e3312SSimon Glass """Test that an image with a CMC binary can be created""" 1022741f2d62SSimon Glass data = self._DoReadFile('043_intel-cmc.dts') 1023680e3312SSimon Glass self.assertEqual(CMC_DATA, data[:len(CMC_DATA)]) 1024680e3312SSimon Glass 1025680e3312SSimon Glass def testPackVbt(self): 1026680e3312SSimon Glass """Test that an image with a VBT binary can be created""" 1027741f2d62SSimon Glass data = self._DoReadFile('046_intel-vbt.dts') 1028680e3312SSimon Glass self.assertEqual(VBT_DATA, data[:len(VBT_DATA)]) 10299fc60b49SSimon Glass 103056509843SSimon Glass def testSplBssPad(self): 103156509843SSimon Glass """Test that we can pad SPL's BSS with zeros""" 10326b187df7SSimon Glass # ELF file with a '__bss_size' symbol 103311ae93eeSSimon Glass self._SetupSplElf() 1034741f2d62SSimon Glass data = self._DoReadFile('047_spl_bss_pad.dts') 103556509843SSimon Glass self.assertEqual(U_BOOT_SPL_DATA + (chr(0) * 10) + U_BOOT_DATA, data) 103656509843SSimon Glass 103786af511dSSimon Glass def testSplBssPadMissing(self): 103886af511dSSimon Glass """Test that a missing symbol is detected""" 103911ae93eeSSimon Glass self._SetupSplElf('u_boot_ucode_ptr') 1040b50e5611SSimon Glass with self.assertRaises(ValueError) as e: 1041741f2d62SSimon Glass self._DoReadFile('047_spl_bss_pad.dts') 1042b50e5611SSimon Glass self.assertIn('Expected __bss_size symbol in spl/u-boot-spl', 1043b50e5611SSimon Glass str(e.exception)) 1044b50e5611SSimon Glass 10458772213eSSimon Glass def testPackStart16Spl(self): 104635b384cbSSimon Glass """Test that an image with an x86 start16 SPL region can be created""" 1047741f2d62SSimon Glass data = self._DoReadFile('048_x86-start16-spl.dts') 10488772213eSSimon Glass self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)]) 10498772213eSSimon Glass 1050736bb0aeSSimon Glass def _PackUbootSplMicrocode(self, dts, ucode_second=False): 1051736bb0aeSSimon Glass """Helper function for microcode tests 10526b187df7SSimon Glass 10536b187df7SSimon Glass We expect to see the following in the image, in order: 10546b187df7SSimon Glass u-boot-spl-nodtb.bin with a microcode pointer inserted at the 10556b187df7SSimon Glass correct place 10566b187df7SSimon Glass u-boot.dtb with the microcode removed 10576b187df7SSimon Glass the microcode 1058736bb0aeSSimon Glass 1059736bb0aeSSimon Glass Args: 1060736bb0aeSSimon Glass dts: Device tree file to use for test 1061736bb0aeSSimon Glass ucode_second: True if the microsecond entry is second instead of 1062736bb0aeSSimon Glass third 10636b187df7SSimon Glass """ 106411ae93eeSSimon Glass self._SetupSplElf('u_boot_ucode_ptr') 1065736bb0aeSSimon Glass first, pos_and_size = self._RunMicrocodeTest(dts, U_BOOT_SPL_NODTB_DATA, 1066736bb0aeSSimon Glass ucode_second=ucode_second) 10676b187df7SSimon Glass self.assertEqual('splnodtb with microc' + pos_and_size + 10686b187df7SSimon Glass 'ter somewhere in here', first) 10696b187df7SSimon Glass 1070736bb0aeSSimon Glass def testPackUbootSplMicrocode(self): 1071736bb0aeSSimon Glass """Test that x86 microcode can be handled correctly in SPL""" 1072741f2d62SSimon Glass self._PackUbootSplMicrocode('049_x86_ucode_spl.dts') 1073736bb0aeSSimon Glass 1074736bb0aeSSimon Glass def testPackUbootSplMicrocodeReorder(self): 1075736bb0aeSSimon Glass """Test that order doesn't matter for microcode entries 1076736bb0aeSSimon Glass 1077736bb0aeSSimon Glass This is the same as testPackUbootSplMicrocode but when we process the 1078736bb0aeSSimon Glass u-boot-ucode entry we have not yet seen the u-boot-dtb-with-ucode 1079736bb0aeSSimon Glass entry, so we reply on binman to try later. 1080736bb0aeSSimon Glass """ 1081741f2d62SSimon Glass self._PackUbootSplMicrocode('058_x86_ucode_spl_needs_retry.dts', 1082736bb0aeSSimon Glass ucode_second=True) 1083736bb0aeSSimon Glass 1084ca4f4ff7SSimon Glass def testPackMrc(self): 1085ca4f4ff7SSimon Glass """Test that an image with an MRC binary can be created""" 1086741f2d62SSimon Glass data = self._DoReadFile('050_intel_mrc.dts') 1087ca4f4ff7SSimon Glass self.assertEqual(MRC_DATA, data[:len(MRC_DATA)]) 1088ca4f4ff7SSimon Glass 108947419eaeSSimon Glass def testSplDtb(self): 109047419eaeSSimon Glass """Test that an image with spl/u-boot-spl.dtb can be created""" 1091741f2d62SSimon Glass data = self._DoReadFile('051_u_boot_spl_dtb.dts') 109247419eaeSSimon Glass self.assertEqual(U_BOOT_SPL_DTB_DATA, data[:len(U_BOOT_SPL_DTB_DATA)]) 109347419eaeSSimon Glass 10944e6fdbefSSimon Glass def testSplNoDtb(self): 10954e6fdbefSSimon Glass """Test that an image with spl/u-boot-spl-nodtb.bin can be created""" 1096741f2d62SSimon Glass data = self._DoReadFile('052_u_boot_spl_nodtb.dts') 10974e6fdbefSSimon Glass self.assertEqual(U_BOOT_SPL_NODTB_DATA, data[:len(U_BOOT_SPL_NODTB_DATA)]) 10984e6fdbefSSimon Glass 109919790632SSimon Glass def testSymbols(self): 110019790632SSimon Glass """Test binman can assign symbols embedded in U-Boot""" 110119790632SSimon Glass elf_fname = self.TestFile('u_boot_binman_syms') 110219790632SSimon Glass syms = elf.GetSymbols(elf_fname, ['binman', 'image']) 110319790632SSimon Glass addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start') 11043ab9598dSSimon Glass self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr) 110519790632SSimon Glass 110611ae93eeSSimon Glass self._SetupSplElf('u_boot_binman_syms') 1107741f2d62SSimon Glass data = self._DoReadFile('053_symbols.dts') 110819790632SSimon Glass sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20) 110919790632SSimon Glass expected = (sym_values + U_BOOT_SPL_DATA[16:] + chr(0xff) + 111019790632SSimon Glass U_BOOT_DATA + 111119790632SSimon Glass sym_values + U_BOOT_SPL_DATA[16:]) 111219790632SSimon Glass self.assertEqual(expected, data) 111319790632SSimon Glass 1114dd57c13bSSimon Glass def testPackUnitAddress(self): 1115dd57c13bSSimon Glass """Test that we support multiple binaries with the same name""" 1116741f2d62SSimon Glass data = self._DoReadFile('054_unit_address.dts') 1117dd57c13bSSimon Glass self.assertEqual(U_BOOT_DATA + U_BOOT_DATA, data) 1118dd57c13bSSimon Glass 11191854695bSSimon Glass def testSections(self): 11201854695bSSimon Glass """Basic test of sections""" 1121741f2d62SSimon Glass data = self._DoReadFile('055_sections.dts') 11228122f396SSimon Glass expected = (U_BOOT_DATA + '!' * 12 + U_BOOT_DATA + 'a' * 12 + 11238122f396SSimon Glass U_BOOT_DATA + '&' * 4) 11241854695bSSimon Glass self.assertEqual(expected, data) 11259fc60b49SSimon Glass 11263b0c3821SSimon Glass def testMap(self): 11273b0c3821SSimon Glass """Tests outputting a map of the images""" 1128741f2d62SSimon Glass _, _, map_data, _ = self._DoReadFileDtb('055_sections.dts', map=True) 11291be70d20SSimon Glass self.assertEqual('''ImagePos Offset Size Name 11301be70d20SSimon Glass00000000 00000000 00000028 main-section 11311be70d20SSimon Glass00000000 00000000 00000010 section@0 11321be70d20SSimon Glass00000000 00000000 00000004 u-boot 11331be70d20SSimon Glass00000010 00000010 00000010 section@1 11341be70d20SSimon Glass00000010 00000000 00000004 u-boot 11351be70d20SSimon Glass00000020 00000020 00000004 section@2 11361be70d20SSimon Glass00000020 00000000 00000004 u-boot 11373b0c3821SSimon Glass''', map_data) 11383b0c3821SSimon Glass 1139c8d48efbSSimon Glass def testNamePrefix(self): 1140c8d48efbSSimon Glass """Tests that name prefixes are used""" 1141741f2d62SSimon Glass _, _, map_data, _ = self._DoReadFileDtb('056_name_prefix.dts', map=True) 11421be70d20SSimon Glass self.assertEqual('''ImagePos Offset Size Name 11431be70d20SSimon Glass00000000 00000000 00000028 main-section 11441be70d20SSimon Glass00000000 00000000 00000010 section@0 11451be70d20SSimon Glass00000000 00000000 00000004 ro-u-boot 11461be70d20SSimon Glass00000010 00000010 00000010 section@1 11471be70d20SSimon Glass00000010 00000000 00000004 rw-u-boot 1148c8d48efbSSimon Glass''', map_data) 1149c8d48efbSSimon Glass 1150736bb0aeSSimon Glass def testUnknownContents(self): 1151736bb0aeSSimon Glass """Test that obtaining the contents works as expected""" 1152736bb0aeSSimon Glass with self.assertRaises(ValueError) as e: 1153741f2d62SSimon Glass self._DoReadFile('057_unknown_contents.dts', True) 1154736bb0aeSSimon Glass self.assertIn("Section '/binman': Internal error: Could not complete " 1155736bb0aeSSimon Glass "processing of contents: remaining [<_testing.Entry__testing ", 1156736bb0aeSSimon Glass str(e.exception)) 1157736bb0aeSSimon Glass 11585c890238SSimon Glass def testBadChangeSize(self): 11595c890238SSimon Glass """Test that trying to change the size of an entry fails""" 11605c890238SSimon Glass with self.assertRaises(ValueError) as e: 1161741f2d62SSimon Glass self._DoReadFile('059_change_size.dts', True) 11625c890238SSimon Glass self.assertIn("Node '/binman/_testing': Cannot update entry size from " 11635c890238SSimon Glass '2 to 1', str(e.exception)) 11645c890238SSimon Glass 116516b8d6b7SSimon Glass def testUpdateFdt(self): 11663ab9598dSSimon Glass """Test that we can update the device tree with offset/size info""" 1167741f2d62SSimon Glass _, _, _, out_dtb_fname = self._DoReadFileDtb('060_fdt_update.dts', 116816b8d6b7SSimon Glass update_dtb=True) 1169cee02e6fSSimon Glass dtb = fdt.Fdt(out_dtb_fname) 1170cee02e6fSSimon Glass dtb.Scan() 1171cee02e6fSSimon Glass props = self._GetPropTree(dtb, ['offset', 'size', 'image-pos']) 117216b8d6b7SSimon Glass self.assertEqual({ 1173dbf6be9fSSimon Glass 'image-pos': 0, 11748122f396SSimon Glass 'offset': 0, 11753ab9598dSSimon Glass '_testing:offset': 32, 117616b8d6b7SSimon Glass '_testing:size': 1, 1177dbf6be9fSSimon Glass '_testing:image-pos': 32, 11783ab9598dSSimon Glass 'section@0/u-boot:offset': 0, 117916b8d6b7SSimon Glass 'section@0/u-boot:size': len(U_BOOT_DATA), 1180dbf6be9fSSimon Glass 'section@0/u-boot:image-pos': 0, 11813ab9598dSSimon Glass 'section@0:offset': 0, 118216b8d6b7SSimon Glass 'section@0:size': 16, 1183dbf6be9fSSimon Glass 'section@0:image-pos': 0, 118416b8d6b7SSimon Glass 11853ab9598dSSimon Glass 'section@1/u-boot:offset': 0, 118616b8d6b7SSimon Glass 'section@1/u-boot:size': len(U_BOOT_DATA), 1187dbf6be9fSSimon Glass 'section@1/u-boot:image-pos': 16, 11883ab9598dSSimon Glass 'section@1:offset': 16, 118916b8d6b7SSimon Glass 'section@1:size': 16, 1190dbf6be9fSSimon Glass 'section@1:image-pos': 16, 119116b8d6b7SSimon Glass 'size': 40 119216b8d6b7SSimon Glass }, props) 119316b8d6b7SSimon Glass 119416b8d6b7SSimon Glass def testUpdateFdtBad(self): 119516b8d6b7SSimon Glass """Test that we detect when ProcessFdt never completes""" 119616b8d6b7SSimon Glass with self.assertRaises(ValueError) as e: 1197741f2d62SSimon Glass self._DoReadFileDtb('061_fdt_update_bad.dts', update_dtb=True) 119816b8d6b7SSimon Glass self.assertIn('Could not complete processing of Fdt: remaining ' 119916b8d6b7SSimon Glass '[<_testing.Entry__testing', str(e.exception)) 12005c890238SSimon Glass 120153af22a9SSimon Glass def testEntryArgs(self): 120253af22a9SSimon Glass """Test passing arguments to entries from the command line""" 120353af22a9SSimon Glass entry_args = { 120453af22a9SSimon Glass 'test-str-arg': 'test1', 120553af22a9SSimon Glass 'test-int-arg': '456', 120653af22a9SSimon Glass } 1207741f2d62SSimon Glass self._DoReadFileDtb('062_entry_args.dts', entry_args=entry_args) 120853af22a9SSimon Glass self.assertIn('image', control.images) 120953af22a9SSimon Glass entry = control.images['image'].GetEntries()['_testing'] 121053af22a9SSimon Glass self.assertEqual('test0', entry.test_str_fdt) 121153af22a9SSimon Glass self.assertEqual('test1', entry.test_str_arg) 121253af22a9SSimon Glass self.assertEqual(123, entry.test_int_fdt) 121353af22a9SSimon Glass self.assertEqual(456, entry.test_int_arg) 121453af22a9SSimon Glass 121553af22a9SSimon Glass def testEntryArgsMissing(self): 121653af22a9SSimon Glass """Test missing arguments and properties""" 121753af22a9SSimon Glass entry_args = { 121853af22a9SSimon Glass 'test-int-arg': '456', 121953af22a9SSimon Glass } 1220741f2d62SSimon Glass self._DoReadFileDtb('063_entry_args_missing.dts', entry_args=entry_args) 122153af22a9SSimon Glass entry = control.images['image'].GetEntries()['_testing'] 122253af22a9SSimon Glass self.assertEqual('test0', entry.test_str_fdt) 122353af22a9SSimon Glass self.assertEqual(None, entry.test_str_arg) 122453af22a9SSimon Glass self.assertEqual(None, entry.test_int_fdt) 122553af22a9SSimon Glass self.assertEqual(456, entry.test_int_arg) 122653af22a9SSimon Glass 122753af22a9SSimon Glass def testEntryArgsRequired(self): 122853af22a9SSimon Glass """Test missing arguments and properties""" 122953af22a9SSimon Glass entry_args = { 123053af22a9SSimon Glass 'test-int-arg': '456', 123153af22a9SSimon Glass } 123253af22a9SSimon Glass with self.assertRaises(ValueError) as e: 1233741f2d62SSimon Glass self._DoReadFileDtb('064_entry_args_required.dts') 123453af22a9SSimon Glass self.assertIn("Node '/binman/_testing': Missing required " 123553af22a9SSimon Glass 'properties/entry args: test-str-arg, test-int-fdt, test-int-arg', 123653af22a9SSimon Glass str(e.exception)) 123753af22a9SSimon Glass 123853af22a9SSimon Glass def testEntryArgsInvalidFormat(self): 123953af22a9SSimon Glass """Test that an invalid entry-argument format is detected""" 1240741f2d62SSimon Glass args = ['-d', self.TestFile('064_entry_args_required.dts'), '-ano-value'] 124153af22a9SSimon Glass with self.assertRaises(ValueError) as e: 124253af22a9SSimon Glass self._DoBinman(*args) 124353af22a9SSimon Glass self.assertIn("Invalid entry arguemnt 'no-value'", str(e.exception)) 124453af22a9SSimon Glass 124553af22a9SSimon Glass def testEntryArgsInvalidInteger(self): 124653af22a9SSimon Glass """Test that an invalid entry-argument integer is detected""" 124753af22a9SSimon Glass entry_args = { 124853af22a9SSimon Glass 'test-int-arg': 'abc', 124953af22a9SSimon Glass } 125053af22a9SSimon Glass with self.assertRaises(ValueError) as e: 1251741f2d62SSimon Glass self._DoReadFileDtb('062_entry_args.dts', entry_args=entry_args) 125253af22a9SSimon Glass self.assertIn("Node '/binman/_testing': Cannot convert entry arg " 125353af22a9SSimon Glass "'test-int-arg' (value 'abc') to integer", 125453af22a9SSimon Glass str(e.exception)) 125553af22a9SSimon Glass 125653af22a9SSimon Glass def testEntryArgsInvalidDatatype(self): 125753af22a9SSimon Glass """Test that an invalid entry-argument datatype is detected 125853af22a9SSimon Glass 125953af22a9SSimon Glass This test could be written in entry_test.py except that it needs 126053af22a9SSimon Glass access to control.entry_args, which seems more than that module should 126153af22a9SSimon Glass be able to see. 126253af22a9SSimon Glass """ 126353af22a9SSimon Glass entry_args = { 126453af22a9SSimon Glass 'test-bad-datatype-arg': '12', 126553af22a9SSimon Glass } 126653af22a9SSimon Glass with self.assertRaises(ValueError) as e: 1267741f2d62SSimon Glass self._DoReadFileDtb('065_entry_args_unknown_datatype.dts', 126853af22a9SSimon Glass entry_args=entry_args) 126953af22a9SSimon Glass self.assertIn('GetArg() internal error: Unknown data type ', 127053af22a9SSimon Glass str(e.exception)) 127153af22a9SSimon Glass 1272bb74837cSSimon Glass def testText(self): 1273bb74837cSSimon Glass """Test for a text entry type""" 1274bb74837cSSimon Glass entry_args = { 1275bb74837cSSimon Glass 'test-id': TEXT_DATA, 1276bb74837cSSimon Glass 'test-id2': TEXT_DATA2, 1277bb74837cSSimon Glass 'test-id3': TEXT_DATA3, 1278bb74837cSSimon Glass } 1279741f2d62SSimon Glass data, _, _, _ = self._DoReadFileDtb('066_text.dts', 1280bb74837cSSimon Glass entry_args=entry_args) 1281bb74837cSSimon Glass expected = (TEXT_DATA + chr(0) * (8 - len(TEXT_DATA)) + TEXT_DATA2 + 1282bb74837cSSimon Glass TEXT_DATA3 + 'some text') 1283bb74837cSSimon Glass self.assertEqual(expected, data) 1284bb74837cSSimon Glass 1285fd8d1f79SSimon Glass def testEntryDocs(self): 1286fd8d1f79SSimon Glass """Test for creation of entry documentation""" 1287fd8d1f79SSimon Glass with test_util.capture_sys_output() as (stdout, stderr): 1288fd8d1f79SSimon Glass control.WriteEntryDocs(binman.GetEntryModules()) 1289fd8d1f79SSimon Glass self.assertTrue(len(stdout.getvalue()) > 0) 1290fd8d1f79SSimon Glass 1291fd8d1f79SSimon Glass def testEntryDocsMissing(self): 1292fd8d1f79SSimon Glass """Test handling of missing entry documentation""" 1293fd8d1f79SSimon Glass with self.assertRaises(ValueError) as e: 1294fd8d1f79SSimon Glass with test_util.capture_sys_output() as (stdout, stderr): 1295fd8d1f79SSimon Glass control.WriteEntryDocs(binman.GetEntryModules(), 'u_boot') 1296fd8d1f79SSimon Glass self.assertIn('Documentation is missing for modules: u_boot', 1297fd8d1f79SSimon Glass str(e.exception)) 1298fd8d1f79SSimon Glass 129911e36cceSSimon Glass def testFmap(self): 130011e36cceSSimon Glass """Basic test of generation of a flashrom fmap""" 1301741f2d62SSimon Glass data = self._DoReadFile('067_fmap.dts') 130211e36cceSSimon Glass fhdr, fentries = fmap_util.DecodeFmap(data[32:]) 130311e36cceSSimon Glass expected = U_BOOT_DATA + '!' * 12 + U_BOOT_DATA + 'a' * 12 130411e36cceSSimon Glass self.assertEqual(expected, data[:32]) 130511e36cceSSimon Glass self.assertEqual('__FMAP__', fhdr.signature) 130611e36cceSSimon Glass self.assertEqual(1, fhdr.ver_major) 130711e36cceSSimon Glass self.assertEqual(0, fhdr.ver_minor) 130811e36cceSSimon Glass self.assertEqual(0, fhdr.base) 130911e36cceSSimon Glass self.assertEqual(16 + 16 + 131011e36cceSSimon Glass fmap_util.FMAP_HEADER_LEN + 131111e36cceSSimon Glass fmap_util.FMAP_AREA_LEN * 3, fhdr.image_size) 131211e36cceSSimon Glass self.assertEqual('FMAP', fhdr.name) 131311e36cceSSimon Glass self.assertEqual(3, fhdr.nareas) 131411e36cceSSimon Glass for fentry in fentries: 131511e36cceSSimon Glass self.assertEqual(0, fentry.flags) 131611e36cceSSimon Glass 131711e36cceSSimon Glass self.assertEqual(0, fentries[0].offset) 131811e36cceSSimon Glass self.assertEqual(4, fentries[0].size) 131911e36cceSSimon Glass self.assertEqual('RO_U_BOOT', fentries[0].name) 132011e36cceSSimon Glass 132111e36cceSSimon Glass self.assertEqual(16, fentries[1].offset) 132211e36cceSSimon Glass self.assertEqual(4, fentries[1].size) 132311e36cceSSimon Glass self.assertEqual('RW_U_BOOT', fentries[1].name) 132411e36cceSSimon Glass 132511e36cceSSimon Glass self.assertEqual(32, fentries[2].offset) 132611e36cceSSimon Glass self.assertEqual(fmap_util.FMAP_HEADER_LEN + 132711e36cceSSimon Glass fmap_util.FMAP_AREA_LEN * 3, fentries[2].size) 132811e36cceSSimon Glass self.assertEqual('FMAP', fentries[2].name) 132911e36cceSSimon Glass 1330ec127af0SSimon Glass def testBlobNamedByArg(self): 1331ec127af0SSimon Glass """Test we can add a blob with the filename coming from an entry arg""" 1332ec127af0SSimon Glass entry_args = { 1333ec127af0SSimon Glass 'cros-ec-rw-path': 'ecrw.bin', 1334ec127af0SSimon Glass } 1335741f2d62SSimon Glass data, _, _, _ = self._DoReadFileDtb('068_blob_named_by_arg.dts', 1336ec127af0SSimon Glass entry_args=entry_args) 1337ec127af0SSimon Glass 13383af8e49cSSimon Glass def testFill(self): 13393af8e49cSSimon Glass """Test for an fill entry type""" 1340741f2d62SSimon Glass data = self._DoReadFile('069_fill.dts') 13413af8e49cSSimon Glass expected = 8 * chr(0xff) + 8 * chr(0) 13423af8e49cSSimon Glass self.assertEqual(expected, data) 13433af8e49cSSimon Glass 13443af8e49cSSimon Glass def testFillNoSize(self): 13453af8e49cSSimon Glass """Test for an fill entry type with no size""" 13463af8e49cSSimon Glass with self.assertRaises(ValueError) as e: 1347741f2d62SSimon Glass self._DoReadFile('070_fill_no_size.dts') 13483af8e49cSSimon Glass self.assertIn("'fill' entry must have a size property", 13493af8e49cSSimon Glass str(e.exception)) 13503af8e49cSSimon Glass 13510ef87aa3SSimon Glass def _HandleGbbCommand(self, pipe_list): 13520ef87aa3SSimon Glass """Fake calls to the futility utility""" 13530ef87aa3SSimon Glass if pipe_list[0][0] == 'futility': 13540ef87aa3SSimon Glass fname = pipe_list[0][-1] 13550ef87aa3SSimon Glass # Append our GBB data to the file, which will happen every time the 13560ef87aa3SSimon Glass # futility command is called. 13570ef87aa3SSimon Glass with open(fname, 'a') as fd: 13580ef87aa3SSimon Glass fd.write(GBB_DATA) 13590ef87aa3SSimon Glass return command.CommandResult() 13600ef87aa3SSimon Glass 13610ef87aa3SSimon Glass def testGbb(self): 13620ef87aa3SSimon Glass """Test for the Chromium OS Google Binary Block""" 13630ef87aa3SSimon Glass command.test_result = self._HandleGbbCommand 13640ef87aa3SSimon Glass entry_args = { 13650ef87aa3SSimon Glass 'keydir': 'devkeys', 13660ef87aa3SSimon Glass 'bmpblk': 'bmpblk.bin', 13670ef87aa3SSimon Glass } 1368741f2d62SSimon Glass data, _, _, _ = self._DoReadFileDtb('071_gbb.dts', entry_args=entry_args) 13690ef87aa3SSimon Glass 13700ef87aa3SSimon Glass # Since futility 13710ef87aa3SSimon Glass expected = GBB_DATA + GBB_DATA + 8 * chr(0) + (0x2180 - 16) * chr(0) 13720ef87aa3SSimon Glass self.assertEqual(expected, data) 13730ef87aa3SSimon Glass 13740ef87aa3SSimon Glass def testGbbTooSmall(self): 13750ef87aa3SSimon Glass """Test for the Chromium OS Google Binary Block being large enough""" 13760ef87aa3SSimon Glass with self.assertRaises(ValueError) as e: 1377741f2d62SSimon Glass self._DoReadFileDtb('072_gbb_too_small.dts') 13780ef87aa3SSimon Glass self.assertIn("Node '/binman/gbb': GBB is too small", 13790ef87aa3SSimon Glass str(e.exception)) 13800ef87aa3SSimon Glass 13810ef87aa3SSimon Glass def testGbbNoSize(self): 13820ef87aa3SSimon Glass """Test for the Chromium OS Google Binary Block having a size""" 13830ef87aa3SSimon Glass with self.assertRaises(ValueError) as e: 1384741f2d62SSimon Glass self._DoReadFileDtb('073_gbb_no_size.dts') 13850ef87aa3SSimon Glass self.assertIn("Node '/binman/gbb': GBB must have a fixed size", 13860ef87aa3SSimon Glass str(e.exception)) 13870ef87aa3SSimon Glass 138824d0d3c3SSimon Glass def _HandleVblockCommand(self, pipe_list): 138924d0d3c3SSimon Glass """Fake calls to the futility utility""" 139024d0d3c3SSimon Glass if pipe_list[0][0] == 'futility': 139124d0d3c3SSimon Glass fname = pipe_list[0][3] 1392a326b495SSimon Glass with open(fname, 'wb') as fd: 139324d0d3c3SSimon Glass fd.write(VBLOCK_DATA) 139424d0d3c3SSimon Glass return command.CommandResult() 139524d0d3c3SSimon Glass 139624d0d3c3SSimon Glass def testVblock(self): 139724d0d3c3SSimon Glass """Test for the Chromium OS Verified Boot Block""" 139824d0d3c3SSimon Glass command.test_result = self._HandleVblockCommand 139924d0d3c3SSimon Glass entry_args = { 140024d0d3c3SSimon Glass 'keydir': 'devkeys', 140124d0d3c3SSimon Glass } 1402741f2d62SSimon Glass data, _, _, _ = self._DoReadFileDtb('074_vblock.dts', 140324d0d3c3SSimon Glass entry_args=entry_args) 140424d0d3c3SSimon Glass expected = U_BOOT_DATA + VBLOCK_DATA + U_BOOT_DTB_DATA 140524d0d3c3SSimon Glass self.assertEqual(expected, data) 140624d0d3c3SSimon Glass 140724d0d3c3SSimon Glass def testVblockNoContent(self): 140824d0d3c3SSimon Glass """Test we detect a vblock which has no content to sign""" 140924d0d3c3SSimon Glass with self.assertRaises(ValueError) as e: 1410741f2d62SSimon Glass self._DoReadFile('075_vblock_no_content.dts') 141124d0d3c3SSimon Glass self.assertIn("Node '/binman/vblock': Vblock must have a 'content' " 141224d0d3c3SSimon Glass 'property', str(e.exception)) 141324d0d3c3SSimon Glass 141424d0d3c3SSimon Glass def testVblockBadPhandle(self): 141524d0d3c3SSimon Glass """Test that we detect a vblock with an invalid phandle in contents""" 141624d0d3c3SSimon Glass with self.assertRaises(ValueError) as e: 1417741f2d62SSimon Glass self._DoReadFile('076_vblock_bad_phandle.dts') 141824d0d3c3SSimon Glass self.assertIn("Node '/binman/vblock': Cannot find node for phandle " 141924d0d3c3SSimon Glass '1000', str(e.exception)) 142024d0d3c3SSimon Glass 142124d0d3c3SSimon Glass def testVblockBadEntry(self): 142224d0d3c3SSimon Glass """Test that we detect an entry that points to a non-entry""" 142324d0d3c3SSimon Glass with self.assertRaises(ValueError) as e: 1424741f2d62SSimon Glass self._DoReadFile('077_vblock_bad_entry.dts') 142524d0d3c3SSimon Glass self.assertIn("Node '/binman/vblock': Cannot find entry for node " 142624d0d3c3SSimon Glass "'other'", str(e.exception)) 142724d0d3c3SSimon Glass 1428b8ef5b6bSSimon Glass def testTpl(self): 1429b8ef5b6bSSimon Glass """Test that an image with TPL and ots device tree can be created""" 1430b8ef5b6bSSimon Glass # ELF file with a '__bss_size' symbol 1431b8ef5b6bSSimon Glass with open(self.TestFile('bss_data')) as fd: 1432b8ef5b6bSSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) 1433741f2d62SSimon Glass data = self._DoReadFile('078_u_boot_tpl.dts') 1434b8ef5b6bSSimon Glass self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data) 1435b8ef5b6bSSimon Glass 143615a587c9SSimon Glass def testUsesPos(self): 143715a587c9SSimon Glass """Test that the 'pos' property cannot be used anymore""" 143815a587c9SSimon Glass with self.assertRaises(ValueError) as e: 1439741f2d62SSimon Glass data = self._DoReadFile('079_uses_pos.dts') 144015a587c9SSimon Glass self.assertIn("Node '/binman/u-boot': Please use 'offset' instead of " 144115a587c9SSimon Glass "'pos'", str(e.exception)) 144215a587c9SSimon Glass 1443d178eab8SSimon Glass def testFillZero(self): 1444d178eab8SSimon Glass """Test for an fill entry type with a size of 0""" 1445741f2d62SSimon Glass data = self._DoReadFile('080_fill_empty.dts') 1446d178eab8SSimon Glass self.assertEqual(chr(0) * 16, data) 1447d178eab8SSimon Glass 14480b489364SSimon Glass def testTextMissing(self): 14490b489364SSimon Glass """Test for a text entry type where there is no text""" 14500b489364SSimon Glass with self.assertRaises(ValueError) as e: 1451741f2d62SSimon Glass self._DoReadFileDtb('066_text.dts',) 14520b489364SSimon Glass self.assertIn("Node '/binman/text': No value provided for text label " 14530b489364SSimon Glass "'test-id'", str(e.exception)) 14540b489364SSimon Glass 145535b384cbSSimon Glass def testPackStart16Tpl(self): 145635b384cbSSimon Glass """Test that an image with an x86 start16 TPL region can be created""" 1457741f2d62SSimon Glass data = self._DoReadFile('081_x86-start16-tpl.dts') 145835b384cbSSimon Glass self.assertEqual(X86_START16_TPL_DATA, data[:len(X86_START16_TPL_DATA)]) 145935b384cbSSimon Glass 14600bfa7b09SSimon Glass def testSelectImage(self): 14610bfa7b09SSimon Glass """Test that we can select which images to build""" 14620bfa7b09SSimon Glass with test_util.capture_sys_output() as (stdout, stderr): 1463741f2d62SSimon Glass retcode = self._DoTestFile('006_dual_image.dts', images=['image2']) 14640bfa7b09SSimon Glass self.assertEqual(0, retcode) 14650bfa7b09SSimon Glass self.assertIn('Skipping images: image1', stdout.getvalue()) 14660bfa7b09SSimon Glass 14670bfa7b09SSimon Glass self.assertFalse(os.path.exists(tools.GetOutputFilename('image1.bin'))) 14680bfa7b09SSimon Glass self.assertTrue(os.path.exists(tools.GetOutputFilename('image2.bin'))) 14690bfa7b09SSimon Glass 14706ed45ba0SSimon Glass def testUpdateFdtAll(self): 14716ed45ba0SSimon Glass """Test that all device trees are updated with offset/size info""" 1472741f2d62SSimon Glass data, _, _, _ = self._DoReadFileDtb('082_fdt_update_all.dts', 14736ed45ba0SSimon Glass use_real_dtb=True, update_dtb=True) 14746ed45ba0SSimon Glass 14756ed45ba0SSimon Glass base_expected = { 14766ed45ba0SSimon Glass 'section:image-pos': 0, 14776ed45ba0SSimon Glass 'u-boot-tpl-dtb:size': 513, 14786ed45ba0SSimon Glass 'u-boot-spl-dtb:size': 513, 14796ed45ba0SSimon Glass 'u-boot-spl-dtb:offset': 493, 14806ed45ba0SSimon Glass 'image-pos': 0, 14816ed45ba0SSimon Glass 'section/u-boot-dtb:image-pos': 0, 14826ed45ba0SSimon Glass 'u-boot-spl-dtb:image-pos': 493, 14836ed45ba0SSimon Glass 'section/u-boot-dtb:size': 493, 14846ed45ba0SSimon Glass 'u-boot-tpl-dtb:image-pos': 1006, 14856ed45ba0SSimon Glass 'section/u-boot-dtb:offset': 0, 14866ed45ba0SSimon Glass 'section:size': 493, 14876ed45ba0SSimon Glass 'offset': 0, 14886ed45ba0SSimon Glass 'section:offset': 0, 14896ed45ba0SSimon Glass 'u-boot-tpl-dtb:offset': 1006, 14906ed45ba0SSimon Glass 'size': 1519 14916ed45ba0SSimon Glass } 14926ed45ba0SSimon Glass 14936ed45ba0SSimon Glass # We expect three device-tree files in the output, one after the other. 14946ed45ba0SSimon Glass # Read them in sequence. We look for an 'spl' property in the SPL tree, 14956ed45ba0SSimon Glass # and 'tpl' in the TPL tree, to make sure they are distinct from the 14966ed45ba0SSimon Glass # main U-Boot tree. All three should have the same postions and offset. 14976ed45ba0SSimon Glass start = 0 14986ed45ba0SSimon Glass for item in ['', 'spl', 'tpl']: 14996ed45ba0SSimon Glass dtb = fdt.Fdt.FromData(data[start:]) 15006ed45ba0SSimon Glass dtb.Scan() 15016ed45ba0SSimon Glass props = self._GetPropTree(dtb, ['offset', 'size', 'image-pos', 15026ed45ba0SSimon Glass 'spl', 'tpl']) 15036ed45ba0SSimon Glass expected = dict(base_expected) 15046ed45ba0SSimon Glass if item: 15056ed45ba0SSimon Glass expected[item] = 0 15066ed45ba0SSimon Glass self.assertEqual(expected, props) 15076ed45ba0SSimon Glass start += dtb._fdt_obj.totalsize() 15086ed45ba0SSimon Glass 15096ed45ba0SSimon Glass def testUpdateFdtOutput(self): 15106ed45ba0SSimon Glass """Test that output DTB files are updated""" 15116ed45ba0SSimon Glass try: 1512741f2d62SSimon Glass data, dtb_data, _, _ = self._DoReadFileDtb('082_fdt_update_all.dts', 15136ed45ba0SSimon Glass use_real_dtb=True, update_dtb=True, reset_dtbs=False) 15146ed45ba0SSimon Glass 15156ed45ba0SSimon Glass # Unfortunately, compiling a source file always results in a file 15166ed45ba0SSimon Glass # called source.dtb (see fdt_util.EnsureCompiled()). The test 1517741f2d62SSimon Glass # source file (e.g. test/075_fdt_update_all.dts) thus does not enter 15186ed45ba0SSimon Glass # binman as a file called u-boot.dtb. To fix this, copy the file 15196ed45ba0SSimon Glass # over to the expected place. 15206ed45ba0SSimon Glass #tools.WriteFile(os.path.join(self._indir, 'u-boot.dtb'), 15216ed45ba0SSimon Glass #tools.ReadFile(tools.GetOutputFilename('source.dtb'))) 15226ed45ba0SSimon Glass start = 0 15236ed45ba0SSimon Glass for fname in ['u-boot.dtb.out', 'spl/u-boot-spl.dtb.out', 15246ed45ba0SSimon Glass 'tpl/u-boot-tpl.dtb.out']: 15256ed45ba0SSimon Glass dtb = fdt.Fdt.FromData(data[start:]) 15266ed45ba0SSimon Glass size = dtb._fdt_obj.totalsize() 15276ed45ba0SSimon Glass pathname = tools.GetOutputFilename(os.path.split(fname)[1]) 15286ed45ba0SSimon Glass outdata = tools.ReadFile(pathname) 15296ed45ba0SSimon Glass name = os.path.split(fname)[0] 15306ed45ba0SSimon Glass 15316ed45ba0SSimon Glass if name: 15326ed45ba0SSimon Glass orig_indata = self._GetDtbContentsForSplTpl(dtb_data, name) 15336ed45ba0SSimon Glass else: 15346ed45ba0SSimon Glass orig_indata = dtb_data 15356ed45ba0SSimon Glass self.assertNotEqual(outdata, orig_indata, 15366ed45ba0SSimon Glass "Expected output file '%s' be updated" % pathname) 15376ed45ba0SSimon Glass self.assertEqual(outdata, data[start:start + size], 15386ed45ba0SSimon Glass "Expected output file '%s' to match output image" % 15396ed45ba0SSimon Glass pathname) 15406ed45ba0SSimon Glass start += size 15416ed45ba0SSimon Glass finally: 15426ed45ba0SSimon Glass self._ResetDtbs() 15436ed45ba0SSimon Glass 154483d73c2fSSimon Glass def _decompress(self, data): 154583d73c2fSSimon Glass out = os.path.join(self._indir, 'lz4.tmp') 154683d73c2fSSimon Glass with open(out, 'wb') as fd: 154783d73c2fSSimon Glass fd.write(data) 154883d73c2fSSimon Glass return tools.Run('lz4', '-dc', out) 154983d73c2fSSimon Glass ''' 155083d73c2fSSimon Glass try: 155183d73c2fSSimon Glass orig = lz4.frame.decompress(data) 155283d73c2fSSimon Glass except AttributeError: 155383d73c2fSSimon Glass orig = lz4.decompress(data) 155483d73c2fSSimon Glass ''' 155583d73c2fSSimon Glass 155683d73c2fSSimon Glass def testCompress(self): 155783d73c2fSSimon Glass """Test compression of blobs""" 1558741f2d62SSimon Glass data, _, _, out_dtb_fname = self._DoReadFileDtb('083_compress.dts', 155983d73c2fSSimon Glass use_real_dtb=True, update_dtb=True) 156083d73c2fSSimon Glass dtb = fdt.Fdt(out_dtb_fname) 156183d73c2fSSimon Glass dtb.Scan() 156283d73c2fSSimon Glass props = self._GetPropTree(dtb, ['size', 'uncomp-size']) 156383d73c2fSSimon Glass orig = self._decompress(data) 156483d73c2fSSimon Glass self.assertEquals(COMPRESS_DATA, orig) 156583d73c2fSSimon Glass expected = { 156683d73c2fSSimon Glass 'blob:uncomp-size': len(COMPRESS_DATA), 156783d73c2fSSimon Glass 'blob:size': len(data), 156883d73c2fSSimon Glass 'size': len(data), 156983d73c2fSSimon Glass } 157083d73c2fSSimon Glass self.assertEqual(expected, props) 157183d73c2fSSimon Glass 15720a98b28bSSimon Glass def testFiles(self): 15730a98b28bSSimon Glass """Test bringing in multiple files""" 1574741f2d62SSimon Glass data = self._DoReadFile('084_files.dts') 15750a98b28bSSimon Glass self.assertEqual(FILES_DATA, data) 15760a98b28bSSimon Glass 15770a98b28bSSimon Glass def testFilesCompress(self): 15780a98b28bSSimon Glass """Test bringing in multiple files and compressing them""" 1579741f2d62SSimon Glass data = self._DoReadFile('085_files_compress.dts') 15800a98b28bSSimon Glass 15810a98b28bSSimon Glass image = control.images['image'] 15820a98b28bSSimon Glass entries = image.GetEntries() 15830a98b28bSSimon Glass files = entries['files'] 15840a98b28bSSimon Glass entries = files._section._entries 15850a98b28bSSimon Glass 15860a98b28bSSimon Glass orig = '' 15870a98b28bSSimon Glass for i in range(1, 3): 15880a98b28bSSimon Glass key = '%d.dat' % i 15890a98b28bSSimon Glass start = entries[key].image_pos 15900a98b28bSSimon Glass len = entries[key].size 15910a98b28bSSimon Glass chunk = data[start:start + len] 15920a98b28bSSimon Glass orig += self._decompress(chunk) 15930a98b28bSSimon Glass 15940a98b28bSSimon Glass self.assertEqual(FILES_DATA, orig) 15950a98b28bSSimon Glass 15960a98b28bSSimon Glass def testFilesMissing(self): 15970a98b28bSSimon Glass """Test missing files""" 15980a98b28bSSimon Glass with self.assertRaises(ValueError) as e: 1599741f2d62SSimon Glass data = self._DoReadFile('086_files_none.dts') 16000a98b28bSSimon Glass self.assertIn("Node '/binman/files': Pattern \'files/*.none\' matched " 16010a98b28bSSimon Glass 'no files', str(e.exception)) 16020a98b28bSSimon Glass 16030a98b28bSSimon Glass def testFilesNoPattern(self): 16040a98b28bSSimon Glass """Test missing files""" 16050a98b28bSSimon Glass with self.assertRaises(ValueError) as e: 1606741f2d62SSimon Glass data = self._DoReadFile('087_files_no_pattern.dts') 16070a98b28bSSimon Glass self.assertIn("Node '/binman/files': Missing 'pattern' property", 16080a98b28bSSimon Glass str(e.exception)) 16090a98b28bSSimon Glass 1610ba64a0bbSSimon Glass def testExpandSize(self): 1611ba64a0bbSSimon Glass """Test an expanding entry""" 1612741f2d62SSimon Glass data, _, map_data, _ = self._DoReadFileDtb('088_expand_size.dts', 1613ba64a0bbSSimon Glass map=True) 1614ba64a0bbSSimon Glass expect = ('a' * 8 + U_BOOT_DATA + 1615ba64a0bbSSimon Glass MRC_DATA + 'b' * 1 + U_BOOT_DATA + 1616ba64a0bbSSimon Glass 'c' * 8 + U_BOOT_DATA + 1617ba64a0bbSSimon Glass 'd' * 8) 1618ba64a0bbSSimon Glass self.assertEqual(expect, data) 1619ba64a0bbSSimon Glass self.assertEqual('''ImagePos Offset Size Name 1620ba64a0bbSSimon Glass00000000 00000000 00000028 main-section 1621ba64a0bbSSimon Glass00000000 00000000 00000008 fill 1622ba64a0bbSSimon Glass00000008 00000008 00000004 u-boot 1623ba64a0bbSSimon Glass0000000c 0000000c 00000004 section 1624ba64a0bbSSimon Glass0000000c 00000000 00000003 intel-mrc 1625ba64a0bbSSimon Glass00000010 00000010 00000004 u-boot2 1626ba64a0bbSSimon Glass00000014 00000014 0000000c section2 1627ba64a0bbSSimon Glass00000014 00000000 00000008 fill 1628ba64a0bbSSimon Glass0000001c 00000008 00000004 u-boot 1629ba64a0bbSSimon Glass00000020 00000020 00000008 fill2 1630ba64a0bbSSimon Glass''', map_data) 1631ba64a0bbSSimon Glass 1632ba64a0bbSSimon Glass def testExpandSizeBad(self): 1633ba64a0bbSSimon Glass """Test an expanding entry which fails to provide contents""" 1634163ed6c3SSimon Glass with test_util.capture_sys_output() as (stdout, stderr): 1635ba64a0bbSSimon Glass with self.assertRaises(ValueError) as e: 1636741f2d62SSimon Glass self._DoReadFileDtb('089_expand_size_bad.dts', map=True) 1637ba64a0bbSSimon Glass self.assertIn("Node '/binman/_testing': Cannot obtain contents when " 1638ba64a0bbSSimon Glass 'expanding entry', str(e.exception)) 1639ba64a0bbSSimon Glass 1640e0e5df93SSimon Glass def testHash(self): 1641e0e5df93SSimon Glass """Test hashing of the contents of an entry""" 1642741f2d62SSimon Glass _, _, _, out_dtb_fname = self._DoReadFileDtb('090_hash.dts', 1643e0e5df93SSimon Glass use_real_dtb=True, update_dtb=True) 1644e0e5df93SSimon Glass dtb = fdt.Fdt(out_dtb_fname) 1645e0e5df93SSimon Glass dtb.Scan() 1646e0e5df93SSimon Glass hash_node = dtb.GetNode('/binman/u-boot/hash').props['value'] 1647e0e5df93SSimon Glass m = hashlib.sha256() 1648e0e5df93SSimon Glass m.update(U_BOOT_DATA) 1649e0e5df93SSimon Glass self.assertEqual(m.digest(), ''.join(hash_node.value)) 1650e0e5df93SSimon Glass 1651e0e5df93SSimon Glass def testHashNoAlgo(self): 1652e0e5df93SSimon Glass with self.assertRaises(ValueError) as e: 1653741f2d62SSimon Glass self._DoReadFileDtb('091_hash_no_algo.dts', update_dtb=True) 1654e0e5df93SSimon Glass self.assertIn("Node \'/binman/u-boot\': Missing \'algo\' property for " 1655e0e5df93SSimon Glass 'hash node', str(e.exception)) 1656e0e5df93SSimon Glass 1657e0e5df93SSimon Glass def testHashBadAlgo(self): 1658e0e5df93SSimon Glass with self.assertRaises(ValueError) as e: 1659741f2d62SSimon Glass self._DoReadFileDtb('092_hash_bad_algo.dts', update_dtb=True) 1660e0e5df93SSimon Glass self.assertIn("Node '/binman/u-boot': Unknown hash algorithm", 1661e0e5df93SSimon Glass str(e.exception)) 1662e0e5df93SSimon Glass 1663e0e5df93SSimon Glass def testHashSection(self): 1664e0e5df93SSimon Glass """Test hashing of the contents of an entry""" 1665741f2d62SSimon Glass _, _, _, out_dtb_fname = self._DoReadFileDtb('099_hash_section.dts', 1666e0e5df93SSimon Glass use_real_dtb=True, update_dtb=True) 1667e0e5df93SSimon Glass dtb = fdt.Fdt(out_dtb_fname) 1668e0e5df93SSimon Glass dtb.Scan() 1669e0e5df93SSimon Glass hash_node = dtb.GetNode('/binman/section/hash').props['value'] 1670e0e5df93SSimon Glass m = hashlib.sha256() 1671e0e5df93SSimon Glass m.update(U_BOOT_DATA) 1672e0e5df93SSimon Glass m.update(16 * 'a') 1673e0e5df93SSimon Glass self.assertEqual(m.digest(), ''.join(hash_node.value)) 1674e0e5df93SSimon Glass 1675f0253635SSimon Glass def testPackUBootTplMicrocode(self): 1676f0253635SSimon Glass """Test that x86 microcode can be handled correctly in TPL 1677f0253635SSimon Glass 1678f0253635SSimon Glass We expect to see the following in the image, in order: 1679f0253635SSimon Glass u-boot-tpl-nodtb.bin with a microcode pointer inserted at the correct 1680f0253635SSimon Glass place 1681f0253635SSimon Glass u-boot-tpl.dtb with the microcode removed 1682f0253635SSimon Glass the microcode 1683f0253635SSimon Glass """ 1684f0253635SSimon Glass with open(self.TestFile('u_boot_ucode_ptr')) as fd: 1685f0253635SSimon Glass TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) 1686741f2d62SSimon Glass first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts', 1687f0253635SSimon Glass U_BOOT_TPL_NODTB_DATA) 1688f0253635SSimon Glass self.assertEqual('tplnodtb with microc' + pos_and_size + 1689f0253635SSimon Glass 'ter somewhere in here', first) 1690f0253635SSimon Glass 1691f8f8df6eSSimon Glass def testFmapX86(self): 1692f8f8df6eSSimon Glass """Basic test of generation of a flashrom fmap""" 1693741f2d62SSimon Glass data = self._DoReadFile('094_fmap_x86.dts') 1694f8f8df6eSSimon Glass fhdr, fentries = fmap_util.DecodeFmap(data[32:]) 1695f8f8df6eSSimon Glass expected = U_BOOT_DATA + MRC_DATA + 'a' * (32 - 7) 1696f8f8df6eSSimon Glass self.assertEqual(expected, data[:32]) 1697f8f8df6eSSimon Glass fhdr, fentries = fmap_util.DecodeFmap(data[32:]) 1698f8f8df6eSSimon Glass 1699f8f8df6eSSimon Glass self.assertEqual(0x100, fhdr.image_size) 1700f8f8df6eSSimon Glass 1701f8f8df6eSSimon Glass self.assertEqual(0, fentries[0].offset) 1702f8f8df6eSSimon Glass self.assertEqual(4, fentries[0].size) 1703f8f8df6eSSimon Glass self.assertEqual('U_BOOT', fentries[0].name) 1704f8f8df6eSSimon Glass 1705f8f8df6eSSimon Glass self.assertEqual(4, fentries[1].offset) 1706f8f8df6eSSimon Glass self.assertEqual(3, fentries[1].size) 1707f8f8df6eSSimon Glass self.assertEqual('INTEL_MRC', fentries[1].name) 1708f8f8df6eSSimon Glass 1709f8f8df6eSSimon Glass self.assertEqual(32, fentries[2].offset) 1710f8f8df6eSSimon Glass self.assertEqual(fmap_util.FMAP_HEADER_LEN + 1711f8f8df6eSSimon Glass fmap_util.FMAP_AREA_LEN * 3, fentries[2].size) 1712f8f8df6eSSimon Glass self.assertEqual('FMAP', fentries[2].name) 1713f8f8df6eSSimon Glass 1714f8f8df6eSSimon Glass def testFmapX86Section(self): 1715f8f8df6eSSimon Glass """Basic test of generation of a flashrom fmap""" 1716741f2d62SSimon Glass data = self._DoReadFile('095_fmap_x86_section.dts') 1717f8f8df6eSSimon Glass expected = U_BOOT_DATA + MRC_DATA + 'b' * (32 - 7) 1718f8f8df6eSSimon Glass self.assertEqual(expected, data[:32]) 1719f8f8df6eSSimon Glass fhdr, fentries = fmap_util.DecodeFmap(data[36:]) 1720f8f8df6eSSimon Glass 1721f8f8df6eSSimon Glass self.assertEqual(0x100, fhdr.image_size) 1722f8f8df6eSSimon Glass 1723f8f8df6eSSimon Glass self.assertEqual(0, fentries[0].offset) 1724f8f8df6eSSimon Glass self.assertEqual(4, fentries[0].size) 1725f8f8df6eSSimon Glass self.assertEqual('U_BOOT', fentries[0].name) 1726f8f8df6eSSimon Glass 1727f8f8df6eSSimon Glass self.assertEqual(4, fentries[1].offset) 1728f8f8df6eSSimon Glass self.assertEqual(3, fentries[1].size) 1729f8f8df6eSSimon Glass self.assertEqual('INTEL_MRC', fentries[1].name) 1730f8f8df6eSSimon Glass 1731f8f8df6eSSimon Glass self.assertEqual(36, fentries[2].offset) 1732f8f8df6eSSimon Glass self.assertEqual(fmap_util.FMAP_HEADER_LEN + 1733f8f8df6eSSimon Glass fmap_util.FMAP_AREA_LEN * 3, fentries[2].size) 1734f8f8df6eSSimon Glass self.assertEqual('FMAP', fentries[2].name) 1735f8f8df6eSSimon Glass 1736fe1ae3ecSSimon Glass def testElf(self): 1737fe1ae3ecSSimon Glass """Basic test of ELF entries""" 173811ae93eeSSimon Glass self._SetupSplElf() 1739fe1ae3ecSSimon Glass with open(self.TestFile('bss_data')) as fd: 1740fe1ae3ecSSimon Glass TestFunctional._MakeInputFile('-boot', fd.read()) 1741741f2d62SSimon Glass data = self._DoReadFile('096_elf.dts') 1742fe1ae3ecSSimon Glass 1743fe1ae3ecSSimon Glass def testElfStripg(self): 1744fe1ae3ecSSimon Glass """Basic test of ELF entries""" 174511ae93eeSSimon Glass self._SetupSplElf() 1746fe1ae3ecSSimon Glass with open(self.TestFile('bss_data')) as fd: 1747fe1ae3ecSSimon Glass TestFunctional._MakeInputFile('-boot', fd.read()) 1748741f2d62SSimon Glass data = self._DoReadFile('097_elf_strip.dts') 1749fe1ae3ecSSimon Glass 1750163ed6c3SSimon Glass def testPackOverlapMap(self): 1751163ed6c3SSimon Glass """Test that overlapping regions are detected""" 1752163ed6c3SSimon Glass with test_util.capture_sys_output() as (stdout, stderr): 1753163ed6c3SSimon Glass with self.assertRaises(ValueError) as e: 1754741f2d62SSimon Glass self._DoTestFile('014_pack_overlap.dts', map=True) 1755163ed6c3SSimon Glass map_fname = tools.GetOutputFilename('image.map') 1756163ed6c3SSimon Glass self.assertEqual("Wrote map file '%s' to show errors\n" % map_fname, 1757163ed6c3SSimon Glass stdout.getvalue()) 1758163ed6c3SSimon Glass 1759163ed6c3SSimon Glass # We should not get an inmage, but there should be a map file 1760163ed6c3SSimon Glass self.assertFalse(os.path.exists(tools.GetOutputFilename('image.bin'))) 1761163ed6c3SSimon Glass self.assertTrue(os.path.exists(map_fname)) 1762163ed6c3SSimon Glass map_data = tools.ReadFile(map_fname) 1763163ed6c3SSimon Glass self.assertEqual('''ImagePos Offset Size Name 1764163ed6c3SSimon Glass<none> 00000000 00000007 main-section 1765163ed6c3SSimon Glass<none> 00000000 00000004 u-boot 1766163ed6c3SSimon Glass<none> 00000003 00000004 u-boot-align 1767163ed6c3SSimon Glass''', map_data) 1768163ed6c3SSimon Glass 1769*3ae192c2SSimon Glass def testPacRefCode(self): 1770*3ae192c2SSimon Glass """Test that an image with an Intel Reference code binary works""" 1771*3ae192c2SSimon Glass data = self._DoReadFile('100_intel_refcode.dts') 1772*3ae192c2SSimon Glass self.assertEqual(REFCODE_DATA, data[:len(REFCODE_DATA)]) 1773*3ae192c2SSimon Glass 177453af22a9SSimon Glass 17759fc60b49SSimon Glassif __name__ == "__main__": 17769fc60b49SSimon Glass unittest.main() 1777